33OnigCaseFoldType OnigDefaultCaseFoldFlag = ONIGENC_CASE_FOLD_MIN;
35extern OnigCaseFoldType
36onig_get_default_case_fold_flag(
void)
38 return OnigDefaultCaseFoldFlag;
42onig_set_default_case_fold_flag(OnigCaseFoldType case_fold_flag)
44 OnigDefaultCaseFoldFlag = case_fold_flag;
49#ifndef PLATFORM_UNALIGNED_WORD_ACCESS
50static unsigned char PadBuf[WORD_ALIGNMENT_SIZE];
55str_dup(UChar* s, UChar* end)
57 ptrdiff_t
len = end - s;
74 c = *a; *a = *b; *b = c;
76 if (NTYPE(a) == NT_STR) {
79 size_t len = sn->end - sn->s;
81 sn->end = sn->s +
len;
85 if (NTYPE(b) == NT_STR) {
88 size_t len = sn->end - sn->s;
90 sn->end = sn->s +
len;
96distance_add(OnigDistance d1, OnigDistance d2)
98 if (d1 == ONIG_INFINITE_DISTANCE || d2 == ONIG_INFINITE_DISTANCE)
99 return ONIG_INFINITE_DISTANCE;
101 if (d1 <= ONIG_INFINITE_DISTANCE - d2)
return d1 + d2;
102 else return ONIG_INFINITE_DISTANCE;
107distance_multiply(OnigDistance d,
int m)
109 if (m == 0)
return 0;
111 if (d < ONIG_INFINITE_DISTANCE / m)
114 return ONIG_INFINITE_DISTANCE;
118bitset_is_empty(BitSetRef bs)
121 for (i = 0; i < BITSET_SIZE; i++) {
122 if (bs[i] != 0)
return 0;
129bitset_on_num(BitSetRef bs)
134 for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
135 if (BITSET_AT(bs, i)) n++;
151 else if (reg->alloc > reg->used) {
152 unsigned char *new_ptr =
xrealloc(reg->p, reg->used);
155 reg->alloc = reg->used;
159 }
while ((reg = reg->chain) != 0);
163onig_bbuf_init(
BBuf* buf, OnigDistance size)
170 buf->p = (UChar* )
xmalloc(size);
171 if (IS_NULL(buf->p))
return(ONIGERR_MEMORY);
174 buf->alloc = (
unsigned int )size;
180#ifdef USE_SUBEXP_CALL
188 CHECK_NULL_RETURN_MEMERR(p);
190 uslist->alloc = size;
207 if (uslist->num >= uslist->alloc) {
208 size = uslist->alloc * 2;
210 CHECK_NULL_RETURN_MEMERR(p);
211 uslist->alloc = size;
215 uslist->us[uslist->num].offset = offset;
216 uslist->us[uslist->num].target = node;
224add_opcode(
regex_t* reg,
int opcode)
228 if (reg->used > MAX_COMPILED_PROGRAM_SIZE)
229 return ONIGERR_TOO_BIG_COMPILED_PROGRAM;
230 BBUF_ADD1(reg, opcode);
234#ifdef USE_COMBINATION_EXPLOSION_CHECK
236add_state_check_num(
regex_t* reg,
int num)
238 StateCheckNumType n = (StateCheckNumType )num;
240 BBUF_ADD(reg, &n, SIZE_STATE_CHECK_NUM);
246add_rel_addr(
regex_t* reg,
int addr)
248 RelAddrType ra = (RelAddrType )addr;
250 BBUF_ADD(reg, &ra, SIZE_RELADDR);
255add_abs_addr(
regex_t* reg,
int addr)
257 AbsAddrType ra = (AbsAddrType )addr;
259 BBUF_ADD(reg, &ra, SIZE_ABSADDR);
266 LengthType l = (LengthType )
len;
268 BBUF_ADD(reg, &l, SIZE_LENGTH);
273add_mem_num(
regex_t* reg,
int num)
275 MemNumType n = (MemNumType )num;
277 BBUF_ADD(reg, &n, SIZE_MEMNUM);
283add_pointer(
regex_t* reg,
void* addr)
285 PointerType ptr = (PointerType )addr;
287 BBUF_ADD(reg, &ptr, SIZE_POINTER);
293add_option(
regex_t* reg, OnigOptionType option)
295 BBUF_ADD(reg, &option, SIZE_OPTION);
300add_opcode_rel_addr(
regex_t* reg,
int opcode,
int addr)
304 r = add_opcode(reg, opcode);
306 r = add_rel_addr(reg, addr);
311add_bytes(
regex_t* reg, UChar* bytes, OnigDistance
len)
313 BBUF_ADD(reg, bytes,
len);
318add_bitset(
regex_t* reg, BitSetRef bs)
320 BBUF_ADD(reg, bs, SIZE_BITSET);
325add_opcode_option(
regex_t* reg,
int opcode, OnigOptionType option)
329 r = add_opcode(reg, opcode);
331 r = add_option(reg, option);
335static int compile_length_tree(
Node* node,
regex_t* reg);
339#define IS_NEED_STR_LEN_OP_EXACT(op) \
340 ((op) == OP_EXACTN || (op) == OP_EXACTMB2N ||\
341 (op) == OP_EXACTMB3N || (op) == OP_EXACTMBN || (op) == OP_EXACTN_IC)
344select_str_opcode(
int mb_len, OnigDistance byte_len,
int ignore_case)
347 OnigDistance str_len = roomof(byte_len, mb_len);
351 case 1: op = OP_EXACT1_IC;
break;
352 default: op = OP_EXACTN_IC;
break;
359 case 1: op = OP_EXACT1;
break;
360 case 2: op = OP_EXACT2;
break;
361 case 3: op = OP_EXACT3;
break;
362 case 4: op = OP_EXACT4;
break;
363 case 5: op = OP_EXACT5;
break;
364 default: op = OP_EXACTN;
break;
370 case 1: op = OP_EXACTMB2N1;
break;
371 case 2: op = OP_EXACTMB2N2;
break;
372 case 3: op = OP_EXACTMB2N3;
break;
373 default: op = OP_EXACTMB2N;
break;
390compile_tree_empty_check(
Node* node,
regex_t* reg,
int empty_info)
393 int saved_num_null_check = reg->num_null_check;
395 if (empty_info != 0) {
396 r = add_opcode(reg, OP_NULL_CHECK_START);
398 r = add_mem_num(reg, reg->num_null_check);
400 reg->num_null_check++;
401 if ((MemNumType)reg->num_null_check <= 0)
return ONIGERR_TOO_MANY_NULL_CHECK;
404 r = compile_tree(node, reg);
407 if (empty_info != 0) {
408 if (empty_info == NQ_TARGET_IS_EMPTY)
409 r = add_opcode(reg, OP_NULL_CHECK_END);
410 else if (empty_info == NQ_TARGET_IS_EMPTY_MEM)
411 r = add_opcode(reg, OP_NULL_CHECK_END_MEMST);
412 else if (empty_info == NQ_TARGET_IS_EMPTY_REC)
413 r = add_opcode(reg, OP_NULL_CHECK_END_MEMST_PUSH);
416 r = add_mem_num(reg, saved_num_null_check);
421#ifdef USE_SUBEXP_CALL
427 r = add_opcode(reg, OP_CALL);
429 r = unset_addr_list_add(node->unset_addr_list, BBUF_GET_OFFSET_POS(reg),
432 r = add_abs_addr(reg, 0 );
438compile_tree_n_times(
Node* node,
int n,
regex_t* reg)
442 for (i = 0; i < n; i++) {
443 r = compile_tree(node, reg);
450add_compile_string_length(UChar* s ARG_UNUSED,
int mb_len, OnigDistance byte_len,
451 regex_t* reg ARG_UNUSED,
int ignore_case)
454 int op = select_str_opcode(mb_len, byte_len, ignore_case);
458 if (op == OP_EXACTMBN)
len += SIZE_LENGTH;
459 if (IS_NEED_STR_LEN_OP_EXACT(op))
462 len += (int )byte_len;
467add_compile_string(UChar* s,
int mb_len, OnigDistance byte_len,
470 int op = select_str_opcode(mb_len, byte_len, ignore_case);
473 if (op == OP_EXACTMBN)
474 add_length(reg, mb_len);
476 if (IS_NEED_STR_LEN_OP_EXACT(op)) {
477 if (op == OP_EXACTN_IC)
478 add_length(reg, byte_len);
480 add_length(reg, byte_len / mb_len);
483 add_bytes(reg, s, byte_len);
489compile_length_string_node(
Node* node,
regex_t* reg)
491 int rlen, r,
len, prev_len, blen, ambig;
497 if (sn->end <= sn->s)
500 ambig = NSTRING_IS_AMBIG(node);
503 prev_len = enclen(enc, p, sn->end);
508 for (; p < sn->end; ) {
509 len = enclen(enc, p, sn->end);
510 if (
len == prev_len || ambig) {
514 r = add_compile_string_length(prev, prev_len, blen, reg, ambig);
522 r = add_compile_string_length(prev, prev_len, blen, reg, ambig);
530 if (sn->end <= sn->s)
533 return add_compile_string_length(sn->s, 1 , sn->end - sn->s, reg, 0);
539 int r,
len, prev_len, blen, ambig;
541 UChar *p, *prev, *end;
545 if (sn->end <= sn->s)
549 ambig = NSTRING_IS_AMBIG(node);
552 prev_len = enclen(enc, p, end);
557 len = enclen(enc, p, end);
558 if (
len == prev_len || ambig) {
562 r = add_compile_string(prev, prev_len, blen, reg, ambig);
572 return add_compile_string(prev, prev_len, blen, reg, ambig);
578 if (sn->end <= sn->s)
581 return add_compile_string(sn->s, 1 , sn->end - sn->s, reg, 0);
587#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
588 add_length(reg, mbuf->used);
589 return add_bytes(reg, mbuf->p, mbuf->used);
592 UChar* p = BBUF_GET_ADD_ADDRESS(reg) + SIZE_LENGTH;
594 GET_ALIGNMENT_PAD_SIZE(p, pad_size);
595 add_length(reg, mbuf->used + (WORD_ALIGNMENT_SIZE - 1));
596 if (pad_size != 0) add_bytes(reg, PadBuf, pad_size);
598 r = add_bytes(reg, mbuf->p, mbuf->used);
601 pad_size = (WORD_ALIGNMENT_SIZE - 1) - pad_size;
602 if (pad_size != 0) add_bytes(reg, PadBuf, pad_size);
612 if (IS_NULL(cc->mbuf)) {
613 len = SIZE_OPCODE + SIZE_BITSET;
616 if (ONIGENC_MBC_MINLEN(reg->enc) > 1 || bitset_is_empty(cc->bs)) {
620 len = SIZE_OPCODE + SIZE_BITSET;
622#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
623 len += SIZE_LENGTH + cc->mbuf->used;
625 len += SIZE_LENGTH + cc->mbuf->used + (WORD_ALIGNMENT_SIZE - 1);
637 if (IS_NULL(cc->mbuf)) {
638 if (IS_NCCLASS_NOT(cc))
639 add_opcode(reg, OP_CCLASS_NOT);
641 add_opcode(reg, OP_CCLASS);
643 r = add_bitset(reg, cc->bs);
646 if (ONIGENC_MBC_MINLEN(reg->enc) > 1 || bitset_is_empty(cc->bs)) {
647 if (IS_NCCLASS_NOT(cc))
648 add_opcode(reg, OP_CCLASS_MB_NOT);
650 add_opcode(reg, OP_CCLASS_MB);
652 r = add_multi_byte_cclass(cc->mbuf, reg);
655 if (IS_NCCLASS_NOT(cc))
656 add_opcode(reg, OP_CCLASS_MIX_NOT);
658 add_opcode(reg, OP_CCLASS_MIX);
660 r = add_bitset(reg, cc->bs);
662 r = add_multi_byte_cclass(cc->mbuf, reg);
670entry_repeat_range(
regex_t* reg,
int id,
int lower,
int upper)
672#define REPEAT_RANGE_ALLOC 4
676 if (reg->repeat_range_alloc == 0) {
678 CHECK_NULL_RETURN_MEMERR(p);
679 reg->repeat_range = p;
680 reg->repeat_range_alloc = REPEAT_RANGE_ALLOC;
682 else if (reg->repeat_range_alloc <=
id) {
684 n = reg->repeat_range_alloc + REPEAT_RANGE_ALLOC;
687 CHECK_NULL_RETURN_MEMERR(p);
688 reg->repeat_range = p;
689 reg->repeat_range_alloc = n;
692 p = reg->repeat_range;
696 p[id].upper = (IS_REPEAT_INFINITE(upper) ? 0x7fffffff : upper);
701compile_range_repeat_node(
QtfrNode* qn,
int target_len,
int empty_info,
705 int num_repeat = reg->num_repeat;
707 r = add_opcode(reg, qn->greedy ? OP_REPEAT : OP_REPEAT_NG);
709 r = add_mem_num(reg, num_repeat);
711 if ((MemNumType)reg->num_repeat <= 0)
return ONIGERR_TOO_MANY_RANGE_REPEAT;
713 r = add_rel_addr(reg, target_len + SIZE_OP_REPEAT_INC);
716 r = entry_repeat_range(reg, num_repeat, qn->lower, qn->upper);
719 r = compile_tree_empty_check(qn->target, reg, empty_info);
723#ifdef USE_SUBEXP_CALL
726 IS_QUANTIFIER_IN_REPEAT(qn)) {
727 r = add_opcode(reg, qn->greedy ? OP_REPEAT_INC_SG : OP_REPEAT_INC_NG_SG);
730 r = add_opcode(reg, qn->greedy ? OP_REPEAT_INC : OP_REPEAT_INC_NG);
733 r = add_mem_num(reg, num_repeat);
738is_anychar_star_quantifier(
QtfrNode* qn)
740 if (qn->greedy && IS_REPEAT_INFINITE(qn->upper) &&
741 NTYPE(qn->target) == NT_CANY)
747#define QUANTIFIER_EXPAND_LIMIT_SIZE 50
750#define IS_EXPAND_LIMIT_OK(tlen, n) \
751 ((n) <= 0 || (tlen) <= QUANTIFIER_EXPAND_LIMIT_SIZE / (n))
752#define CKN_ON (ckn > 0)
754#ifdef USE_COMBINATION_EXPLOSION_CHECK
759 int len, mod_tlen, cklen;
761 int infinite = IS_REPEAT_INFINITE(qn->upper);
762 int empty_info = qn->target_empty_info;
763 int tlen = compile_length_tree(qn->target, reg);
765 if (tlen < 0)
return tlen;
767 ckn = ((reg->num_comb_exp_check > 0) ? qn->comb_exp_check_num : 0);
769 cklen = (CKN_ON ? SIZE_STATE_CHECK_NUM: 0);
772 if (NTYPE(qn->target) == NT_CANY) {
773 if (qn->greedy && infinite) {
774 if (IS_NOT_NULL(qn->next_head_exact) && !CKN_ON)
775 return SIZE_OP_ANYCHAR_STAR_PEEK_NEXT + tlen * qn->lower + cklen;
777 return SIZE_OP_ANYCHAR_STAR + tlen * qn->lower + cklen;
782 mod_tlen = tlen + (SIZE_OP_NULL_CHECK_START + SIZE_OP_NULL_CHECK_END);
786 if (infinite && qn->lower <= 1) {
793 len += SIZE_OP_PUSH + cklen + mod_tlen + SIZE_OP_JUMP;
801 len += mod_tlen + SIZE_OP_PUSH + cklen;
804 else if (qn->upper == 0) {
805 if (qn->is_referred != 0)
806 len = SIZE_OP_JUMP + tlen;
810 else if (qn->upper == 1 && qn->greedy) {
811 if (qn->lower == 0) {
813 len = SIZE_OP_STATE_CHECK_PUSH + tlen;
816 len = SIZE_OP_PUSH + tlen;
823 else if (!qn->greedy && qn->upper == 1 && qn->lower == 0) {
824 len = SIZE_OP_PUSH + cklen + SIZE_OP_JUMP + tlen;
827 len = SIZE_OP_REPEAT_INC
828 + mod_tlen + SIZE_OPCODE + SIZE_RELADDR + SIZE_MEMNUM;
830 len += SIZE_OP_STATE_CHECK;
841 int infinite = IS_REPEAT_INFINITE(qn->upper);
842 int empty_info = qn->target_empty_info;
843 int tlen = compile_length_tree(qn->target, reg);
845 if (tlen < 0)
return tlen;
847 ckn = ((reg->num_comb_exp_check > 0) ? qn->comb_exp_check_num : 0);
849 if (is_anychar_star_quantifier(qn)) {
850 r = compile_tree_n_times(qn->target, qn->lower, reg);
852 if (IS_NOT_NULL(qn->next_head_exact) && !CKN_ON) {
853 if (IS_MULTILINE(reg->options))
854 r = add_opcode(reg, OP_ANYCHAR_ML_STAR_PEEK_NEXT);
856 r = add_opcode(reg, OP_ANYCHAR_STAR_PEEK_NEXT);
859 r = add_state_check_num(reg, ckn);
863 return add_bytes(reg, NSTR(qn->next_head_exact)->s, 1);
866 if (IS_MULTILINE(reg->options)) {
867 r = add_opcode(reg, (CKN_ON ?
868 OP_STATE_CHECK_ANYCHAR_ML_STAR
869 : OP_ANYCHAR_ML_STAR));
872 r = add_opcode(reg, (CKN_ON ?
873 OP_STATE_CHECK_ANYCHAR_STAR
878 r = add_state_check_num(reg, ckn);
885 mod_tlen = tlen + (SIZE_OP_NULL_CHECK_START + SIZE_OP_NULL_CHECK_END);
889 if (infinite && qn->lower <= 1) {
891 if (qn->lower == 1) {
892 r = add_opcode_rel_addr(reg, OP_JUMP,
893 (CKN_ON ? SIZE_OP_STATE_CHECK_PUSH : SIZE_OP_PUSH));
898 r = add_opcode(reg, OP_STATE_CHECK_PUSH);
900 r = add_state_check_num(reg, ckn);
902 r = add_rel_addr(reg, mod_tlen + SIZE_OP_JUMP);
905 r = add_opcode_rel_addr(reg, OP_PUSH, mod_tlen + SIZE_OP_JUMP);
908 r = compile_tree_empty_check(qn->target, reg, empty_info);
910 r = add_opcode_rel_addr(reg, OP_JUMP,
911 -(mod_tlen + (
int )SIZE_OP_JUMP
912 + (
int )(CKN_ON ? SIZE_OP_STATE_CHECK_PUSH : SIZE_OP_PUSH)));
915 if (qn->lower == 0) {
916 r = add_opcode_rel_addr(reg, OP_JUMP, mod_tlen);
919 r = compile_tree_empty_check(qn->target, reg, empty_info);
922 r = add_opcode(reg, OP_STATE_CHECK_PUSH_OR_JUMP);
924 r = add_state_check_num(reg, ckn);
926 r = add_rel_addr(reg,
927 -(mod_tlen + (
int )SIZE_OP_STATE_CHECK_PUSH_OR_JUMP));
930 r = add_opcode_rel_addr(reg, OP_PUSH, -(mod_tlen + (
int )SIZE_OP_PUSH));
933 else if (qn->upper == 0) {
934 if (qn->is_referred != 0) {
935 r = add_opcode_rel_addr(reg, OP_JUMP, tlen);
937 r = compile_tree(qn->target, reg);
942 else if (qn->upper == 1 && qn->greedy) {
943 if (qn->lower == 0) {
945 r = add_opcode(reg, OP_STATE_CHECK_PUSH);
947 r = add_state_check_num(reg, ckn);
949 r = add_rel_addr(reg, tlen);
952 r = add_opcode_rel_addr(reg, OP_PUSH, tlen);
957 r = compile_tree(qn->target, reg);
959 else if (!qn->greedy && qn->upper == 1 && qn->lower == 0) {
961 r = add_opcode(reg, OP_STATE_CHECK_PUSH);
963 r = add_state_check_num(reg, ckn);
965 r = add_rel_addr(reg, SIZE_OP_JUMP);
968 r = add_opcode_rel_addr(reg, OP_PUSH, SIZE_OP_JUMP);
972 r = add_opcode_rel_addr(reg, OP_JUMP, tlen);
974 r = compile_tree(qn->target, reg);
977 r = compile_range_repeat_node(qn, mod_tlen, empty_info, reg);
980 r = add_opcode(reg, OP_STATE_CHECK);
982 r = add_state_check_num(reg, ckn);
994 int infinite = IS_REPEAT_INFINITE(qn->upper);
995 int empty_info = qn->target_empty_info;
996 int tlen = compile_length_tree(qn->target, reg);
998 if (tlen < 0)
return tlen;
1001 if (NTYPE(qn->target) == NT_CANY) {
1002 if (qn->greedy && infinite) {
1003 if (IS_NOT_NULL(qn->next_head_exact))
1004 return SIZE_OP_ANYCHAR_STAR_PEEK_NEXT + tlen * qn->lower;
1006 return SIZE_OP_ANYCHAR_STAR + tlen * qn->lower;
1010 if (empty_info != 0)
1011 mod_tlen = tlen + (SIZE_OP_NULL_CHECK_START + SIZE_OP_NULL_CHECK_END);
1016 (qn->lower <= 1 || IS_EXPAND_LIMIT_OK(tlen, qn->lower))) {
1017 if (qn->lower == 1 && tlen > QUANTIFIER_EXPAND_LIMIT_SIZE) {
1021 len = tlen * qn->lower;
1025#ifdef USE_OP_PUSH_OR_JUMP_EXACT
1026 if (IS_NOT_NULL(qn->head_exact))
1027 len += SIZE_OP_PUSH_OR_JUMP_EXACT1 + mod_tlen + SIZE_OP_JUMP;
1030 if (IS_NOT_NULL(qn->next_head_exact))
1031 len += SIZE_OP_PUSH_IF_PEEK_NEXT + mod_tlen + SIZE_OP_JUMP;
1033 len += SIZE_OP_PUSH + mod_tlen + SIZE_OP_JUMP;
1036 len += SIZE_OP_JUMP + mod_tlen + SIZE_OP_PUSH;
1038 else if (qn->upper == 0 && qn->is_referred != 0) {
1039 len = SIZE_OP_JUMP + tlen;
1041 else if (!infinite && qn->greedy &&
1043 IS_EXPAND_LIMIT_OK(tlen + SIZE_OP_PUSH, qn->upper))) {
1044 len = tlen * qn->lower;
1045 len += (SIZE_OP_PUSH + tlen) * (qn->upper - qn->lower);
1047 else if (!qn->greedy && qn->upper == 1 && qn->lower == 0) {
1048 len = SIZE_OP_PUSH + SIZE_OP_JUMP + tlen;
1051 len = SIZE_OP_REPEAT_INC
1052 + mod_tlen + SIZE_OPCODE + SIZE_RELADDR + SIZE_MEMNUM;
1062 int infinite = IS_REPEAT_INFINITE(qn->upper);
1063 int empty_info = qn->target_empty_info;
1064 int tlen = compile_length_tree(qn->target, reg);
1066 if (tlen < 0)
return tlen;
1068 if (is_anychar_star_quantifier(qn)) {
1069 r = compile_tree_n_times(qn->target, qn->lower, reg);
1071 if (IS_NOT_NULL(qn->next_head_exact)) {
1072 if (IS_MULTILINE(reg->options))
1073 r = add_opcode(reg, OP_ANYCHAR_ML_STAR_PEEK_NEXT);
1075 r = add_opcode(reg, OP_ANYCHAR_STAR_PEEK_NEXT);
1077 return add_bytes(reg, NSTR(qn->next_head_exact)->s, 1);
1080 if (IS_MULTILINE(reg->options))
1081 return add_opcode(reg, OP_ANYCHAR_ML_STAR);
1083 return add_opcode(reg, OP_ANYCHAR_STAR);
1087 if (empty_info != 0)
1088 mod_tlen = tlen + (SIZE_OP_NULL_CHECK_START + SIZE_OP_NULL_CHECK_END);
1093 (qn->lower <= 1 || IS_EXPAND_LIMIT_OK(tlen, qn->lower))) {
1094 if (qn->lower == 1 && tlen > QUANTIFIER_EXPAND_LIMIT_SIZE) {
1096#ifdef USE_OP_PUSH_OR_JUMP_EXACT
1097 if (IS_NOT_NULL(qn->head_exact))
1098 r = add_opcode_rel_addr(reg, OP_JUMP, SIZE_OP_PUSH_OR_JUMP_EXACT1);
1101 if (IS_NOT_NULL(qn->next_head_exact))
1102 r = add_opcode_rel_addr(reg, OP_JUMP, SIZE_OP_PUSH_IF_PEEK_NEXT);
1104 r = add_opcode_rel_addr(reg, OP_JUMP, SIZE_OP_PUSH);
1107 r = add_opcode_rel_addr(reg, OP_JUMP, SIZE_OP_JUMP);
1112 r = compile_tree_n_times(qn->target, qn->lower, reg);
1117#ifdef USE_OP_PUSH_OR_JUMP_EXACT
1118 if (IS_NOT_NULL(qn->head_exact)) {
1119 r = add_opcode_rel_addr(reg, OP_PUSH_OR_JUMP_EXACT1,
1120 mod_tlen + SIZE_OP_JUMP);
1122 add_bytes(reg, NSTR(qn->head_exact)->s, 1);
1123 r = compile_tree_empty_check(qn->target, reg, empty_info);
1125 r = add_opcode_rel_addr(reg, OP_JUMP,
1126 -(mod_tlen + (
int )SIZE_OP_JUMP + (
int )SIZE_OP_PUSH_OR_JUMP_EXACT1));
1130 if (IS_NOT_NULL(qn->next_head_exact)) {
1131 r = add_opcode_rel_addr(reg, OP_PUSH_IF_PEEK_NEXT,
1132 mod_tlen + SIZE_OP_JUMP);
1134 add_bytes(reg, NSTR(qn->next_head_exact)->s, 1);
1135 r = compile_tree_empty_check(qn->target, reg, empty_info);
1137 r = add_opcode_rel_addr(reg, OP_JUMP,
1138 -(mod_tlen + (
int )SIZE_OP_JUMP + (
int )SIZE_OP_PUSH_IF_PEEK_NEXT));
1141 r = add_opcode_rel_addr(reg, OP_PUSH, mod_tlen + SIZE_OP_JUMP);
1143 r = compile_tree_empty_check(qn->target, reg, empty_info);
1145 r = add_opcode_rel_addr(reg, OP_JUMP,
1146 -(mod_tlen + (
int )SIZE_OP_JUMP + (
int )SIZE_OP_PUSH));
1150 r = add_opcode_rel_addr(reg, OP_JUMP, mod_tlen);
1152 r = compile_tree_empty_check(qn->target, reg, empty_info);
1154 r = add_opcode_rel_addr(reg, OP_PUSH, -(mod_tlen + (
int )SIZE_OP_PUSH));
1157 else if (qn->upper == 0 && qn->is_referred != 0) {
1158 r = add_opcode_rel_addr(reg, OP_JUMP, tlen);
1160 r = compile_tree(qn->target, reg);
1162 else if (!infinite && qn->greedy &&
1164 IS_EXPAND_LIMIT_OK(tlen + SIZE_OP_PUSH, qn->upper))) {
1165 int n = qn->upper - qn->lower;
1167 r = compile_tree_n_times(qn->target, qn->lower, reg);
1170 for (i = 0; i < n; i++) {
1171 r = add_opcode_rel_addr(reg, OP_PUSH,
1172 (n - i) * tlen + (n - i - 1) * SIZE_OP_PUSH);
1174 r = compile_tree(qn->target, reg);
1178 else if (!qn->greedy && qn->upper == 1 && qn->lower == 0) {
1179 r = add_opcode_rel_addr(reg, OP_PUSH, SIZE_OP_JUMP);
1181 r = add_opcode_rel_addr(reg, OP_JUMP, tlen);
1183 r = compile_tree(qn->target, reg);
1186 r = compile_range_repeat_node(qn, mod_tlen, empty_info, reg);
1196 OnigOptionType prev = reg->options;
1198 reg->options = node->option;
1199 tlen = compile_length_tree(node->target, reg);
1200 reg->options = prev;
1202 if (tlen < 0)
return tlen;
1204 if (IS_DYNAMIC_OPTION(prev ^ node->option)) {
1205 return SIZE_OP_SET_OPTION_PUSH + SIZE_OP_SET_OPTION + SIZE_OP_FAIL
1206 + tlen + SIZE_OP_SET_OPTION;
1216 OnigOptionType prev = reg->options;
1218 if (IS_DYNAMIC_OPTION(prev ^ node->option)) {
1219 r = add_opcode_option(reg, OP_SET_OPTION_PUSH, node->option);
1221 r = add_opcode_option(reg, OP_SET_OPTION, prev);
1223 r = add_opcode(reg, OP_FAIL);
1227 reg->options = node->option;
1228 r = compile_tree(node->target, reg);
1229 reg->options = prev;
1231 if (IS_DYNAMIC_OPTION(prev ^ node->option)) {
1233 r = add_opcode_option(reg, OP_SET_OPTION, prev);
1244 if (node->type == ENCLOSE_OPTION)
1245 return compile_length_option_node(node, reg);
1248 tlen = compile_length_tree(node->target, reg);
1249 if (tlen < 0)
return tlen;
1254 switch (node->type) {
1255 case ENCLOSE_MEMORY:
1256#ifdef USE_SUBEXP_CALL
1257 if (IS_ENCLOSE_CALLED(node)) {
1258 len = SIZE_OP_MEMORY_START_PUSH + tlen
1259 + SIZE_OP_CALL + SIZE_OP_JUMP + SIZE_OP_RETURN;
1260 if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
1261 len += (IS_ENCLOSE_RECURSION(node)
1262 ? SIZE_OP_MEMORY_END_PUSH_REC : SIZE_OP_MEMORY_END_PUSH);
1264 len += (IS_ENCLOSE_RECURSION(node)
1265 ? SIZE_OP_MEMORY_END_REC : SIZE_OP_MEMORY_END);
1267 else if (IS_ENCLOSE_RECURSION(node)) {
1268 len = SIZE_OP_MEMORY_START_PUSH;
1269 len += tlen + (BIT_STATUS_AT(reg->bt_mem_end, node->regnum)
1270 ? SIZE_OP_MEMORY_END_PUSH_REC : SIZE_OP_MEMORY_END_REC);
1275 if (BIT_STATUS_AT(reg->bt_mem_start, node->regnum))
1276 len = SIZE_OP_MEMORY_START_PUSH;
1278 len = SIZE_OP_MEMORY_START;
1280 len += tlen + (BIT_STATUS_AT(reg->bt_mem_end, node->regnum)
1281 ? SIZE_OP_MEMORY_END_PUSH : SIZE_OP_MEMORY_END);
1285 case ENCLOSE_STOP_BACKTRACK:
1289#ifndef USE_MATCH_CACHE
1290 if (IS_ENCLOSE_STOP_BT_SIMPLE_REPEAT(node)) {
1291 QtfrNode* qn = NQTFR(node->target);
1292 tlen = compile_length_tree(qn->target, reg);
1293 if (tlen < 0)
return tlen;
1295 len = tlen * qn->lower
1296 + SIZE_OP_PUSH + tlen + SIZE_OP_POP + SIZE_OP_JUMP;
1300 len = SIZE_OP_PUSH_STOP_BT + tlen + SIZE_OP_POP_STOP_BT;
1301#ifndef USE_MATCH_CACHE
1306 case ENCLOSE_CONDITION:
1307 len = SIZE_OP_CONDITION;
1308 if (NTYPE(node->target) == NT_ALT) {
1309 Node* x = node->target;
1311 tlen = compile_length_tree(NCAR(x), reg);
1312 if (tlen < 0)
return tlen;
1313 len += tlen + SIZE_OP_JUMP;
1314 if (NCDR(x) == NULL)
return ONIGERR_PARSER_BUG;
1316 tlen = compile_length_tree(NCAR(x), reg);
1317 if (tlen < 0)
return tlen;
1319 if (NCDR(x) != NULL)
return ONIGERR_INVALID_CONDITION_PATTERN;
1322 return ONIGERR_PARSER_BUG;
1326 case ENCLOSE_ABSENT:
1327 len = SIZE_OP_PUSH_ABSENT_POS + SIZE_OP_ABSENT + tlen + SIZE_OP_ABSENT_END;
1331 return ONIGERR_TYPE_BUG;
1338static int get_char_length_tree(
Node* node,
regex_t* reg,
int*
len);
1345 if (node->type == ENCLOSE_OPTION)
1346 return compile_option_node(node, reg);
1348 switch (node->type) {
1349 case ENCLOSE_MEMORY:
1350#ifdef USE_SUBEXP_CALL
1351 if (IS_ENCLOSE_CALLED(node)) {
1352 r = add_opcode(reg, OP_CALL);
1354 node->call_addr = BBUF_GET_OFFSET_POS(reg) + SIZE_ABSADDR + SIZE_OP_JUMP;
1355 node->state |= NST_ADDR_FIXED;
1356 r = add_abs_addr(reg, (
int )node->call_addr);
1358 len = compile_length_tree(node->target, reg);
1360 len += (SIZE_OP_MEMORY_START_PUSH + SIZE_OP_RETURN);
1361 if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
1362 len += (IS_ENCLOSE_RECURSION(node)
1363 ? SIZE_OP_MEMORY_END_PUSH_REC : SIZE_OP_MEMORY_END_PUSH);
1365 len += (IS_ENCLOSE_RECURSION(node)
1366 ? SIZE_OP_MEMORY_END_REC : SIZE_OP_MEMORY_END);
1368 r = add_opcode_rel_addr(reg, OP_JUMP,
len);
1372 if (BIT_STATUS_AT(reg->bt_mem_start, node->regnum))
1373 r = add_opcode(reg, OP_MEMORY_START_PUSH);
1375 r = add_opcode(reg, OP_MEMORY_START);
1377 r = add_mem_num(reg, node->regnum);
1379 r = compile_tree(node->target, reg);
1381#ifdef USE_SUBEXP_CALL
1382 if (IS_ENCLOSE_CALLED(node)) {
1383 if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
1384 r = add_opcode(reg, (IS_ENCLOSE_RECURSION(node)
1385 ? OP_MEMORY_END_PUSH_REC : OP_MEMORY_END_PUSH));
1387 r = add_opcode(reg, (IS_ENCLOSE_RECURSION(node)
1388 ? OP_MEMORY_END_REC : OP_MEMORY_END));
1391 r = add_mem_num(reg, node->regnum);
1393 r = add_opcode(reg, OP_RETURN);
1395 else if (IS_ENCLOSE_RECURSION(node)) {
1396 if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
1397 r = add_opcode(reg, OP_MEMORY_END_PUSH_REC);
1399 r = add_opcode(reg, OP_MEMORY_END_REC);
1401 r = add_mem_num(reg, node->regnum);
1406 if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
1407 r = add_opcode(reg, OP_MEMORY_END_PUSH);
1409 r = add_opcode(reg, OP_MEMORY_END);
1411 r = add_mem_num(reg, node->regnum);
1415 case ENCLOSE_STOP_BACKTRACK:
1419#ifndef USE_MATCH_CACHE
1420 if (IS_ENCLOSE_STOP_BT_SIMPLE_REPEAT(node)) {
1421 QtfrNode* qn = NQTFR(node->target);
1422 r = compile_tree_n_times(qn->target, qn->lower, reg);
1425 len = compile_length_tree(qn->target, reg);
1428 r = add_opcode_rel_addr(reg, OP_PUSH,
len + SIZE_OP_POP + SIZE_OP_JUMP);
1430 r = compile_tree(qn->target, reg);
1432 r = add_opcode(reg, OP_POP);
1434 r = add_opcode_rel_addr(reg, OP_JUMP,
1435 -((
int )SIZE_OP_PUSH +
len + (
int )SIZE_OP_POP + (
int )SIZE_OP_JUMP));
1439 r = add_opcode(reg, OP_PUSH_STOP_BT);
1441 r = compile_tree(node->target, reg);
1443 r = add_opcode(reg, OP_POP_STOP_BT);
1444#ifndef USE_MATCH_CACHE
1449 case ENCLOSE_CONDITION:
1450 r = add_opcode(reg, OP_CONDITION);
1452 r = add_mem_num(reg, node->regnum);
1455 if (NTYPE(node->target) == NT_ALT) {
1456 Node* x = node->target;
1459 len = compile_length_tree(NCAR(x), reg);
1461 if (NCDR(x) == NULL)
return ONIGERR_PARSER_BUG;
1463 len2 = compile_length_tree(NCAR(x), reg);
1464 if (len2 < 0)
return len2;
1465 if (NCDR(x) != NULL)
return ONIGERR_INVALID_CONDITION_PATTERN;
1468 r = add_rel_addr(reg,
len + SIZE_OP_JUMP);
1470 r = compile_tree(NCAR(x), reg);
1472 r = add_opcode_rel_addr(reg, OP_JUMP, len2);
1475 r = compile_tree(NCAR(x), reg);
1478 return ONIGERR_PARSER_BUG;
1482 case ENCLOSE_ABSENT:
1483 len = compile_length_tree(node->target, reg);
1486 r = add_opcode(reg, OP_PUSH_ABSENT_POS);
1488 r = add_opcode_rel_addr(reg, OP_ABSENT,
len + SIZE_OP_ABSENT_END);
1490 r = compile_tree(node->target, reg);
1492 r = add_opcode(reg, OP_ABSENT_END);
1496 return ONIGERR_TYPE_BUG;
1510 tlen = compile_length_tree(node->target, reg);
1511 if (tlen < 0)
return tlen;
1514 switch (node->type) {
1515 case ANCHOR_PREC_READ:
1516 len = SIZE_OP_PUSH_POS + tlen + SIZE_OP_POP_POS;
1518 case ANCHOR_PREC_READ_NOT:
1519 len = SIZE_OP_PUSH_POS_NOT + tlen + SIZE_OP_FAIL_POS;
1521 case ANCHOR_LOOK_BEHIND:
1522 len = SIZE_OP_LOOK_BEHIND + tlen;
1524 case ANCHOR_LOOK_BEHIND_NOT:
1525 len = SIZE_OP_PUSH_LOOK_BEHIND_NOT + tlen + SIZE_OP_FAIL_LOOK_BEHIND_NOT;
1541 switch (node->type) {
1542 case ANCHOR_BEGIN_BUF: r = add_opcode(reg, OP_BEGIN_BUF);
break;
1543 case ANCHOR_END_BUF: r = add_opcode(reg, OP_END_BUF);
break;
1544 case ANCHOR_BEGIN_LINE: r = add_opcode(reg, OP_BEGIN_LINE);
break;
1545 case ANCHOR_END_LINE: r = add_opcode(reg, OP_END_LINE);
break;
1546 case ANCHOR_SEMI_END_BUF: r = add_opcode(reg, OP_SEMI_END_BUF);
break;
1547 case ANCHOR_BEGIN_POSITION: r = add_opcode(reg, OP_BEGIN_POSITION);
break;
1549 case ANCHOR_WORD_BOUND:
1550 if (node->ascii_range) r = add_opcode(reg, OP_ASCII_WORD_BOUND);
1551 else r = add_opcode(reg, OP_WORD_BOUND);
1553 case ANCHOR_NOT_WORD_BOUND:
1554 if (node->ascii_range) r = add_opcode(reg, OP_NOT_ASCII_WORD_BOUND);
1555 else r = add_opcode(reg, OP_NOT_WORD_BOUND);
1557#ifdef USE_WORD_BEGIN_END
1558 case ANCHOR_WORD_BEGIN:
1559 if (node->ascii_range) r = add_opcode(reg, OP_ASCII_WORD_BEGIN);
1560 else r = add_opcode(reg, OP_WORD_BEGIN);
1562 case ANCHOR_WORD_END:
1563 if (node->ascii_range) r = add_opcode(reg, OP_ASCII_WORD_END);
1564 else r = add_opcode(reg, OP_WORD_END);
1567 case ANCHOR_KEEP: r = add_opcode(reg, OP_KEEP);
break;
1569 case ANCHOR_PREC_READ:
1570 r = add_opcode(reg, OP_PUSH_POS);
1572 r = compile_tree(node->target, reg);
1574 r = add_opcode(reg, OP_POP_POS);
1577 case ANCHOR_PREC_READ_NOT:
1578 len = compile_length_tree(node->target, reg);
1580 r = add_opcode_rel_addr(reg, OP_PUSH_POS_NOT,
len + SIZE_OP_FAIL_POS);
1582 r = compile_tree(node->target, reg);
1584 r = add_opcode(reg, OP_FAIL_POS);
1587 case ANCHOR_LOOK_BEHIND:
1590 r = add_opcode(reg, OP_LOOK_BEHIND);
1592 if (node->char_len < 0) {
1593 r = get_char_length_tree(node->target, reg, &n);
1594 if (r)
return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
1598 r = add_length(reg, n);
1600 r = compile_tree(node->target, reg);
1604 case ANCHOR_LOOK_BEHIND_NOT:
1607 len = compile_length_tree(node->target, reg);
1608 if (
len < 0)
return ONIGERR_PARSER_BUG;
1609 r = add_opcode_rel_addr(reg, OP_PUSH_LOOK_BEHIND_NOT,
1610 len + SIZE_OP_FAIL_LOOK_BEHIND_NOT);
1612 if (node->char_len < 0) {
1613 r = get_char_length_tree(node->target, reg, &n);
1614 if (r)
return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
1618 r = add_length(reg, n);
1620 r = compile_tree(node->target, reg);
1622 r = add_opcode(reg, OP_FAIL_LOOK_BEHIND_NOT);
1627 return ONIGERR_TYPE_BUG;
1644 r = compile_length_tree(NCAR(node), reg);
1645 if (r < 0)
return r;
1647 }
while (IS_NOT_NULL(node = NCDR(node)));
1656 r = compile_length_tree(NCAR(node), reg);
1657 if (r < 0)
return r;
1660 }
while (IS_NOT_NULL(node = NCDR(node)));
1662 r += (SIZE_OP_PUSH + SIZE_OP_JUMP) * (n - 1);
1667 if (NSTRING_IS_RAW(node))
1668 r = compile_length_string_raw_node(NSTR(node), reg);
1670 r = compile_length_string_node(node, reg);
1674 r = compile_length_cclass_node(NCCLASS(node), reg);
1686#ifdef USE_BACKREF_WITH_LEVEL
1687 if (IS_BACKREF_NEST_LEVEL(br)) {
1688 r = SIZE_OPCODE + SIZE_OPTION + SIZE_LENGTH +
1689 SIZE_LENGTH + (SIZE_MEMNUM * br->back_num);
1693 if (br->back_num == 1) {
1694 r = ((!IS_IGNORECASE(reg->options) && br->back_static[0] <= 2)
1695 ? SIZE_OPCODE : (SIZE_OPCODE + SIZE_MEMNUM));
1698 r = SIZE_OPCODE + SIZE_LENGTH + (SIZE_MEMNUM * br->back_num);
1703#ifdef USE_SUBEXP_CALL
1710 r = compile_length_quantifier_node(NQTFR(node), reg);
1714 r = compile_length_enclose_node(NENCLOSE(node), reg);
1718 r = compile_length_anchor_node(NANCHOR(node), reg);
1722 return ONIGERR_TYPE_BUG;
1738 r = compile_tree(NCAR(node), reg);
1739 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
1747 r = compile_length_tree(NCAR(x), reg);
1748 if (r < 0)
return r;
1750 if (NCDR(x) != NULL) {
1751 len += SIZE_OP_PUSH + SIZE_OP_JUMP;
1753 }
while (IS_NOT_NULL(x = NCDR(x)));
1754 pos = reg->used +
len;
1757 len = compile_length_tree(NCAR(node), reg);
1758 if (
len < 0)
return ONIGERR_PARSER_BUG;
1759 if (IS_NOT_NULL(NCDR(node))) {
1760 r = add_opcode_rel_addr(reg, OP_PUSH,
len + SIZE_OP_JUMP);
1763 r = compile_tree(NCAR(node), reg);
1765 if (IS_NOT_NULL(NCDR(node))) {
1766 len = pos - (reg->used + SIZE_OP_JUMP);
1767 r = add_opcode_rel_addr(reg, OP_JUMP,
len);
1770 }
while (IS_NOT_NULL(node = NCDR(node)));
1775 if (NSTRING_IS_RAW(node))
1776 r = compile_string_raw_node(NSTR(node), reg);
1778 r = compile_string_node(node, reg);
1782 r = compile_cclass_node(NCCLASS(node), reg);
1789 switch (NCTYPE(node)->ctype) {
1790 case ONIGENC_CTYPE_WORD:
1791 if (NCTYPE(node)->ascii_range != 0) {
1792 if (NCTYPE(node)->not != 0) op = OP_NOT_ASCII_WORD;
1793 else op = OP_ASCII_WORD;
1796 if (NCTYPE(node)->not != 0) op = OP_NOT_WORD;
1801 return ONIGERR_TYPE_BUG;
1804 r = add_opcode(reg, op);
1809 if (IS_MULTILINE(reg->options))
1810 r = add_opcode(reg, OP_ANYCHAR_ML);
1812 r = add_opcode(reg, OP_ANYCHAR);
1819#ifdef USE_BACKREF_WITH_LEVEL
1820 if (IS_BACKREF_NEST_LEVEL(br)) {
1821 r = add_opcode(reg, OP_BACKREF_WITH_LEVEL);
1823 r = add_option(reg, (reg->options & ONIG_OPTION_IGNORECASE));
1825 r = add_length(reg, br->nest_level);
1828 goto add_bacref_mems;
1832 if (br->back_num == 1) {
1833 n = br->back_static[0];
1834 if (IS_IGNORECASE(reg->options)) {
1835 r = add_opcode(reg, OP_BACKREFN_IC);
1837 r = add_mem_num(reg, n);
1841 case 1: r = add_opcode(reg, OP_BACKREF1);
break;
1842 case 2: r = add_opcode(reg, OP_BACKREF2);
break;
1844 r = add_opcode(reg, OP_BACKREFN);
1846 r = add_mem_num(reg, n);
1855 if (IS_IGNORECASE(reg->options)) {
1856 r = add_opcode(reg, OP_BACKREF_MULTI_IC);
1859 r = add_opcode(reg, OP_BACKREF_MULTI);
1863#ifdef USE_BACKREF_WITH_LEVEL
1866 r = add_length(reg, br->back_num);
1869 for (i = br->back_num - 1; i >= 0; i--) {
1870 r = add_mem_num(reg, p[i]);
1877#ifdef USE_SUBEXP_CALL
1879 r = compile_call(NCALL(node), reg);
1884 r = compile_quantifier_node(NQTFR(node), reg);
1888 r = compile_enclose_node(NENCLOSE(node), reg);
1892 r = compile_anchor_node(NANCHOR(node), reg);
1897 fprintf(stderr,
"compile_tree: undefined node type %d\n", NTYPE(node));
1905#ifdef USE_NAMED_GROUP
1911 Node* node = *plink;
1913 switch (NTYPE(node)) {
1917 r = noname_disable_map(&(NCAR(node)), map, counter);
1918 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
1923 Node** ptarget = &(NQTFR(node)->target);
1924 Node* old = *ptarget;
1925 r = noname_disable_map(ptarget, map, counter);
1926 if (*ptarget != old && NTYPE(*ptarget) == NT_QTFR) {
1927 onig_reduce_nested_quantifier(node, *ptarget);
1935 if (en->type == ENCLOSE_MEMORY) {
1936 if (IS_ENCLOSE_NAMED_GROUP(en)) {
1938 map[en->regnum].new_val = *counter;
1939 en->regnum = *counter;
1941 else if (en->regnum != 0) {
1942 *plink = en->target;
1943 en->target = NULL_NODE;
1944 onig_node_free(node);
1945 r = noname_disable_map(plink, map, counter);
1949 r = noname_disable_map(&(en->target), map, counter);
1954 if (NANCHOR(node)->target)
1955 r = noname_disable_map(&(NANCHOR(node)->target), map, counter);
1968 int i, pos, n, old_num;
1972 if (! IS_BACKREF_NAME_REF(bn))
1973 return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
1975 old_num = bn->back_num;
1976 if (IS_NULL(bn->back_dynamic))
1977 backs = bn->back_static;
1979 backs = bn->back_dynamic;
1981 for (i = 0, pos = 0; i < old_num; i++) {
1982 if (backs[i] > num_mem)
return ONIGERR_INVALID_BACKREF;
1983 n = map[backs[i]].new_val;
1999 switch (NTYPE(node)) {
2003 r = renumber_by_map(NCAR(node), map, num_mem);
2004 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
2007 r = renumber_by_map(NQTFR(node)->target, map, num_mem);
2012 if (en->type == ENCLOSE_CONDITION) {
2013 if (en->regnum > num_mem)
return ONIGERR_INVALID_BACKREF;
2014 en->regnum = map[en->regnum].new_val;
2016 r = renumber_by_map(en->target, map, num_mem);
2021 r = renumber_node_backref(node, map, num_mem);
2025 if (NANCHOR(node)->target)
2026 r = renumber_by_map(NANCHOR(node)->target, map, num_mem);
2037numbered_ref_check(
Node* node)
2041 switch (NTYPE(node)) {
2045 r = numbered_ref_check(NCAR(node));
2046 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
2049 r = numbered_ref_check(NQTFR(node)->target);
2052 r = numbered_ref_check(NENCLOSE(node)->target);
2056 if (! IS_BACKREF_NAME_REF(NBREF(node)))
2057 return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
2061 if (NANCHOR(node)->target)
2062 r = numbered_ref_check(NANCHOR(node)->target);
2075 int r, i, pos, counter;
2080 CHECK_NULL_RETURN_MEMERR(map);
2081 for (i = 1; i <= env->num_mem; i++) {
2085 r = noname_disable_map(root, map, &counter);
2086 if (r != 0)
return r;
2088 r = renumber_by_map(*root, map, env->num_mem);
2089 if (r != 0)
return r;
2091 for (i = 1, pos = 1; i <= env->num_mem; i++) {
2092 if (map[i].new_val > 0) {
2093 SCANENV_MEM_NODES(env)[pos] = SCANENV_MEM_NODES(env)[i];
2098 loc = env->capture_history;
2099 BIT_STATUS_CLEAR(env->capture_history);
2100 for (i = 1; i <= ONIG_MAX_CAPTURE_HISTORY_GROUP; i++) {
2101 if (BIT_STATUS_AT(loc, i)) {
2102 BIT_STATUS_ON_AT_SIMPLE(env->capture_history, map[i].new_val);
2106 env->num_mem = env->num_named;
2107 reg->num_mem = env->num_named;
2109 return onig_renumber_name_table(reg, map);
2113#ifdef USE_SUBEXP_CALL
2121 for (i = 0; i < uslist->num; i++) {
2122 en = NENCLOSE(uslist->us[i].target);
2123 if (! IS_ENCLOSE_ADDR_FIXED(en))
return ONIGERR_PARSER_BUG;
2124 addr = en->call_addr;
2125 offset = uslist->us[i].offset;
2127 BBUF_WRITE(reg, offset, &addr, SIZE_ABSADDR);
2133#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
2135quantifiers_memory_node_info(
Node* node)
2139 switch (NTYPE(node)) {
2145 v = quantifiers_memory_node_info(NCAR(node));
2147 }
while (v >= 0 && IS_NOT_NULL(node = NCDR(node)));
2151# ifdef USE_SUBEXP_CALL
2153 if (IS_CALL_RECURSION(NCALL(node))) {
2154 return NQ_TARGET_IS_EMPTY_REC;
2157 r = quantifiers_memory_node_info(NCALL(node)->target);
2164 if (qn->upper != 0) {
2165 r = quantifiers_memory_node_info(qn->target);
2174 case ENCLOSE_MEMORY:
2175 return NQ_TARGET_IS_EMPTY_MEM;
2178 case ENCLOSE_OPTION:
2179 case ENCLOSE_STOP_BACKTRACK:
2180 case ENCLOSE_CONDITION:
2181 case ENCLOSE_ABSENT:
2182 r = quantifiers_memory_node_info(en->target);
2205get_min_match_length(
Node* node, OnigDistance *min,
ScanEnv* env)
2211 switch (NTYPE(node)) {
2216 Node** nodes = SCANENV_MEM_NODES(env);
2218 if (br->state & NST_RECURSION)
break;
2220 backs = BACKREFS_P(br);
2221 if (backs[0] > env->num_mem)
return ONIGERR_INVALID_BACKREF;
2222 r = get_min_match_length(nodes[backs[0]], min, env);
2224 for (i = 1; i < br->back_num; i++) {
2225 if (backs[i] > env->num_mem)
return ONIGERR_INVALID_BACKREF;
2226 r = get_min_match_length(nodes[backs[i]], &tmin, env);
2228 if (*min > tmin) *min = tmin;
2233#ifdef USE_SUBEXP_CALL
2235 if (IS_CALL_RECURSION(NCALL(node))) {
2237 if (IS_ENCLOSE_MIN_FIXED(en))
2241 r = get_min_match_length(NCALL(node)->target, min, env);
2247 r = get_min_match_length(NCAR(node), &tmin, env);
2248 if (r == 0) *min += tmin;
2249 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
2258 r = get_min_match_length(x, &tmin, env);
2260 if (y == node) *min = tmin;
2261 else if (*min > tmin) *min = tmin;
2262 }
while (r == 0 && IS_NOT_NULL(y = NCDR(y)));
2269 *min = sn->end - sn->s;
2286 if (qn->lower > 0) {
2287 r = get_min_match_length(qn->target, min, env);
2289 *min = distance_multiply(*min, qn->lower);
2298 case ENCLOSE_MEMORY:
2299 if (IS_ENCLOSE_MIN_FIXED(en))
2302 if (IS_ENCLOSE_MARK1(NENCLOSE(node)))
2305 SET_ENCLOSE_STATUS(node, NST_MARK1);
2306 r = get_min_match_length(en->target, min, env);
2307 CLEAR_ENCLOSE_STATUS(node, NST_MARK1);
2310 SET_ENCLOSE_STATUS(node, NST_MIN_FIXED);
2316 case ENCLOSE_OPTION:
2317 case ENCLOSE_STOP_BACKTRACK:
2318 case ENCLOSE_CONDITION:
2319 r = get_min_match_length(en->target, min, env);
2322 case ENCLOSE_ABSENT:
2337get_max_match_length(
Node* node, OnigDistance *max,
ScanEnv* env)
2343 switch (NTYPE(node)) {
2346 r = get_max_match_length(NCAR(node), &tmax, env);
2348 *max = distance_add(*max, tmax);
2349 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
2354 r = get_max_match_length(NCAR(node), &tmax, env);
2355 if (r == 0 && *max < tmax) *max = tmax;
2356 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
2362 *max = sn->end - sn->s;
2367 *max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
2372 *max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
2379 Node** nodes = SCANENV_MEM_NODES(env);
2381 if (br->state & NST_RECURSION) {
2382 *max = ONIG_INFINITE_DISTANCE;
2385 backs = BACKREFS_P(br);
2386 for (i = 0; i < br->back_num; i++) {
2387 if (backs[i] > env->num_mem)
return ONIGERR_INVALID_BACKREF;
2388 r = get_max_match_length(nodes[backs[i]], &tmax, env);
2390 if (*max < tmax) *max = tmax;
2395#ifdef USE_SUBEXP_CALL
2397 if (! IS_CALL_RECURSION(NCALL(node)))
2398 r = get_max_match_length(NCALL(node)->target, max, env);
2400 *max = ONIG_INFINITE_DISTANCE;
2408 if (qn->upper != 0) {
2409 r = get_max_match_length(qn->target, max, env);
2410 if (r == 0 && *max != 0) {
2411 if (! IS_REPEAT_INFINITE(qn->upper))
2412 *max = distance_multiply(*max, qn->upper);
2414 *max = ONIG_INFINITE_DISTANCE;
2424 case ENCLOSE_MEMORY:
2425 if (IS_ENCLOSE_MAX_FIXED(en))
2428 if (IS_ENCLOSE_MARK1(NENCLOSE(node)))
2429 *max = ONIG_INFINITE_DISTANCE;
2431 SET_ENCLOSE_STATUS(node, NST_MARK1);
2432 r = get_max_match_length(en->target, max, env);
2433 CLEAR_ENCLOSE_STATUS(node, NST_MARK1);
2436 SET_ENCLOSE_STATUS(node, NST_MAX_FIXED);
2442 case ENCLOSE_OPTION:
2443 case ENCLOSE_STOP_BACKTRACK:
2444 case ENCLOSE_CONDITION:
2445 r = get_max_match_length(en->target, max, env);
2448 case ENCLOSE_ABSENT:
2462#define GET_CHAR_LEN_VARLEN -1
2463#define GET_CHAR_LEN_TOP_ALT_VARLEN -2
2467get_char_length_tree1(
Node* node,
regex_t* reg,
int*
len,
int level)
2474 switch (NTYPE(node)) {
2477 r = get_char_length_tree1(NCAR(node), reg, &tlen, level);
2479 *
len = (int )distance_add(*
len, tlen);
2480 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
2488 r = get_char_length_tree1(NCAR(node), reg, &tlen, level);
2489 while (r == 0 && IS_NOT_NULL(node = NCDR(node))) {
2490 r = get_char_length_tree1(NCAR(node), reg, &tlen2, level);
2499 r = GET_CHAR_LEN_TOP_ALT_VARLEN;
2501 r = GET_CHAR_LEN_VARLEN;
2513 while (s < sn->end) {
2514 s += enclen(reg->enc, s, sn->end);
2523 if (qn->lower == qn->upper) {
2524 r = get_char_length_tree1(qn->target, reg, &tlen, level);
2526 *
len = (int )distance_multiply(tlen, qn->lower);
2529 r = GET_CHAR_LEN_VARLEN;
2533#ifdef USE_SUBEXP_CALL
2535 if (! IS_CALL_RECURSION(NCALL(node)))
2536 r = get_char_length_tree1(NCALL(node)->target, reg,
len, level);
2538 r = GET_CHAR_LEN_VARLEN;
2555 case ENCLOSE_MEMORY:
2556#ifdef USE_SUBEXP_CALL
2557 if (IS_ENCLOSE_CLEN_FIXED(en))
2558 *
len = en->char_len;
2560 r = get_char_length_tree1(en->target, reg,
len, level);
2562 en->char_len = *
len;
2563 SET_ENCLOSE_STATUS(node, NST_CLEN_FIXED);
2568 case ENCLOSE_OPTION:
2569 case ENCLOSE_STOP_BACKTRACK:
2570 case ENCLOSE_CONDITION:
2571 r = get_char_length_tree1(en->target, reg,
len, level);
2573 case ENCLOSE_ABSENT:
2584 r = GET_CHAR_LEN_VARLEN;
2594 return get_char_length_tree1(node, reg,
len, 0);
2614 if (NCTYPE(y)->ctype == NCTYPE(x)->ctype &&
2615 NCTYPE(y)->not != NCTYPE(x)->not &&
2616 NCTYPE(y)->ascii_range == NCTYPE(x)->ascii_range)
2626 tmp = x; x = y; y = tmp;
2646 switch (NCTYPE(y)->ctype) {
2647 case ONIGENC_CTYPE_WORD:
2648 if (NCTYPE(y)->not == 0) {
2649 if (IS_NULL(xc->mbuf) && !IS_NCCLASS_NOT(xc)) {
2650 for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
2651 if (BITSET_AT(xc->bs, i)) {
2652 if (NCTYPE(y)->ascii_range) {
2653 if (IS_CODE_SB_WORD(reg->enc, i))
return 0;
2656 if (ONIGENC_IS_CODE_WORD(reg->enc, i))
return 0;
2665 if (IS_NOT_NULL(xc->mbuf))
return 0;
2666 for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
2668 if (NCTYPE(y)->ascii_range)
2669 is_word = IS_CODE_SB_WORD(reg->enc, i);
2671 is_word = ONIGENC_IS_CODE_WORD(reg->enc, i);
2673 if (!IS_NCCLASS_NOT(xc)) {
2674 if (BITSET_AT(xc->bs, i))
2678 if (! BITSET_AT(xc->bs, i))
2697 for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
2698 v = BITSET_AT(xc->bs, i);
2699 if ((v != 0 && !IS_NCCLASS_NOT(xc)) ||
2700 (v == 0 && IS_NCCLASS_NOT(xc))) {
2701 v = BITSET_AT(yc->bs, i);
2702 if ((v != 0 && !IS_NCCLASS_NOT(yc)) ||
2703 (v == 0 && IS_NCCLASS_NOT(yc)))
2707 if ((IS_NULL(xc->mbuf) && !IS_NCCLASS_NOT(xc)) ||
2708 (IS_NULL(yc->mbuf) && !IS_NCCLASS_NOT(yc)))
2727 if (NSTRING_LEN(x) == 0)
2732 switch (NCTYPE(y)->ctype) {
2733 case ONIGENC_CTYPE_WORD:
2734 if (NCTYPE(y)->ascii_range) {
2735 if (ONIGENC_IS_MBC_ASCII_WORD(reg->enc, xs->s, xs->end))
2736 return NCTYPE(y)->not;
2738 return !(NCTYPE(y)->not);
2741 if (ONIGENC_IS_MBC_WORD(reg->enc, xs->s, xs->end))
2742 return NCTYPE(y)->not;
2744 return !(NCTYPE(y)->not);
2756 code = ONIGENC_MBC_TO_CODE(reg->enc, xs->s,
2757 xs->s + ONIGENC_MBC_MAXLEN(reg->enc));
2758 return (onig_is_code_in_cc(reg->enc, code, cc) != 0 ? 0 : 1);
2766 len = NSTRING_LEN(x);
2767 if (
len > NSTRING_LEN(y))
len = NSTRING_LEN(y);
2768 if (NSTRING_IS_AMBIG(x) || NSTRING_IS_AMBIG(y)) {
2773 for (i = 0, p = ys->s, q = xs->s; (OnigDistance )i <
len; i++, p++, q++) {
2774 if (*p != *q)
return 1;
2794get_head_value_node(
Node* node,
int exact,
regex_t* reg)
2796 Node* n = NULL_NODE;
2798 switch (NTYPE(node)) {
2802#ifdef USE_SUBEXP_CALL
2815 n = get_head_value_node(NCAR(node), exact, reg);
2821 if (sn->end <= sn->s)
2825 NSTRING_IS_RAW(node) || !IS_IGNORECASE(reg->options)) {
2834 if (qn->lower > 0) {
2835#ifdef USE_OP_PUSH_OR_JUMP_EXACT
2836 if (IS_NOT_NULL(qn->head_exact))
2840 n = get_head_value_node(qn->target, exact, reg);
2849 case ENCLOSE_OPTION:
2851 OnigOptionType options = reg->options;
2853 reg->options = NENCLOSE(node)->option;
2854 n = get_head_value_node(NENCLOSE(node)->target, exact, reg);
2855 reg->options = options;
2859 case ENCLOSE_MEMORY:
2860 case ENCLOSE_STOP_BACKTRACK:
2861 case ENCLOSE_CONDITION:
2862 n = get_head_value_node(en->target, exact, reg);
2865 case ENCLOSE_ABSENT:
2872 if (NANCHOR(node)->type == ANCHOR_PREC_READ)
2873 n = get_head_value_node(NANCHOR(node)->target, exact, reg);
2884check_type_tree(
Node* node,
int type_mask,
int enclose_mask,
int anchor_mask)
2889 if ((NTYPE2BIT(type) & type_mask) == 0)
2896 r = check_type_tree(NCAR(node), type_mask, enclose_mask,
2898 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
2902 r = check_type_tree(NQTFR(node)->target, type_mask, enclose_mask,
2909 if ((en->type & enclose_mask) == 0)
2912 r = check_type_tree(en->target, type_mask, enclose_mask, anchor_mask);
2917 type = NANCHOR(node)->type;
2918 if ((type & anchor_mask) == 0)
2921 if (NANCHOR(node)->target)
2922 r = check_type_tree(NANCHOR(node)->target,
2923 type_mask, enclose_mask, anchor_mask);
2932#ifdef USE_SUBEXP_CALL
2934# define RECURSION_EXIST 1
2935# define RECURSION_INFINITE 2
2938subexp_inf_recursive_check(
Node* node,
ScanEnv* env,
int head)
2953 ret = subexp_inf_recursive_check(NCAR(x), env, head);
2954 if (ret < 0 || ret == RECURSION_INFINITE)
return ret;
2957 ret = get_min_match_length(NCAR(x), &min, env);
2958 if (ret != 0)
return ret;
2959 if (min != 0) head = 0;
2961 }
while (IS_NOT_NULL(x = NCDR(x)));
2968 r = RECURSION_EXIST;
2970 ret = subexp_inf_recursive_check(NCAR(node), env, head);
2971 if (ret < 0 || ret == RECURSION_INFINITE)
return ret;
2973 }
while (IS_NOT_NULL(node = NCDR(node)));
2978 r = subexp_inf_recursive_check(NQTFR(node)->target, env, head);
2979 if (r == RECURSION_EXIST) {
2980 if (NQTFR(node)->lower == 0) r = 0;
2988 case ANCHOR_PREC_READ:
2989 case ANCHOR_PREC_READ_NOT:
2990 case ANCHOR_LOOK_BEHIND:
2991 case ANCHOR_LOOK_BEHIND_NOT:
2992 r = subexp_inf_recursive_check(an->target, env, head);
2999 r = subexp_inf_recursive_check(NCALL(node)->target, env, head);
3003 if (IS_ENCLOSE_MARK2(NENCLOSE(node)))
3005 else if (IS_ENCLOSE_MARK1(NENCLOSE(node)))
3006 return (head == 0 ? RECURSION_EXIST : RECURSION_INFINITE);
3008 SET_ENCLOSE_STATUS(node, NST_MARK2);
3009 r = subexp_inf_recursive_check(NENCLOSE(node)->target, env, head);
3010 CLEAR_ENCLOSE_STATUS(node, NST_MARK2);
3022subexp_inf_recursive_check_trav(
Node* node,
ScanEnv* env)
3032 r = subexp_inf_recursive_check_trav(NCAR(node), env);
3033 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
3037 r = subexp_inf_recursive_check_trav(NQTFR(node)->target, env);
3044 case ANCHOR_PREC_READ:
3045 case ANCHOR_PREC_READ_NOT:
3046 case ANCHOR_LOOK_BEHIND:
3047 case ANCHOR_LOOK_BEHIND_NOT:
3048 r = subexp_inf_recursive_check_trav(an->target, env);
3058 if (IS_ENCLOSE_RECURSION(en)) {
3059 SET_ENCLOSE_STATUS(node, NST_MARK1);
3060 r = subexp_inf_recursive_check(en->target, env, 1);
3061 if (r > 0)
return ONIGERR_NEVER_ENDING_RECURSION;
3062 CLEAR_ENCLOSE_STATUS(node, NST_MARK1);
3064 r = subexp_inf_recursive_check_trav(en->target, env);
3077subexp_recursive_check(
Node* node)
3081 switch (NTYPE(node)) {
3085 r |= subexp_recursive_check(NCAR(node));
3086 }
while (IS_NOT_NULL(node = NCDR(node)));
3090 r = subexp_recursive_check(NQTFR(node)->target);
3097 case ANCHOR_PREC_READ:
3098 case ANCHOR_PREC_READ_NOT:
3099 case ANCHOR_LOOK_BEHIND:
3100 case ANCHOR_LOOK_BEHIND_NOT:
3101 r = subexp_recursive_check(an->target);
3108 r = subexp_recursive_check(NCALL(node)->target);
3109 if (r != 0) SET_CALL_RECURSION(node);
3113 if (IS_ENCLOSE_MARK2(NENCLOSE(node)))
3115 else if (IS_ENCLOSE_MARK1(NENCLOSE(node)))
3118 SET_ENCLOSE_STATUS(node, NST_MARK2);
3119 r = subexp_recursive_check(NENCLOSE(node)->target);
3120 CLEAR_ENCLOSE_STATUS(node, NST_MARK2);
3133subexp_recursive_check_trav(
Node* node,
ScanEnv* env)
3135# define FOUND_CALLED_NODE 1
3147 ret = subexp_recursive_check_trav(NCAR(node), env);
3148 if (ret == FOUND_CALLED_NODE) r = FOUND_CALLED_NODE;
3149 else if (ret < 0)
return ret;
3150 }
while (IS_NOT_NULL(node = NCDR(node)));
3155 r = subexp_recursive_check_trav(NQTFR(node)->target, env);
3156 if (NQTFR(node)->upper == 0) {
3157 if (r == FOUND_CALLED_NODE)
3158 NQTFR(node)->is_referred = 1;
3166 case ANCHOR_PREC_READ:
3167 case ANCHOR_PREC_READ_NOT:
3168 case ANCHOR_LOOK_BEHIND:
3169 case ANCHOR_LOOK_BEHIND_NOT:
3170 r = subexp_recursive_check_trav(an->target, env);
3180 if (! IS_ENCLOSE_RECURSION(en)) {
3181 if (IS_ENCLOSE_CALLED(en)) {
3182 SET_ENCLOSE_STATUS(node, NST_MARK1);
3183 r = subexp_recursive_check(en->target);
3184 if (r != 0) SET_ENCLOSE_STATUS(node, NST_RECURSION);
3185 CLEAR_ENCLOSE_STATUS(node, NST_MARK1);
3188 r = subexp_recursive_check_trav(en->target, env);
3189 if (IS_ENCLOSE_CALLED(en))
3190 r |= FOUND_CALLED_NODE;
3211 r = setup_subexp_call(NCAR(node), env);
3212 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
3217 r = setup_subexp_call(NCAR(node), env);
3218 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
3222 r = setup_subexp_call(NQTFR(node)->target, env);
3225 r = setup_subexp_call(NENCLOSE(node)->target, env);
3231 Node** nodes = SCANENV_MEM_NODES(env);
3233 if (cn->group_num != 0) {
3234 int gnum = cn->group_num;
3236# ifdef USE_NAMED_GROUP
3237 if (env->num_named > 0 &&
3238 IS_SYNTAX_BV(env->syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
3239 !ONIG_IS_OPTION_ON(env->option, ONIG_OPTION_CAPTURE_GROUP)) {
3240 return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
3243 if (gnum > env->num_mem) {
3244 onig_scan_env_set_error_string(env,
3245 ONIGERR_UNDEFINED_GROUP_REFERENCE, cn->name, cn->name_end);
3246 return ONIGERR_UNDEFINED_GROUP_REFERENCE;
3249# ifdef USE_NAMED_GROUP
3252 cn->target = nodes[cn->group_num];
3253 if (IS_NULL(cn->target)) {
3254 onig_scan_env_set_error_string(env,
3255 ONIGERR_UNDEFINED_NAME_REFERENCE, cn->name, cn->name_end);
3256 return ONIGERR_UNDEFINED_NAME_REFERENCE;
3258 SET_ENCLOSE_STATUS(cn->target, NST_CALLED);
3259 BIT_STATUS_ON_AT(env->bt_mem_start, cn->group_num);
3260 cn->unset_addr_list = env->unset_addr_list;
3262# ifdef USE_NAMED_GROUP
3263# ifdef USE_PERL_SUBEXP_CALL
3264 else if (cn->name == cn->name_end) {
3271 int n = onig_name_to_group_numbers(env->reg, cn->name, cn->name_end,
3274 onig_scan_env_set_error_string(env,
3275 ONIGERR_UNDEFINED_NAME_REFERENCE, cn->name, cn->name_end);
3276 return ONIGERR_UNDEFINED_NAME_REFERENCE;
3279 ! IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME_CALL)) {
3280 onig_scan_env_set_error_string(env,
3281 ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL, cn->name, cn->name_end);
3282 return ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL;
3285 cn->group_num = refs[0];
3298 case ANCHOR_PREC_READ:
3299 case ANCHOR_PREC_READ_NOT:
3300 case ANCHOR_LOOK_BEHIND:
3301 case ANCHOR_LOOK_BEHIND_NOT:
3302 r = setup_subexp_call(an->target, env);
3316#define IN_ALT (1<<0)
3317#define IN_NOT (1<<1)
3318#define IN_REPEAT (1<<2)
3319#define IN_VAR_REPEAT (1<<3)
3320#define IN_CALL (1<<4)
3321#define IN_RECCALL (1<<5)
3322#define IN_LOOK_BEHIND (1<<6)
3329divide_look_behind_alternatives(
Node* node)
3331 Node *head, *np, *insert_node;
3333 int anc_type = an->type;
3337 swap_node(node, head);
3339 NANCHOR(head)->target = np;
3342 while ((np = NCDR(np)) != NULL_NODE) {
3343 insert_node = onig_node_new_anchor(anc_type);
3344 CHECK_NULL_RETURN_MEMERR(insert_node);
3345 NANCHOR(insert_node)->target = NCAR(np);
3346 NCAR(np) = insert_node;
3349 if (anc_type == ANCHOR_LOOK_BEHIND_NOT) {
3352 SET_NTYPE(np, NT_LIST);
3353 }
while ((np = NCDR(np)) != NULL_NODE);
3364 r = get_char_length_tree(an->target, reg, &
len);
3367 else if (r == GET_CHAR_LEN_VARLEN)
3368 r = ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
3369 else if (r == GET_CHAR_LEN_TOP_ALT_VARLEN) {
3370 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND))
3371 r = divide_look_behind_alternatives(node);
3373 r = ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
3386 if (type == NT_QTFR) {
3388 if (qn->greedy && IS_REPEAT_INFINITE(qn->upper)) {
3389#ifdef USE_QTFR_PEEK_NEXT
3390 Node* n = get_head_value_node(next_node, 1, reg);
3392 if (IS_NOT_NULL(n) && NSTR(n)->s[0] !=
'\0') {
3393 qn->next_head_exact = n;
3397 if (qn->lower <= 1) {
3398 int ttype = NTYPE(qn->target);
3399 if (IS_NODE_TYPE_SIMPLE(ttype)) {
3401 x = get_head_value_node(qn->target, 0, reg);
3402 if (IS_NOT_NULL(x)) {
3403 y = get_head_value_node(next_node, 0, reg);
3404 if (IS_NOT_NULL(y) && is_not_included(x, y, reg)) {
3405 Node* en = onig_node_new_enclose(ENCLOSE_STOP_BACKTRACK);
3406 CHECK_NULL_RETURN_MEMERR(en);
3407 SET_ENCLOSE_STATUS(en, NST_STOP_BT_SIMPLE_REPEAT);
3408 swap_node(node, en);
3409 NENCLOSE(node)->target = en;
3416 else if (type == NT_ENCLOSE) {
3418 if (en->type == ENCLOSE_MEMORY && !IS_ENCLOSE_CALLED(en)) {
3428update_string_node_case_fold(
regex_t* reg,
Node *node)
3430 UChar *p, *end, buf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
3431 UChar *sbuf, *ebuf, *sp;
3433 OnigDistance sbuf_size;
3437 sbuf_size = (end - sn->s) * 2;
3438 sbuf = (UChar* )
xmalloc(sbuf_size);
3439 CHECK_NULL_RETURN_MEMERR(sbuf);
3440 ebuf = sbuf + sbuf_size;
3445 len = ONIGENC_MBC_CASE_FOLD(reg->enc, reg->case_fold_flag, &p, end, buf);
3446 for (i = 0; i <
len; i++) {
3448 UChar* p = (UChar* )
xrealloc(sbuf, sbuf_size * 2);
3451 return ONIGERR_MEMORY;
3454 sp = sbuf + sbuf_size;
3456 ebuf = sbuf + sbuf_size;
3463 r = onig_node_str_set(node, sbuf, sp);
3470expand_case_fold_make_rem_string(
Node** rnode, UChar *s, UChar *end,
3476 node = onig_node_new_str(s, end);
3477 if (IS_NULL(node))
return ONIGERR_MEMORY;
3479 r = update_string_node_case_fold(reg, node);
3481 onig_node_free(node);
3485 NSTRING_SET_AMBIG(node);
3486 NSTRING_SET_DONT_GET_OPT_INFO(node);
3497 for (i = 0; i < item_num; i++) {
3498 if (items[i].byte_len != slen) {
3501 if (items[i].code_len != 1) {
3510 UChar *p,
int slen, UChar *end,
3513 int r, i, j,
len, varlen;
3514 Node *anode, *var_anode, *snode, *xnode, *an;
3515 UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
3517 *rnode = var_anode = NULL_NODE;
3520 for (i = 0; i < item_num; i++) {
3521 if (items[i].byte_len != slen) {
3528 *rnode = var_anode = onig_node_new_alt(NULL_NODE, NULL_NODE);
3529 if (IS_NULL(var_anode))
return ONIGERR_MEMORY;
3531 xnode = onig_node_new_list(NULL, NULL);
3532 if (IS_NULL(xnode))
goto mem_err;
3533 NCAR(var_anode) = xnode;
3535 anode = onig_node_new_alt(NULL_NODE, NULL_NODE);
3536 if (IS_NULL(anode))
goto mem_err;
3537 NCAR(xnode) = anode;
3540 *rnode = anode = onig_node_new_alt(NULL_NODE, NULL_NODE);
3541 if (IS_NULL(anode))
return ONIGERR_MEMORY;
3544 snode = onig_node_new_str(p, p + slen);
3545 if (IS_NULL(snode))
goto mem_err;
3547 NCAR(anode) = snode;
3549 for (i = 0; i < item_num; i++) {
3550 snode = onig_node_new_str(NULL, NULL);
3551 if (IS_NULL(snode))
goto mem_err;
3553 for (j = 0; j < items[i].code_len; j++) {
3554 len = ONIGENC_CODE_TO_MBC(reg->enc, items[i].code[j], buf);
3560 r = onig_node_str_cat(snode, buf, buf +
len);
3561 if (r != 0)
goto mem_err2;
3564 an = onig_node_new_alt(NULL_NODE, NULL_NODE);
3569 if (items[i].byte_len != slen) {
3571 UChar *q = p + items[i].byte_len;
3574 r = expand_case_fold_make_rem_string(&rem, q, end, reg);
3580 xnode = onig_node_list_add(NULL_NODE, snode);
3581 if (IS_NULL(xnode)) {
3583 onig_node_free(rem);
3586 if (IS_NULL(onig_node_list_add(xnode, rem))) {
3588 onig_node_free(xnode);
3589 onig_node_free(rem);
3599 NCDR(var_anode) = an;
3612 onig_node_free(snode);
3615 onig_node_free(*rnode);
3617 return ONIGERR_MEMORY;
3620#define THRESHOLD_CASE_FOLD_ALT_FOR_EXPANSION 8
3623expand_case_fold_string(
Node* node,
regex_t* reg,
int state)
3625 int r, n,
len, alt_num;
3627 int is_in_look_behind;
3628 UChar *start, *end, *p;
3629 Node *top_root, *root, *snode, *prev_node;
3633 if (NSTRING_IS_AMBIG(node))
return 0;
3639 if (start >= end)
return 0;
3641 is_in_look_behind = (state & IN_LOOK_BEHIND) != 0;
3644 top_root = root = prev_node = snode = NULL_NODE;
3648 n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(reg->enc, reg->case_fold_flag,
3655 len = enclen(reg->enc, p, end);
3657 varlen = is_case_fold_variable_len(n, items,
len);
3658 if (n == 0 || varlen == 0 || is_in_look_behind) {
3659 if (IS_NULL(snode)) {
3660 if (IS_NULL(root) && IS_NOT_NULL(prev_node)) {
3661 onig_node_free(top_root);
3662 top_root = root = onig_node_list_add(NULL_NODE, prev_node);
3663 if (IS_NULL(root)) {
3664 onig_node_free(prev_node);
3669 prev_node = snode = onig_node_new_str(NULL, NULL);
3670 if (IS_NULL(snode))
goto mem_err;
3671 if (IS_NOT_NULL(root)) {
3672 if (IS_NULL(onig_node_list_add(root, snode))) {
3673 onig_node_free(snode);
3679 r = onig_node_str_cat(snode, p, p +
len);
3680 if (r != 0)
goto err;
3684 if (alt_num > THRESHOLD_CASE_FOLD_ALT_FOR_EXPANSION)
break;
3686 if (IS_NOT_NULL(snode)) {
3687 r = update_string_node_case_fold(reg, snode);
3689 NSTRING_SET_AMBIG(snode);
3692 if (IS_NULL(root) && IS_NOT_NULL(prev_node)) {
3693 onig_node_free(top_root);
3694 top_root = root = onig_node_list_add(NULL_NODE, prev_node);
3695 if (IS_NULL(root)) {
3696 onig_node_free(prev_node);
3701 r = expand_case_fold_string_alt(n, items, p,
len, end, reg, &prev_node);
3702 if (r < 0)
goto mem_err;
3704 if (IS_NULL(root)) {
3705 top_root = prev_node;
3708 if (IS_NULL(onig_node_list_add(root, prev_node))) {
3709 onig_node_free(prev_node);
3714 root = NCAR(prev_node);
3717 if (IS_NOT_NULL(root)) {
3718 if (IS_NULL(onig_node_list_add(root, prev_node))) {
3719 onig_node_free(prev_node);
3730 if (IS_NOT_NULL(snode)) {
3731 r = update_string_node_case_fold(reg, snode);
3733 NSTRING_SET_AMBIG(snode);
3740 r = expand_case_fold_make_rem_string(&srem, p, end, reg);
3741 if (r != 0)
goto mem_err;
3743 if (IS_NOT_NULL(prev_node) && IS_NULL(root)) {
3744 onig_node_free(top_root);
3745 top_root = root = onig_node_list_add(NULL_NODE, prev_node);
3746 if (IS_NULL(root)) {
3747 onig_node_free(srem);
3748 onig_node_free(prev_node);
3753 if (IS_NULL(root)) {
3757 if (IS_NULL(onig_node_list_add(root, srem))) {
3758 onig_node_free(srem);
3765 top_root = (IS_NOT_NULL(top_root) ? top_root : prev_node);
3766 swap_node(node, top_root);
3767 onig_node_free(top_root);
3774 onig_node_free(top_root);
3779#ifdef USE_COMBINATION_EXPLOSION_CHECK
3781# define CEC_THRES_NUM_BIG_REPEAT 512
3782# define CEC_INFINITE_NUM 0x7fffffff
3784# define CEC_IN_INFINITE_REPEAT (1<<0)
3785# define CEC_IN_FINITE_REPEAT (1<<1)
3786# define CEC_CONT_BIG_REPEAT (1<<2)
3789setup_comb_exp_check(
Node* node,
int state,
ScanEnv* env)
3799 r = setup_comb_exp_check(NCAR(node), r, env);
3800 }
while (r >= 0 && IS_NOT_NULL(node = NCDR(node)));
3808 ret = setup_comb_exp_check(NCAR(node), state, env);
3810 }
while (ret >= 0 && IS_NOT_NULL(node = NCDR(node)));
3816 int child_state = state;
3819 Node* target = qn->target;
3822 if (! IS_REPEAT_INFINITE(qn->upper)) {
3823 if (qn->upper > 1) {
3825 child_state |= CEC_IN_FINITE_REPEAT;
3828 if (env->backrefed_mem == 0) {
3829 if (NTYPE(qn->target) == NT_ENCLOSE) {
3831 if (en->type == ENCLOSE_MEMORY) {
3832 if (NTYPE(en->target) == NT_QTFR) {
3834 if (IS_REPEAT_INFINITE(q->upper)
3835 && q->greedy == qn->greedy) {
3836 qn->upper = (qn->lower == 0 ? 1 : qn->lower);
3838 child_state = state;
3847 if (state & CEC_IN_FINITE_REPEAT) {
3848 qn->comb_exp_check_num = -1;
3851 if (IS_REPEAT_INFINITE(qn->upper)) {
3852 var_num = CEC_INFINITE_NUM;
3853 child_state |= CEC_IN_INFINITE_REPEAT;
3856 var_num = qn->upper - qn->lower;
3859 if (var_num >= CEC_THRES_NUM_BIG_REPEAT)
3860 add_state |= CEC_CONT_BIG_REPEAT;
3862 if (((state & CEC_IN_INFINITE_REPEAT) != 0 && var_num != 0) ||
3863 ((state & CEC_CONT_BIG_REPEAT) != 0 &&
3864 var_num >= CEC_THRES_NUM_BIG_REPEAT)) {
3865 if (qn->comb_exp_check_num == 0) {
3866 env->num_comb_exp_check++;
3867 qn->comb_exp_check_num = env->num_comb_exp_check;
3868 if (env->curr_max_regnum > env->comb_exp_max_regnum)
3869 env->comb_exp_max_regnum = env->curr_max_regnum;
3874 r = setup_comb_exp_check(target, child_state, env);
3884 case ENCLOSE_MEMORY:
3886 if (env->curr_max_regnum < en->regnum)
3887 env->curr_max_regnum = en->regnum;
3889 r = setup_comb_exp_check(en->target, state, env);
3894 r = setup_comb_exp_check(en->target, state, env);
3900# ifdef USE_SUBEXP_CALL
3902 if (IS_CALL_RECURSION(NCALL(node)))
3903 env->has_recursion = 1;
3905 r = setup_comb_exp_check(NCALL(node)->target, state, env);
3936 Node* prev = NULL_NODE;
3938 r = setup_tree(NCAR(node), reg, state, env);
3939 if (IS_NOT_NULL(prev) && r == 0) {
3940 r = next_setup(prev, NCAR(node), reg);
3943 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
3949 r = setup_tree(NCAR(node), reg, (state | IN_ALT), env);
3950 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
3957 if (IS_IGNORECASE(reg->options) && !NSTRING_IS_RAW(node)) {
3958 r = expand_case_fold_string(node, reg, state);
3966#ifdef USE_SUBEXP_CALL
3975 Node** nodes = SCANENV_MEM_NODES(env);
3978 for (i = 0; i < br->back_num; i++) {
3979 if (p[i] > env->num_mem)
return ONIGERR_INVALID_BACKREF;
3980 BIT_STATUS_ON_AT(env->backrefed_mem, p[i]);
3981 BIT_STATUS_ON_AT(env->bt_mem_start, p[i]);
3982#ifdef USE_BACKREF_WITH_LEVEL
3983 if (IS_BACKREF_NEST_LEVEL(br)) {
3984 BIT_STATUS_ON_AT(env->bt_mem_end, p[i]);
3987 SET_ENCLOSE_STATUS(nodes[p[i]], NST_MEM_BACKREFED);
3996 Node* target = qn->target;
3998 if ((state & IN_REPEAT) != 0) {
3999 qn->state |= NST_IN_REPEAT;
4002 if (IS_REPEAT_INFINITE(qn->upper) || qn->upper >= 1) {
4003 r = get_min_match_length(target, &d, env);
4006 qn->target_empty_info = NQ_TARGET_IS_EMPTY;
4007#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
4008 r = quantifiers_memory_node_info(target);
4011 qn->target_empty_info = r;
4015 r = get_max_match_length(target, &d, env);
4016 if (r == 0 && d == 0) {
4019 if (qn->lower > 1) qn->lower = 1;
4020 if (NTYPE(target) == NT_STR) {
4021 qn->upper = qn->lower = 0;
4029 if (qn->lower != qn->upper)
4030 state |= IN_VAR_REPEAT;
4031 r = setup_tree(target, reg, state, env);
4035#define EXPAND_STRING_MAX_LENGTH 100
4036 if (NTYPE(target) == NT_STR) {
4037 if (qn->lower > 1) {
4038 int i, n = qn->lower;
4039 OnigDistance
len = NSTRING_LEN(target);
4043 np = onig_node_new_str(sn->s, sn->end);
4044 if (IS_NULL(np))
return ONIGERR_MEMORY;
4045 NSTR(np)->flag = sn->flag;
4047 for (i = 1; i < n && (i+1) *
len <= EXPAND_STRING_MAX_LENGTH; i++) {
4048 r = onig_node_str_cat(np, sn->s, sn->end);
4054 if (i < qn->upper || IS_REPEAT_INFINITE(qn->upper)) {
4058 if (! IS_REPEAT_INFINITE(qn->upper))
4061 np1 = onig_node_new_list(np, NULL);
4064 return ONIGERR_MEMORY;
4066 swap_node(np1, node);
4067 np2 = onig_node_list_add(node, np1);
4069 onig_node_free(np1);
4070 return ONIGERR_MEMORY;
4074 swap_node(np, node);
4081#ifdef USE_OP_PUSH_OR_JUMP_EXACT
4082 if (qn->greedy && (qn->target_empty_info != 0)) {
4083 if (NTYPE(target) == NT_QTFR) {
4085 if (IS_NOT_NULL(tqn->head_exact)) {
4086 qn->head_exact = tqn->head_exact;
4087 tqn->head_exact = NULL;
4091 qn->head_exact = get_head_value_node(qn->target, 1, reg);
4103 case ENCLOSE_OPTION:
4105 OnigOptionType options = reg->options;
4106 reg->options = NENCLOSE(node)->option;
4107 r = setup_tree(NENCLOSE(node)->target, reg, state, env);
4108 reg->options = options;
4112 case ENCLOSE_MEMORY:
4113 if ((state & (IN_ALT | IN_NOT | IN_VAR_REPEAT | IN_CALL)) != 0) {
4114 BIT_STATUS_ON_AT(env->bt_mem_start, en->regnum);
4117 if (IS_ENCLOSE_CALLED(en))
4119 if (IS_ENCLOSE_RECURSION(en))
4120 state |= IN_RECCALL;
4121 else if ((state & IN_RECCALL) != 0)
4122 SET_CALL_RECURSION(node);
4123 r = setup_tree(en->target, reg, state, env);
4126 case ENCLOSE_STOP_BACKTRACK:
4128 Node* target = en->target;
4129 r = setup_tree(target, reg, state, env);
4130 if (NTYPE(target) == NT_QTFR) {
4132 if (IS_REPEAT_INFINITE(tqn->upper) && tqn->lower <= 1 &&
4134 int qtype = NTYPE(tqn->target);
4135 if (IS_NODE_TYPE_SIMPLE(qtype))
4136 SET_ENCLOSE_STATUS(node, NST_STOP_BT_SIMPLE_REPEAT);
4142 case ENCLOSE_CONDITION:
4143#ifdef USE_NAMED_GROUP
4144 if (! IS_ENCLOSE_NAME_REF(NENCLOSE(node)) &&
4145 env->num_named > 0 &&
4146 IS_SYNTAX_BV(env->syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
4147 !ONIG_IS_OPTION_ON(env->option, ONIG_OPTION_CAPTURE_GROUP)) {
4148 return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
4151 if (NENCLOSE(node)->regnum > env->num_mem)
4152 return ONIGERR_INVALID_BACKREF;
4153 r = setup_tree(NENCLOSE(node)->target, reg, state, env);
4156 case ENCLOSE_ABSENT:
4157 r = setup_tree(NENCLOSE(node)->target, reg, state, env);
4168 case ANCHOR_PREC_READ:
4169 r = setup_tree(an->target, reg, state, env);
4171 case ANCHOR_PREC_READ_NOT:
4172 r = setup_tree(an->target, reg, (state | IN_NOT), env);
4176#define ALLOWED_TYPE_IN_LB \
4177 ( BIT_NT_LIST | BIT_NT_ALT | BIT_NT_STR | BIT_NT_CCLASS | BIT_NT_CTYPE | \
4178 BIT_NT_CANY | BIT_NT_ANCHOR | BIT_NT_ENCLOSE | BIT_NT_QTFR | BIT_NT_CALL )
4180#define ALLOWED_ENCLOSE_IN_LB ( ENCLOSE_MEMORY | ENCLOSE_OPTION )
4181#define ALLOWED_ENCLOSE_IN_LB_NOT ENCLOSE_OPTION
4183#define ALLOWED_ANCHOR_IN_LB \
4184( ANCHOR_LOOK_BEHIND | ANCHOR_LOOK_BEHIND_NOT | ANCHOR_BEGIN_LINE | \
4185 ANCHOR_END_LINE | ANCHOR_BEGIN_BUF | ANCHOR_BEGIN_POSITION | ANCHOR_KEEP | \
4186 ANCHOR_WORD_BOUND | ANCHOR_NOT_WORD_BOUND | \
4187 ANCHOR_WORD_BEGIN | ANCHOR_WORD_END )
4188#define ALLOWED_ANCHOR_IN_LB_NOT \
4189( ANCHOR_LOOK_BEHIND | ANCHOR_LOOK_BEHIND_NOT | ANCHOR_BEGIN_LINE | \
4190 ANCHOR_END_LINE | ANCHOR_BEGIN_BUF | ANCHOR_BEGIN_POSITION | ANCHOR_KEEP | \
4191 ANCHOR_WORD_BOUND | ANCHOR_NOT_WORD_BOUND | \
4192 ANCHOR_WORD_BEGIN | ANCHOR_WORD_END )
4194 case ANCHOR_LOOK_BEHIND:
4196 r = check_type_tree(an->target, ALLOWED_TYPE_IN_LB,
4197 ALLOWED_ENCLOSE_IN_LB, ALLOWED_ANCHOR_IN_LB);
4198 if (r < 0)
return r;
4199 if (r > 0)
return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
4200 if (NTYPE(node) != NT_ANCHOR)
goto restart;
4201 r = setup_tree(an->target, reg, (state | IN_LOOK_BEHIND), env);
4202 if (r != 0)
return r;
4203 r = setup_look_behind(node, reg, env);
4207 case ANCHOR_LOOK_BEHIND_NOT:
4209 r = check_type_tree(an->target, ALLOWED_TYPE_IN_LB,
4210 ALLOWED_ENCLOSE_IN_LB_NOT, ALLOWED_ANCHOR_IN_LB_NOT);
4211 if (r < 0)
return r;
4212 if (r > 0)
return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
4213 if (NTYPE(node) != NT_ANCHOR)
goto restart;
4214 r = setup_tree(an->target, reg, (state | IN_NOT | IN_LOOK_BEHIND),
4216 if (r != 0)
return r;
4217 r = setup_look_behind(node, reg, env);
4233set_bm_skip(UChar* s, UChar* end,
regex_t* reg,
4234 UChar skip[],
int ignore_case)
4236 OnigDistance i,
len;
4237 int clen, flen, n, j, k;
4238 UChar *p, buf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
4243 if (
len >= ONIG_CHAR_TABLE_SIZE) {
4245 return ONIGERR_TYPE_BUG;
4249 for (i = 0; i <
len; i += clen) {
4251 n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
4253 clen = enclen(enc, p, end);
4255 clen = (int )(end - p);
4257 for (j = 0; j < n; j++) {
4258 if ((items[j].code_len != 1) || (items[j].byte_len != clen)) {
4263 flen = ONIGENC_CODE_TO_MBC(enc, items[j].code[0], buf);
4275 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
4276 skip[i] = (UChar )(
len + 1);
4278 for (i = 0; i <
len; i += clen) {
4281 n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
4283 clen = enclen(enc, p, end);
4285 clen = (int )(end - p);
4287 for (j = 0; j < clen; j++) {
4288 skip[s[i + j]] = (UChar )(
len - i - j);
4289 for (k = 0; k < n; k++) {
4290 ONIGENC_CODE_TO_MBC(enc, items[k].code[0], buf);
4291 skip[buf[j]] = (UChar )(
len - i - j);
4307 OnigOptionType options;
4308 OnigCaseFoldType case_fold_flag;
4324 UChar s[OPT_EXACT_MAXLEN];
4332 UChar map[ONIG_CHAR_TABLE_SIZE];
4350 static const short int ByteValTable[] = {
4351 5, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10, 1, 1, 10, 1, 1,
4352 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4353 12, 4, 7, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5,
4354 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5,
4355 5, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
4356 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 5, 5, 5,
4357 5, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
4358 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 1
4361 if (i < numberof(ByteValTable)) {
4362 if (i == 0 && ONIGENC_MBC_MINLEN(enc) > 1)
4365 return (
int )ByteValTable[i];
4375 static const short int dist_vals[] = {
4376 1000, 500, 333, 250, 200, 167, 143, 125, 111, 100,
4377 91, 83, 77, 71, 67, 63, 59, 56, 53, 50,
4378 48, 45, 43, 42, 40, 38, 37, 36, 34, 33,
4379 32, 31, 30, 29, 29, 28, 27, 26, 26, 25,
4380 24, 24, 23, 23, 22, 22, 21, 21, 20, 20,
4381 20, 19, 19, 19, 18, 18, 18, 17, 17, 17,
4382 16, 16, 16, 16, 15, 15, 15, 15, 14, 14,
4383 14, 14, 14, 14, 13, 13, 13, 13, 13, 13,
4384 12, 12, 12, 12, 12, 12, 11, 11, 11, 11,
4385 11, 11, 11, 11, 11, 10, 10, 10, 10, 10
4390 if (mm->max == ONIG_INFINITE_DISTANCE)
return 0;
4392 d = mm->max - mm->min;
4393 if (d < numberof(dist_vals))
4395 return (
int )dist_vals[d];
4403 if (v2 <= 0)
return -1;
4404 if (v1 <= 0)
return 1;
4406 v1 *= distance_value(d1);
4407 v2 *= distance_value(d2);
4409 if (v2 > v1)
return 1;
4410 if (v2 < v1)
return -1;
4412 if (d2->min < d1->min)
return 1;
4413 if (d2->min > d1->min)
return -1;
4420 return (a->min == b->min && a->max == b->max) ? 1 : 0;
4425set_mml(
MinMaxLen* mml, OnigDistance min, OnigDistance max)
4434 mml->min = mml->max = 0;
4440 to->min = from->min;
4441 to->max = from->max;
4447 to->min = distance_add(to->min, from->min);
4448 to->max = distance_add(to->max, from->max);
4455 to->min = distance_add(to->min,
len);
4456 to->max = distance_add(to->max,
len);
4463 if (to->min > from->min) to->min = from->min;
4464 if (to->max < from->max) to->max = from->max;
4476 anc->left_anchor = 0;
4477 anc->right_anchor = 0;
4488 OnigDistance left_len, OnigDistance right_len)
4490 clear_opt_anc_info(to);
4492 to->left_anchor = left->left_anchor;
4493 if (left_len == 0) {
4494 to->left_anchor |= right->left_anchor;
4497 to->right_anchor = right->right_anchor;
4498 if (right_len == 0) {
4499 to->right_anchor |= left->right_anchor;
4502 to->right_anchor |= (left->right_anchor & ANCHOR_PREC_READ_NOT);
4507is_left_anchor(
int anc)
4509 if (anc == ANCHOR_END_BUF || anc == ANCHOR_SEMI_END_BUF ||
4510 anc == ANCHOR_END_LINE || anc == ANCHOR_PREC_READ ||
4511 anc == ANCHOR_PREC_READ_NOT)
4520 if ((to->left_anchor & anc) != 0)
return 1;
4522 return ((to->right_anchor & anc) != 0 ? 1 : 0);
4528 if (is_left_anchor(anc))
4529 to->left_anchor |= anc;
4531 to->right_anchor |= anc;
4537 if (is_left_anchor(anc))
4538 to->left_anchor &= ~anc;
4540 to->right_anchor &= ~anc;
4546 to->left_anchor &= add->left_anchor;
4547 to->right_anchor &= add->right_anchor;
4553 return (ex->len >= OPT_EXACT_MAXLEN ? 1 : 0);
4559 clear_mml(&ex->mmd);
4560 clear_opt_anc_info(&ex->anc);
4562 ex->ignore_case = -1;
4580 if (to->ignore_case < 0)
4581 to->ignore_case = add->ignore_case;
4582 else if (to->ignore_case != add->ignore_case)
4587 for (i = to->len; p < end; ) {
4588 len = enclen(enc, p, end);
4589 if (i +
len > OPT_EXACT_MAXLEN)
break;
4590 for (j = 0; j <
len && p < end; j++)
4595 to->reach_end = (p == end ? add->reach_end : 0);
4597 concat_opt_anc_info(&tanc, &to->anc, &add->anc, 1, 1);
4598 if (! to->reach_end) tanc.right_anchor = 0;
4599 copy_opt_anc_info(&to->anc, &tanc);
4603concat_opt_exact_info_str(
OptExactInfo* to, UChar* s, UChar* end,
4609 for (i = to->len, p = s; p < end && i < OPT_EXACT_MAXLEN; ) {
4610 len = enclen(enc, p, end);
4611 if (i +
len > OPT_EXACT_MAXLEN)
break;
4612 for (j = 0; j <
len && p < end; j++)
4624 if (add->len == 0 || to->len == 0) {
4625 clear_opt_exact_info(to);
4629 if (! is_equal_mml(&to->mmd, &add->mmd)) {
4630 clear_opt_exact_info(to);
4634 for (i = 0; i < to->len && i < add->len; ) {
4635 if (to->s[i] != add->s[i])
break;
4636 len = enclen(env->enc, to->s + i, to->s + to->len);
4638 for (j = 1; j <
len; j++) {
4639 if (to->s[i+j] != add->s[i+j])
break;
4645 if (! add->reach_end || i < add->
len || i < to->
len) {
4649 if (to->ignore_case < 0)
4650 to->ignore_case = add->ignore_case;
4651 else if (add->ignore_case >= 0)
4652 to->ignore_case |= add->ignore_case;
4654 alt_merge_opt_anc_info(&to->anc, &add->anc);
4655 if (! to->reach_end) to->anc.right_anchor = 0;
4670 copy_opt_exact_info(now, alt);
4673 else if (v1 <= 2 && v2 <= 2) {
4675 v2 = map_position_value(enc, now->s[0]);
4676 v1 = map_position_value(enc, alt->s[0]);
4678 if (now->len > 1) v1 += 5;
4679 if (alt->len > 1) v2 += 5;
4682 if (now->ignore_case <= 0) v1 *= 2;
4683 if (alt->ignore_case <= 0) v2 *= 2;
4685 if (comp_distance_value(&now->mmd, &alt->mmd, v1, v2) > 0)
4686 copy_opt_exact_info(now, alt);
4695 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4696 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4697 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4698 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4699 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4700 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4701 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4702 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4703 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4704 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4705 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4706 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4707 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4708 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4709 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4710 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
4714 xmemcpy(map, &clean_info,
sizeof(
OptMapInfo));
4726 if (map->map[c] == 0) {
4728 map->value += map_position_value(enc, c);
4733add_char_amb_opt_map_info(
OptMapInfo* map, UChar* p, UChar* end,
4737 UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
4740 add_char_opt_map_info(map, p[0], enc);
4742 case_fold_flag = DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag);
4743 n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, case_fold_flag, p, end, items);
4744 if (n < 0)
return n;
4746 for (i = 0; i < n; i++) {
4747 ONIGENC_CODE_TO_MBC(enc, items[i].code[0], buf);
4748 add_char_opt_map_info(map, buf[0], enc);
4757 const int z = 1<<15;
4761 if (alt->value == 0) return ;
4762 if (now->value == 0) {
4763 copy_opt_map_info(now, alt);
4767 v1 = z / now->value;
4768 v2 = z / alt->value;
4769 if (comp_distance_value(&now->mmd, &alt->mmd, v1, v2) > 0)
4770 copy_opt_map_info(now, alt);
4776#define COMP_EM_BASE 20
4779 if (m->value <= 0)
return -1;
4781 ve = COMP_EM_BASE * e->len * (e->ignore_case > 0 ? 1 : 2);
4782 vm = COMP_EM_BASE * 5 * 2 / m->value;
4783 return comp_distance_value(&e->mmd, &m->mmd, ve, vm);
4792 if (to->value == 0) return ;
4793 if (add->value == 0 || to->mmd.max < add->mmd.min) {
4794 clear_opt_map_info(to);
4798 alt_merge_mml(&to->mmd, &add->mmd);
4801 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) {
4806 val += map_position_value(enc, i);
4810 alt_merge_opt_anc_info(&to->anc, &add->anc);
4816 copy_mml(&(opt->exb.mmd), mmd);
4817 copy_mml(&(opt->expr.mmd), mmd);
4818 copy_mml(&(opt->map.mmd), mmd);
4824 clear_mml(&opt->len);
4825 clear_opt_anc_info(&opt->anc);
4826 clear_opt_exact_info(&opt->exb);
4827 clear_opt_exact_info(&opt->exm);
4828 clear_opt_exact_info(&opt->expr);
4829 clear_opt_map_info(&opt->map);
4841 int exb_reach, exm_reach;
4844 concat_opt_anc_info(&tanc, &to->anc, &add->anc, to->len.max, add->len.max);
4845 copy_opt_anc_info(&to->anc, &tanc);
4847 if (add->exb.len > 0 && to->len.max == 0) {
4848 concat_opt_anc_info(&tanc, &to->anc, &add->exb.anc,
4849 to->len.max, add->len.max);
4850 copy_opt_anc_info(&add->exb.anc, &tanc);
4853 if (add->map.value > 0 && to->len.max == 0) {
4854 if (add->map.mmd.max == 0)
4855 add->map.anc.left_anchor |= to->anc.left_anchor;
4858 exb_reach = to->exb.reach_end;
4859 exm_reach = to->exm.reach_end;
4861 if (add->len.max != 0)
4862 to->exb.reach_end = to->exm.reach_end = 0;
4864 if (add->exb.len > 0) {
4866 concat_opt_exact_info(&to->exb, &add->exb, enc);
4867 clear_opt_exact_info(&add->exb);
4869 else if (exm_reach) {
4870 concat_opt_exact_info(&to->exm, &add->exb, enc);
4871 clear_opt_exact_info(&add->exb);
4874 select_opt_exact_info(enc, &to->exm, &add->exb);
4875 select_opt_exact_info(enc, &to->exm, &add->exm);
4877 if (to->expr.len > 0) {
4878 if (add->len.max > 0) {
4879 if (to->expr.len > (
int )add->len.max)
4880 to->expr.len = (int )add->len.max;
4882 if (to->expr.mmd.max == 0)
4883 select_opt_exact_info(enc, &to->exb, &to->expr);
4885 select_opt_exact_info(enc, &to->exm, &to->expr);
4888 else if (add->expr.len > 0) {
4889 copy_opt_exact_info(&to->expr, &add->expr);
4892 select_opt_map_info(&to->map, &add->map);
4894 add_mml(&to->len, &add->len);
4900 alt_merge_opt_anc_info (&to->anc, &add->anc);
4901 alt_merge_opt_exact_info(&to->exb, &add->exb, env);
4902 alt_merge_opt_exact_info(&to->exm, &add->exm, env);
4903 alt_merge_opt_exact_info(&to->expr, &add->expr, env);
4904 alt_merge_opt_map_info(env->enc, &to->map, &add->map);
4906 alt_merge_mml(&to->len, &add->len);
4910#define MAX_NODE_OPT_INFO_REF_COUNT 5
4918 clear_node_opt_info(opt);
4919 set_bound_node_opt_info(opt, &env->mmd);
4929 copy_opt_env(&nenv, env);
4931 r = optimize_node_left(NCAR(nd), &nopt, &nenv);
4933 add_mml(&nenv.mmd, &nopt.len);
4934 concat_left_node_opt_info(env->enc, opt, &nopt);
4936 }
while (r == 0 && IS_NOT_NULL(nd = NCDR(nd)));
4946 r = optimize_node_left(NCAR(nd), &nopt, env);
4948 if (nd == node) copy_node_opt_info(opt, &nopt);
4949 else alt_merge_node_opt_info(opt, &nopt, env);
4951 }
while ((r == 0) && IS_NOT_NULL(nd = NCDR(nd)));
4958 OnigDistance slen = sn->end - sn->s;
4959 int is_raw = NSTRING_IS_RAW(node);
4961 if (! NSTRING_IS_AMBIG(node)) {
4962 concat_opt_exact_info_str(&opt->exb, sn->s, sn->end,
4964 opt->exb.ignore_case = 0;
4966 add_char_opt_map_info(&opt->map, *(sn->s), env->enc);
4968 set_mml(&opt->len, slen, slen);
4973 if (NSTRING_IS_DONT_GET_OPT_INFO(node)) {
4974 int n = onigenc_strlen(env->enc, sn->s, sn->end);
4975 max = (OnigDistance )ONIGENC_MBC_MAXLEN_DIST(env->enc) * (OnigDistance)n;
4978 concat_opt_exact_info_str(&opt->exb, sn->s, sn->end,
4980 opt->exb.ignore_case = 1;
4983 r = add_char_amb_opt_map_info(&opt->map, sn->s, sn->end,
4984 env->enc, env->case_fold_flag);
4991 set_mml(&opt->len, slen, max);
4994 if ((OnigDistance )opt->exb.len == slen)
4995 opt->exb.reach_end = 1;
5006 if (IS_NOT_NULL(cc->mbuf) || IS_NCCLASS_NOT(cc)) {
5007 OnigDistance min = ONIGENC_MBC_MINLEN(env->enc);
5008 OnigDistance max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
5010 set_mml(&opt->len, min, max);
5013 for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
5014 z = BITSET_AT(cc->bs, i);
5015 if ((z && !IS_NCCLASS_NOT(cc)) || (!z && IS_NCCLASS_NOT(cc))) {
5016 add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
5019 set_mml(&opt->len, 1, 1);
5029 max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
5034 maxcode = NCTYPE(node)->ascii_range ? 0x80 : SINGLE_BYTE_SIZE;
5035 switch (NCTYPE(node)->ctype) {
5036 case ONIGENC_CTYPE_WORD:
5037 if (NCTYPE(node)->not != 0) {
5038 for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
5039 if (! ONIGENC_IS_CODE_WORD(env->enc, i) || i >= maxcode) {
5040 add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
5045 for (i = 0; i < maxcode; i++) {
5046 if (ONIGENC_IS_CODE_WORD(env->enc, i)) {
5047 add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
5055 min = ONIGENC_MBC_MINLEN(env->enc);
5057 set_mml(&opt->len, min, max);
5063 OnigDistance min = ONIGENC_MBC_MINLEN(env->enc);
5064 OnigDistance max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
5065 set_mml(&opt->len, min, max);
5070 switch (NANCHOR(node)->type) {
5071 case ANCHOR_BEGIN_BUF:
5072 case ANCHOR_BEGIN_POSITION:
5073 case ANCHOR_BEGIN_LINE:
5074 case ANCHOR_END_BUF:
5075 case ANCHOR_SEMI_END_BUF:
5076 case ANCHOR_END_LINE:
5077 case ANCHOR_LOOK_BEHIND:
5078 case ANCHOR_PREC_READ_NOT:
5079 add_opt_anc_info(&opt->anc, NANCHOR(node)->type);
5082 case ANCHOR_PREC_READ:
5086 r = optimize_node_left(NANCHOR(node)->target, &nopt, env);
5088 if (nopt.exb.len > 0)
5089 copy_opt_exact_info(&opt->expr, &nopt.exb);
5090 else if (nopt.exm.len > 0)
5091 copy_opt_exact_info(&opt->expr, &nopt.exm);
5093 opt->expr.reach_end = 0;
5095 if (nopt.map.value > 0)
5096 copy_opt_map_info(&opt->map, &nopt.map);
5101 case ANCHOR_LOOK_BEHIND_NOT:
5110 OnigDistance min, max, tmin, tmax;
5111 Node** nodes = SCANENV_MEM_NODES(env->scan_env);
5114 if (br->state & NST_RECURSION) {
5115 set_mml(&opt->len, 0, ONIG_INFINITE_DISTANCE);
5118 backs = BACKREFS_P(br);
5119 r = get_min_match_length(nodes[backs[0]], &min, env->scan_env);
5121 r = get_max_match_length(nodes[backs[0]], &max, env->scan_env);
5123 for (i = 1; i < br->back_num; i++) {
5124 r = get_min_match_length(nodes[backs[i]], &tmin, env->scan_env);
5126 r = get_max_match_length(nodes[backs[i]], &tmax, env->scan_env);
5128 if (min > tmin) min = tmin;
5129 if (max < tmax) max = tmax;
5131 if (r == 0) set_mml(&opt->len, min, max);
5135#ifdef USE_SUBEXP_CALL
5137 if (IS_CALL_RECURSION(NCALL(node)))
5138 set_mml(&opt->len, 0, ONIG_INFINITE_DISTANCE);
5140 OnigOptionType save = env->options;
5141 env->options = NENCLOSE(NCALL(node)->target)->option;
5142 r = optimize_node_left(NCALL(node)->target, opt, env);
5143 env->options = save;
5151 OnigDistance min, max;
5155 r = optimize_node_left(qn->target, &nopt, env);
5158 if (qn->lower == 0 && IS_REPEAT_INFINITE(qn->upper)) {
5159 if (env->mmd.max == 0 &&
5160 NTYPE(qn->target) == NT_CANY && qn->greedy) {
5161 if (IS_MULTILINE(env->options))
5163 add_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR_ML);
5165 add_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR);
5169 if (qn->lower > 0) {
5170 copy_node_opt_info(opt, &nopt);
5171 if (nopt.exb.len > 0) {
5172 if (nopt.exb.reach_end) {
5173 for (i = 2; i <= qn->lower &&
5174 ! is_full_opt_exact_info(&opt->exb); i++) {
5175 concat_opt_exact_info(&opt->exb, &nopt.exb, env->enc);
5177 if (i < qn->lower) {
5178 opt->exb.reach_end = 0;
5183 if (qn->lower != qn->upper) {
5184 opt->exb.reach_end = 0;
5185 opt->exm.reach_end = 0;
5188 opt->exm.reach_end = 0;
5192 min = distance_multiply(nopt.len.min, qn->lower);
5193 if (IS_REPEAT_INFINITE(qn->upper))
5194 max = (nopt.len.max > 0 ? ONIG_INFINITE_DISTANCE : 0);
5196 max = distance_multiply(nopt.len.max, qn->upper);
5198 set_mml(&opt->len, min, max);
5207 case ENCLOSE_OPTION:
5209 OnigOptionType save = env->options;
5211 env->options = en->option;
5212 r = optimize_node_left(en->target, opt, env);
5213 env->options = save;
5217 case ENCLOSE_MEMORY:
5218#ifdef USE_SUBEXP_CALL
5220 if (en->opt_count > MAX_NODE_OPT_INFO_REF_COUNT) {
5221 OnigDistance min, max;
5224 max = ONIG_INFINITE_DISTANCE;
5225 if (IS_ENCLOSE_MIN_FIXED(en)) min = en->min_len;
5226 if (IS_ENCLOSE_MAX_FIXED(en)) max = en->max_len;
5227 set_mml(&opt->len, min, max);
5232 r = optimize_node_left(en->target, opt, env);
5234 if (is_set_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR_MASK)) {
5235 if (BIT_STATUS_AT(env->scan_env->backrefed_mem, en->regnum))
5236 remove_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR_MASK);
5241 case ENCLOSE_STOP_BACKTRACK:
5242 case ENCLOSE_CONDITION:
5243 r = optimize_node_left(en->target, opt, env);
5246 case ENCLOSE_ABSENT:
5247 set_mml(&opt->len, 0, ONIG_INFINITE_DISTANCE);
5255 fprintf(stderr,
"optimize_node_left: undefined node type %d\n",
5258 r = ONIGERR_TYPE_BUG;
5270 if (e->len == 0)
return 0;
5272 reg->exact = (UChar* )
xmalloc(e->len);
5273 CHECK_NULL_RETURN_MEMERR(reg->exact);
5274 xmemcpy(reg->exact, e->s, e->len);
5275 reg->exact_end = reg->exact + e->len;
5278 ONIGENC_IS_ALLOWED_REVERSE_MATCH(reg->enc, reg->exact, reg->exact_end);
5280 if (e->ignore_case > 0) {
5281 if (e->len >= 3 || (e->len >= 2 && allow_reverse)) {
5282 int orig_len = e->len;
5283 e->len = set_bm_skip(reg->exact, reg->exact_end, reg,
5286 reg->exact_end = reg->exact + e->len;
5287 reg->optimize = (allow_reverse != 0
5288 ? ONIG_OPTIMIZE_EXACT_BM_IC : ONIG_OPTIMIZE_EXACT_BM_NOT_REV_IC);
5298 reg->optimize = ONIG_OPTIMIZE_EXACT_IC;
5302 reg->optimize = ONIG_OPTIMIZE_EXACT_IC;
5306 if (e->len >= 3 || (e->len >= 2 && allow_reverse)) {
5307 set_bm_skip(reg->exact, reg->exact_end, reg,
5309 reg->optimize = (allow_reverse != 0
5310 ? ONIG_OPTIMIZE_EXACT_BM : ONIG_OPTIMIZE_EXACT_BM_NOT_REV);
5313 reg->optimize = ONIG_OPTIMIZE_EXACT;
5317 reg->dmin = e->mmd.min;
5318 reg->dmax = e->mmd.max;
5320 if (reg->dmin != ONIG_INFINITE_DISTANCE) {
5321 reg->threshold_len = (int )(reg->dmin + (reg->exact_end - reg->exact));
5332 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
5333 reg->map[i] = m->map[i];
5335 reg->optimize = ONIG_OPTIMIZE_MAP;
5336 reg->dmin = m->mmd.min;
5337 reg->dmax = m->mmd.max;
5339 if (reg->dmin != ONIG_INFINITE_DISTANCE) {
5340 reg->threshold_len = (int )(reg->dmin + 1);
5347 reg->sub_anchor |= anc->left_anchor & ANCHOR_BEGIN_LINE;
5348 reg->sub_anchor |= anc->right_anchor & ANCHOR_END_LINE;
5351#if defined(ONIG_DEBUG_COMPILE) || defined(ONIG_DEBUG_MATCH)
5352static void print_optimize_info(
FILE* f,
regex_t* reg);
5364 env.options = reg->options;
5365 env.case_fold_flag = reg->case_fold_flag;
5366 env.scan_env = scan_env;
5367 clear_mml(&env.mmd);
5369 r = optimize_node_left(node, &opt, &env);
5372 reg->anchor = opt.anc.left_anchor & (ANCHOR_BEGIN_BUF |
5373 ANCHOR_BEGIN_POSITION | ANCHOR_ANYCHAR_STAR | ANCHOR_ANYCHAR_STAR_ML |
5374 ANCHOR_LOOK_BEHIND);
5376 if ((opt.anc.left_anchor & (ANCHOR_LOOK_BEHIND | ANCHOR_PREC_READ_NOT)) != 0)
5377 reg->anchor &= ~ANCHOR_ANYCHAR_STAR_ML;
5379 reg->anchor |= opt.anc.right_anchor & (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF |
5380 ANCHOR_PREC_READ_NOT);
5382 if (reg->anchor & (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF)) {
5383 reg->anchor_dmin = opt.len.min;
5384 reg->anchor_dmax = opt.len.max;
5387 if (opt.exb.len > 0 || opt.exm.len > 0) {
5388 select_opt_exact_info(reg->enc, &opt.exb, &opt.exm);
5389 if (opt.map.value > 0 &&
5390 comp_opt_exact_or_map_info(&opt.exb, &opt.map) > 0) {
5394 r = set_optimize_exact_info(reg, &opt.exb);
5395 set_sub_anchor(reg, &opt.exb.anc);
5398 else if (opt.map.value > 0) {
5400 set_optimize_map_info(reg, &opt.map);
5401 set_sub_anchor(reg, &opt.map.anc);
5404 reg->sub_anchor |= opt.anc.left_anchor & ANCHOR_BEGIN_LINE;
5405 if (opt.len.max == 0)
5406 reg->sub_anchor |= opt.anc.right_anchor & ANCHOR_END_LINE;
5409#if defined(ONIG_DEBUG_COMPILE) || defined(ONIG_DEBUG_MATCH)
5410 print_optimize_info(stderr, reg);
5416clear_optimize_info(
regex_t* reg)
5418 reg->optimize = ONIG_OPTIMIZE_NONE;
5420 reg->anchor_dmin = 0;
5421 reg->anchor_dmax = 0;
5422 reg->sub_anchor = 0;
5423 reg->exact_end = (UChar* )NULL;
5424 reg->threshold_len = 0;
5426 reg->exact = (UChar* )NULL;
5432 const UChar *s,
const UChar *end)
5434 fprintf(fp,
"\nPATTERN: /");
5436 if (ONIGENC_MBC_MINLEN(enc) > 1) {
5442 code = ONIGENC_MBC_TO_CODE(enc, p, end);
5444 fprintf(fp,
" 0x%04x ", (
int )code);
5447 fputc((
int )code, fp);
5450 p += enclen(enc, p, end);
5455 fputc((
int )*s, fp);
5460 fprintf(fp,
"/ (%s)\n", enc->name);
5464#if defined(ONIG_DEBUG_COMPILE) || defined(ONIG_DEBUG_MATCH)
5466print_distance_range(
FILE* f, OnigDistance a, OnigDistance b)
5468 if (a == ONIG_INFINITE_DISTANCE)
5471 fprintf(f,
"(%"PRIuPTR
")", a);
5475 if (b == ONIG_INFINITE_DISTANCE)
5478 fprintf(f,
"(%"PRIuPTR
")", b);
5482print_anchor(
FILE* f,
int anchor)
5488 if (anchor & ANCHOR_BEGIN_BUF) {
5489 fprintf(f,
"begin-buf");
5492 if (anchor & ANCHOR_BEGIN_LINE) {
5493 if (q) fprintf(f,
", ");
5495 fprintf(f,
"begin-line");
5497 if (anchor & ANCHOR_BEGIN_POSITION) {
5498 if (q) fprintf(f,
", ");
5500 fprintf(f,
"begin-pos");
5502 if (anchor & ANCHOR_END_BUF) {
5503 if (q) fprintf(f,
", ");
5505 fprintf(f,
"end-buf");
5507 if (anchor & ANCHOR_SEMI_END_BUF) {
5508 if (q) fprintf(f,
", ");
5510 fprintf(f,
"semi-end-buf");
5512 if (anchor & ANCHOR_END_LINE) {
5513 if (q) fprintf(f,
", ");
5515 fprintf(f,
"end-line");
5517 if (anchor & ANCHOR_ANYCHAR_STAR) {
5518 if (q) fprintf(f,
", ");
5520 fprintf(f,
"anychar-star");
5522 if (anchor & ANCHOR_ANYCHAR_STAR_ML) {
5523 if (q) fprintf(f,
", ");
5524 fprintf(f,
"anychar-star-ml");
5533 static const char* on[] = {
"NONE",
"EXACT",
"EXACT_BM",
"EXACT_BM_NOT_REV",
5535 "EXACT_BM_IC",
"EXACT_BM_NOT_REV_IC" };
5537 fprintf(f,
"optimize: %s\n", on[reg->optimize]);
5538 fprintf(f,
" anchor: "); print_anchor(f, reg->anchor);
5539 if ((reg->anchor & ANCHOR_END_BUF_MASK) != 0)
5540 print_distance_range(f, reg->anchor_dmin, reg->anchor_dmax);
5543 if (reg->optimize) {
5544 fprintf(f,
" sub anchor: "); print_anchor(f, reg->sub_anchor);
5551 fprintf(f,
"exact: [");
5552 for (p = reg->exact; p < reg->exact_end; p++) {
5555 fprintf(f,
"]: length: %"PRIdPTR
"\n", (reg->exact_end - reg->exact));
5557 else if (reg->optimize & ONIG_OPTIMIZE_MAP) {
5560 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
5561 if (reg->map[i]) n++;
5563 fprintf(f,
"map: n=%d\n", n);
5567 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) {
5568 if (reg->map[i] != 0) {
5569 if (c > 0) fputs(
", ", f);
5571 if (ONIGENC_MBC_MAXLEN(reg->enc) == 1 &&
5572 ONIGENC_IS_CODE_PRINT(reg->enc, (OnigCodePoint )i))
5575 fprintf(f,
"%d", i);
5588 if (IS_NOT_NULL(reg)) {
5591 xfree(reg->repeat_range);
5592 onig_free(reg->chain);
5594#ifdef USE_NAMED_GROUP
5595 onig_names_free(reg);
5603 if (IS_NOT_NULL(reg)) {
5604 onig_free_body(reg);
5610dup_copy(
const void *ptr,
size_t size)
5613 if (IS_NOT_NULL(newptr)) {
5614 memcpy(newptr, ptr, size);
5622 if (IS_NOT_NULL(oreg)) {
5625# define COPY_FAILED(mem, size) IS_NULL(nreg->mem = dup_copy(oreg->mem, size))
5627 if (IS_NOT_NULL(oreg->exact)) {
5628 size_t exact_size = oreg->exact_end - oreg->exact;
5629 if (COPY_FAILED(exact, exact_size))
5631 (nreg)->exact_end = (nreg)->exact + exact_size;
5634 if (IS_NOT_NULL(oreg->p)) {
5635 if (COPY_FAILED(p, oreg->alloc))
5638 if (IS_NOT_NULL(oreg->repeat_range)) {
5639 if (COPY_FAILED(repeat_range, oreg->repeat_range_alloc *
sizeof(
OnigRepeatRange)))
5640 goto err_repeat_range;
5642 if (IS_NOT_NULL(oreg->name_table)) {
5643 if (onig_names_copy(nreg, oreg))
5644 goto err_name_table;
5646 if (IS_NOT_NULL(oreg->chain)) {
5647 if (onig_reg_copy(&nreg->chain, oreg->chain))
5654 onig_names_free(nreg);
5656 xfree(nreg->repeat_range);
5663 return ONIGERR_MEMORY;
5671 if (IS_NOT_NULL(oreg)) {
5673 if (IS_NULL(reg))
return ONIGERR_MEMORY;
5675 return onig_reg_copy_body(reg, oreg);
5682onig_memsize(
const regex_t *reg)
5684 size_t size =
sizeof(
regex_t);
5685 if (IS_NULL(reg))
return 0;
5686 if (IS_NOT_NULL(reg->p)) size += reg->alloc;
5687 if (IS_NOT_NULL(reg->exact)) size += reg->exact_end - reg->exact;
5688 if (IS_NOT_NULL(reg->repeat_range)) size += reg->repeat_range_alloc *
sizeof(
OnigRepeatRange);
5689 if (IS_NOT_NULL(reg->chain)) size += onig_memsize(reg->chain);
5697 size_t size =
sizeof(*regs);
5698 if (IS_NULL(regs))
return 0;
5699 size += regs->allocated * (
sizeof(*regs->beg) +
sizeof(*regs->end));
5704#define REGEX_TRANSFER(to,from) do {\
5705 onig_free_body(to);\
5706 xmemcpy(to, from, sizeof(regex_t));\
5714 REGEX_TRANSFER(to, from);
5718#ifdef ONIG_DEBUG_COMPILE
5719static void print_compiled_byte_code_list(
FILE* f,
regex_t* reg);
5721#ifdef ONIG_DEBUG_PARSE_TREE
5722static void print_tree(
FILE* f,
Node* node);
5727onig_compile(
regex_t* reg,
const UChar* pattern,
const UChar* pattern_end,
5730 return onig_compile_ruby(reg, pattern, pattern_end, einfo, NULL, 0);
5736onig_compile_ruby(
regex_t* reg,
const UChar* pattern,
const UChar* pattern_end,
5737 OnigErrorInfo* einfo,
const char *sourcefile,
int sourceline)
5740onig_compile(
regex_t* reg,
const UChar* pattern,
const UChar* pattern_end,
5744#define COMPILE_INIT_SIZE 20
5747 OnigDistance init_size;
5750#ifdef USE_SUBEXP_CALL
5754 if (IS_NOT_NULL(einfo)) einfo->par = (UChar* )NULL;
5757 scan_env.sourcefile = sourcefile;
5758 scan_env.sourceline = sourceline;
5762 print_enc_string(stderr, reg->enc, pattern, pattern_end);
5765 if (reg->alloc == 0) {
5766 init_size = (pattern_end - pattern) * 2;
5767 if (init_size <= 0) init_size = COMPILE_INIT_SIZE;
5768 r = BBUF_INIT(reg, init_size);
5769 if (r != 0)
goto end;
5775 reg->num_repeat = 0;
5776 reg->num_null_check = 0;
5777 reg->repeat_range_alloc = 0;
5779#ifdef USE_COMBINATION_EXPLOSION_CHECK
5780 reg->num_comb_exp_check = 0;
5783 r = onig_parse_make_tree(&root, pattern, pattern_end, reg, &scan_env);
5784 if (r != 0)
goto err;
5786#ifdef ONIG_DEBUG_PARSE_TREE
5788 fprintf(stderr,
"ORIGINAL PARSE TREE:\n");
5789 print_tree(stderr, root);
5793#ifdef USE_NAMED_GROUP
5795 if (scan_env.num_named > 0 &&
5796 IS_SYNTAX_BV(scan_env.syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
5797 !ONIG_IS_OPTION_ON(reg->options, ONIG_OPTION_CAPTURE_GROUP)) {
5798 if (scan_env.num_named != scan_env.num_mem)
5799 r = disable_noname_group_capture(&root, reg, &scan_env);
5801 r = numbered_ref_check(root);
5803 if (r != 0)
goto err;
5807#ifdef USE_SUBEXP_CALL
5808 if (scan_env.num_call > 0) {
5809 r = unset_addr_list_init(&uslist, scan_env.num_call);
5810 if (r != 0)
goto err;
5811 scan_env.unset_addr_list = &uslist;
5812 r = setup_subexp_call(root, &scan_env);
5813 if (r != 0)
goto err_unset;
5814 r = subexp_recursive_check_trav(root, &scan_env);
5815 if (r < 0)
goto err_unset;
5816 r = subexp_inf_recursive_check_trav(root, &scan_env);
5817 if (r != 0)
goto err_unset;
5819 reg->num_call = scan_env.num_call;
5825 r = setup_tree(root, reg, 0, &scan_env);
5826 if (r != 0)
goto err_unset;
5828#ifdef ONIG_DEBUG_PARSE_TREE
5829 print_tree(stderr, root);
5832 reg->capture_history = scan_env.capture_history;
5833 reg->bt_mem_start = scan_env.bt_mem_start;
5834 reg->bt_mem_start |= reg->capture_history;
5835 if (IS_FIND_CONDITION(reg->options))
5836 BIT_STATUS_ON_ALL(reg->bt_mem_end);
5838 reg->bt_mem_end = scan_env.bt_mem_end;
5839 reg->bt_mem_end |= reg->capture_history;
5842#ifdef USE_COMBINATION_EXPLOSION_CHECK
5843 if (scan_env.backrefed_mem == 0
5844# ifdef USE_SUBEXP_CALL
5845 || scan_env.num_call == 0
5848 setup_comb_exp_check(root, 0, &scan_env);
5849# ifdef USE_SUBEXP_CALL
5850 if (scan_env.has_recursion != 0) {
5851 scan_env.num_comb_exp_check = 0;
5855 if (scan_env.comb_exp_max_regnum > 0) {
5857 for (i = 1; i <= scan_env.comb_exp_max_regnum; i++) {
5858 if (BIT_STATUS_AT(scan_env.backrefed_mem, i) != 0) {
5859 scan_env.num_comb_exp_check = 0;
5866 reg->num_comb_exp_check = scan_env.num_comb_exp_check;
5869 clear_optimize_info(reg);
5870#ifndef ONIG_DONT_OPTIMIZE
5871 r = set_optimize_info_from_tree(root, reg, &scan_env);
5872 if (r != 0)
goto err_unset;
5875 if (IS_NOT_NULL(scan_env.mem_nodes_dynamic)) {
5876 xfree(scan_env.mem_nodes_dynamic);
5877 scan_env.mem_nodes_dynamic = (
Node** )NULL;
5880 r = compile_tree(root, reg);
5882 r = add_opcode(reg, OP_END);
5883 if (r != 0)
goto err_unset;
5884#ifdef USE_SUBEXP_CALL
5885 if (scan_env.num_call > 0) {
5886 r = unset_addr_list_fix(&uslist, reg);
5887 unset_addr_list_end(&uslist);
5892 if ((reg->num_repeat != 0) || (reg->bt_mem_end != 0))
5893 reg->stack_pop_level = STACK_POP_LEVEL_ALL;
5895 if (reg->bt_mem_start != 0)
5896 reg->stack_pop_level = STACK_POP_LEVEL_MEM_START;
5898 reg->stack_pop_level = STACK_POP_LEVEL_FREE;
5901#ifdef USE_SUBEXP_CALL
5902 else if (scan_env.num_call > 0) {
5903 unset_addr_list_end(&uslist);
5906 onig_node_free(root);
5908#ifdef ONIG_DEBUG_COMPILE
5909# ifdef USE_NAMED_GROUP
5910 onig_print_names(stderr, reg);
5912 print_compiled_byte_code_list(stderr, reg);
5916 onig_reg_resize(reg);
5920#ifdef USE_SUBEXP_CALL
5921 if (scan_env.num_call > 0) {
5922 unset_addr_list_end(&uslist);
5926 if (IS_NOT_NULL(scan_env.error)) {
5927 if (IS_NOT_NULL(einfo)) {
5928 einfo->enc = scan_env.enc;
5929 einfo->par = scan_env.error;
5930 einfo->par_end = scan_env.error_end;
5934 onig_node_free(root);
5935 xfree(scan_env.mem_nodes_dynamic);
5940static int onig_inited = 0;
5943onig_reg_init(
regex_t* reg, OnigOptionType option,
5944 OnigCaseFoldType case_fold_flag,
5951 return ONIGERR_INVALID_ARGUMENT;
5953 (reg)->exact = (UChar* )NULL;
5954 (reg)->chain = (
regex_t* )NULL;
5955 (reg)->p = (UChar* )NULL;
5956 (reg)->name_table = (
void* )NULL;
5959 if (ONIGENC_IS_UNDEF(enc))
5960 return ONIGERR_DEFAULT_ENCODING_IS_NOT_SET;
5962 if ((option & (ONIG_OPTION_DONT_CAPTURE_GROUP|ONIG_OPTION_CAPTURE_GROUP))
5963 == (ONIG_OPTION_DONT_CAPTURE_GROUP|ONIG_OPTION_CAPTURE_GROUP)) {
5964 return ONIGERR_INVALID_COMBINATION_OF_OPTIONS;
5967 if ((option & ONIG_OPTION_NEGATE_SINGLELINE) != 0) {
5968 option |= syntax->options;
5969 option &= ~ONIG_OPTION_SINGLELINE;
5972 option |= syntax->options;
5975 (reg)->options = option;
5976 (reg)->syntax = syntax;
5977 (reg)->optimize = 0;
5982 (reg)->case_fold_flag = case_fold_flag;
5984 (reg)->timelimit = 0;
5990onig_new_without_alloc(
regex_t* reg,
const UChar* pattern,
5991 const UChar* pattern_end, OnigOptionType option,
OnigEncoding enc,
5996 r = onig_reg_init(reg, option, ONIGENC_CASE_FOLD_DEFAULT, enc, syntax);
5999 r = onig_compile(reg, pattern, pattern_end, einfo);
6004onig_new(
regex_t** reg,
const UChar* pattern,
const UChar* pattern_end,
6009 if (IS_NULL(*reg))
return ONIGERR_MEMORY;
6011 int r = onig_new_without_alloc(*reg, pattern, pattern_end, option, enc, syntax, einfo);
6021onig_initialize(
OnigEncoding encodings[] ARG_UNUSED,
int n ARG_UNUSED)
6029 if (onig_inited != 0)
6034#if defined(ONIG_DEBUG_MEMLEAK) && defined(_MSC_VER)
6035 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
6041#ifdef ONIG_DEBUG_STATISTICS
6042 onig_statistics_init();
6051extern void onig_add_end_call(
void (*func)(
void))
6056 if (item == 0) return ;
6058 item->next = EndCallTop;
6065exec_end_call_list(
void)
6070 while (EndCallTop != 0) {
6071 func = EndCallTop->func;
6075 EndCallTop = EndCallTop->next;
6083 exec_end_call_list();
6085#ifdef ONIG_DEBUG_STATISTICS
6086 onig_print_statistics(stderr);
6089#if defined(ONIG_DEBUG_MEMLEAK) && defined(_MSC_VER)
6090 _CrtDumpMemoryLeaks();
6099onig_is_in_code_range(
const UChar* p, OnigCodePoint code)
6101 OnigCodePoint n, *data;
6102 OnigCodePoint low, high, x;
6104 GET_CODE_POINT(n, p);
6105 data = (OnigCodePoint* )p;
6108 for (low = 0, high = n; low < high; ) {
6109 x = (low + high) >> 1;
6110 if (code > data[x * 2 + 1])
6116 return ((low < n && code >= data[low * 2]) ? 1 : 0);
6120onig_is_code_in_cc_len(
int elen, OnigCodePoint code,
CClassNode* cc)
6124 if (elen > 1 || (code >= SINGLE_BYTE_SIZE)) {
6125 if (IS_NULL(cc->mbuf)) {
6129 found = (onig_is_in_code_range(cc->mbuf->p, code) != 0 ? 1 : 0);
6133 found = (BITSET_AT(cc->bs, code) == 0 ? 0 : 1);
6136 if (IS_NCCLASS_NOT(cc))
6147 if (ONIGENC_MBC_MINLEN(enc) > 1) {
6151 len = ONIGENC_CODE_TO_MBCLEN(enc, code);
6153 return onig_is_code_in_cc_len(
len, code, cc);
6160# define ARG_SPECIAL -1
6162# define ARG_RELADDR 1
6163# define ARG_ABSADDR 2
6164# define ARG_LENGTH 3
6165# define ARG_MEMNUM 4
6166# define ARG_OPTION 5
6167# define ARG_STATE_CHECK 6
6169OnigOpInfoType OnigOpInfo[] = {
6170 { OP_FINISH,
"finish", ARG_NON },
6171 { OP_END,
"end", ARG_NON },
6172 { OP_EXACT1,
"exact1", ARG_SPECIAL },
6173 { OP_EXACT2,
"exact2", ARG_SPECIAL },
6174 { OP_EXACT3,
"exact3", ARG_SPECIAL },
6175 { OP_EXACT4,
"exact4", ARG_SPECIAL },
6176 { OP_EXACT5,
"exact5", ARG_SPECIAL },
6177 { OP_EXACTN,
"exactn", ARG_SPECIAL },
6178 { OP_EXACTMB2N1,
"exactmb2-n1", ARG_SPECIAL },
6179 { OP_EXACTMB2N2,
"exactmb2-n2", ARG_SPECIAL },
6180 { OP_EXACTMB2N3,
"exactmb2-n3", ARG_SPECIAL },
6181 { OP_EXACTMB2N,
"exactmb2-n", ARG_SPECIAL },
6182 { OP_EXACTMB3N,
"exactmb3n" , ARG_SPECIAL },
6183 { OP_EXACTMBN,
"exactmbn", ARG_SPECIAL },
6184 { OP_EXACT1_IC,
"exact1-ic", ARG_SPECIAL },
6185 { OP_EXACTN_IC,
"exactn-ic", ARG_SPECIAL },
6186 { OP_CCLASS,
"cclass", ARG_SPECIAL },
6187 { OP_CCLASS_MB,
"cclass-mb", ARG_SPECIAL },
6188 { OP_CCLASS_MIX,
"cclass-mix", ARG_SPECIAL },
6189 { OP_CCLASS_NOT,
"cclass-not", ARG_SPECIAL },
6190 { OP_CCLASS_MB_NOT,
"cclass-mb-not", ARG_SPECIAL },
6191 { OP_CCLASS_MIX_NOT,
"cclass-mix-not", ARG_SPECIAL },
6192 { OP_ANYCHAR,
"anychar", ARG_NON },
6193 { OP_ANYCHAR_ML,
"anychar-ml", ARG_NON },
6194 { OP_ANYCHAR_STAR,
"anychar*", ARG_NON },
6195 { OP_ANYCHAR_ML_STAR,
"anychar-ml*", ARG_NON },
6196 { OP_ANYCHAR_STAR_PEEK_NEXT,
"anychar*-peek-next", ARG_SPECIAL },
6197 { OP_ANYCHAR_ML_STAR_PEEK_NEXT,
"anychar-ml*-peek-next", ARG_SPECIAL },
6198 { OP_WORD,
"word", ARG_NON },
6199 { OP_NOT_WORD,
"not-word", ARG_NON },
6200 { OP_WORD_BOUND,
"word-bound", ARG_NON },
6201 { OP_NOT_WORD_BOUND,
"not-word-bound", ARG_NON },
6202 { OP_WORD_BEGIN,
"word-begin", ARG_NON },
6203 { OP_WORD_END,
"word-end", ARG_NON },
6204 { OP_ASCII_WORD,
"ascii-word", ARG_NON },
6205 { OP_NOT_ASCII_WORD,
"not-ascii-word", ARG_NON },
6206 { OP_ASCII_WORD_BOUND,
"ascii-word-bound", ARG_NON },
6207 { OP_NOT_ASCII_WORD_BOUND,
"not-ascii-word-bound", ARG_NON },
6208 { OP_ASCII_WORD_BEGIN,
"ascii-word-begin", ARG_NON },
6209 { OP_ASCII_WORD_END,
"ascii-word-end", ARG_NON },
6210 { OP_BEGIN_BUF,
"begin-buf", ARG_NON },
6211 { OP_END_BUF,
"end-buf", ARG_NON },
6212 { OP_BEGIN_LINE,
"begin-line", ARG_NON },
6213 { OP_END_LINE,
"end-line", ARG_NON },
6214 { OP_SEMI_END_BUF,
"semi-end-buf", ARG_NON },
6215 { OP_BEGIN_POSITION,
"begin-position", ARG_NON },
6216 { OP_BACKREF1,
"backref1", ARG_NON },
6217 { OP_BACKREF2,
"backref2", ARG_NON },
6218 { OP_BACKREFN,
"backrefn", ARG_MEMNUM },
6219 { OP_BACKREFN_IC,
"backrefn-ic", ARG_SPECIAL },
6220 { OP_BACKREF_MULTI,
"backref_multi", ARG_SPECIAL },
6221 { OP_BACKREF_MULTI_IC,
"backref_multi-ic", ARG_SPECIAL },
6222 { OP_BACKREF_WITH_LEVEL,
"backref_at_level", ARG_SPECIAL },
6223 { OP_MEMORY_START_PUSH,
"mem-start-push", ARG_MEMNUM },
6224 { OP_MEMORY_START,
"mem-start", ARG_MEMNUM },
6225 { OP_MEMORY_END_PUSH,
"mem-end-push", ARG_MEMNUM },
6226 { OP_MEMORY_END_PUSH_REC,
"mem-end-push-rec", ARG_MEMNUM },
6227 { OP_MEMORY_END,
"mem-end", ARG_MEMNUM },
6228 { OP_MEMORY_END_REC,
"mem-end-rec", ARG_MEMNUM },
6229 { OP_SET_OPTION_PUSH,
"set-option-push", ARG_OPTION },
6230 { OP_SET_OPTION,
"set-option", ARG_OPTION },
6231 { OP_KEEP,
"keep", ARG_NON },
6232 { OP_FAIL,
"fail", ARG_NON },
6233 { OP_JUMP,
"jump", ARG_RELADDR },
6234 { OP_PUSH,
"push", ARG_RELADDR },
6235 { OP_POP,
"pop", ARG_NON },
6236 { OP_PUSH_OR_JUMP_EXACT1,
"push-or-jump-e1", ARG_SPECIAL },
6237 { OP_PUSH_IF_PEEK_NEXT,
"push-if-peek-next", ARG_SPECIAL },
6238 { OP_REPEAT,
"repeat", ARG_SPECIAL },
6239 { OP_REPEAT_NG,
"repeat-ng", ARG_SPECIAL },
6240 { OP_REPEAT_INC,
"repeat-inc", ARG_MEMNUM },
6241 { OP_REPEAT_INC_NG,
"repeat-inc-ng", ARG_MEMNUM },
6242 { OP_REPEAT_INC_SG,
"repeat-inc-sg", ARG_MEMNUM },
6243 { OP_REPEAT_INC_NG_SG,
"repeat-inc-ng-sg", ARG_MEMNUM },
6244 { OP_NULL_CHECK_START,
"null-check-start", ARG_MEMNUM },
6245 { OP_NULL_CHECK_END,
"null-check-end", ARG_MEMNUM },
6246 { OP_NULL_CHECK_END_MEMST,
"null-check-end-memst", ARG_MEMNUM },
6247 { OP_NULL_CHECK_END_MEMST_PUSH,
"null-check-end-memst-push", ARG_MEMNUM },
6248 { OP_PUSH_POS,
"push-pos", ARG_NON },
6249 { OP_POP_POS,
"pop-pos", ARG_NON },
6250 { OP_PUSH_POS_NOT,
"push-pos-not", ARG_RELADDR },
6251 { OP_FAIL_POS,
"fail-pos", ARG_NON },
6252 { OP_PUSH_STOP_BT,
"push-stop-bt", ARG_NON },
6253 { OP_POP_STOP_BT,
"pop-stop-bt", ARG_NON },
6254 { OP_LOOK_BEHIND,
"look-behind", ARG_SPECIAL },
6255 { OP_PUSH_LOOK_BEHIND_NOT,
"push-look-behind-not", ARG_SPECIAL },
6256 { OP_FAIL_LOOK_BEHIND_NOT,
"fail-look-behind-not", ARG_NON },
6257 { OP_PUSH_ABSENT_POS,
"push-absent-pos", ARG_NON },
6258 { OP_ABSENT,
"absent", ARG_RELADDR },
6259 { OP_ABSENT_END,
"absent-end", ARG_NON },
6260 { OP_CALL,
"call", ARG_ABSADDR },
6261 { OP_RETURN,
"return", ARG_NON },
6262 { OP_CONDITION,
"condition", ARG_SPECIAL },
6263 { OP_STATE_CHECK_PUSH,
"state-check-push", ARG_SPECIAL },
6264 { OP_STATE_CHECK_PUSH_OR_JUMP,
"state-check-push-or-jump", ARG_SPECIAL },
6265 { OP_STATE_CHECK,
"state-check", ARG_STATE_CHECK },
6266 { OP_STATE_CHECK_ANYCHAR_STAR,
"state-check-anychar*", ARG_STATE_CHECK },
6267 { OP_STATE_CHECK_ANYCHAR_ML_STAR,
6268 "state-check-anychar-ml*", ARG_STATE_CHECK },
6277 for (i = 0; OnigOpInfo[i].opcode >= 0; i++) {
6278 if (opcode == OnigOpInfo[i].opcode)
6279 return OnigOpInfo[i].name;
6285op2arg_type(
int opcode)
6289 for (i = 0; OnigOpInfo[i].opcode >= 0; i++) {
6290 if (opcode == OnigOpInfo[i].opcode)
6291 return OnigOpInfo[i].arg_type;
6296# ifdef ONIG_DEBUG_PARSE_TREE
6298Indent(
FILE* f,
int indent)
6301 for (i = 0; i < indent; i++) putc(
' ', f);
6306p_string(
FILE* f, ptrdiff_t
len, UChar* s)
6309 while (
len-- > 0) { fputc(*s++, f); }
6313p_len_string(
FILE* f, LengthType
len,
int mb_len, UChar* s)
6315 int x =
len * mb_len;
6317 fprintf(f,
":%d:",
len);
6318 while (x-- > 0) { fputc(*s++, f); }
6322onig_print_compiled_byte_code(
FILE* f, UChar* bp, UChar* bpend, UChar** nextp,
6329 StateCheckNumType scn;
6333 fprintf(f,
"[%s", op2name(*bp));
6334 arg_type = op2arg_type(*bp);
6335 if (arg_type != ARG_SPECIAL) {
6341 GET_RELADDR_INC(addr, bp);
6342 fprintf(f,
":(%s%d)", (addr >= 0) ?
"+" :
"", addr);
6345 GET_ABSADDR_INC(addr, bp);
6346 fprintf(f,
":(%d)", addr);
6349 GET_LENGTH_INC(
len, bp);
6350 fprintf(f,
":%d",
len);
6353 mem = *((MemNumType* )bp);
6355 fprintf(f,
":%d", mem);
6359 OnigOptionType option = *((OnigOptionType* )bp);
6361 fprintf(f,
":%d", option);
6365 case ARG_STATE_CHECK:
6366 scn = *((StateCheckNumType* )bp);
6367 bp += SIZE_STATE_CHECK_NUM;
6368 fprintf(f,
":%d", scn);
6375 case OP_ANYCHAR_STAR_PEEK_NEXT:
6376 case OP_ANYCHAR_ML_STAR_PEEK_NEXT:
6377 p_string(f, 1, bp++);
break;
6379 p_string(f, 2, bp); bp += 2;
break;
6381 p_string(f, 3, bp); bp += 3;
break;
6383 p_string(f, 4, bp); bp += 4;
break;
6385 p_string(f, 5, bp); bp += 5;
break;
6387 GET_LENGTH_INC(
len, bp);
6388 p_len_string(f,
len, 1, bp);
6393 p_string(f, 2, bp); bp += 2;
break;
6395 p_string(f, 4, bp); bp += 4;
break;
6397 p_string(f, 6, bp); bp += 6;
break;
6399 GET_LENGTH_INC(
len, bp);
6400 p_len_string(f,
len, 2, bp);
6404 GET_LENGTH_INC(
len, bp);
6405 p_len_string(f,
len, 3, bp);
6412 GET_LENGTH_INC(mb_len, bp);
6413 GET_LENGTH_INC(
len, bp);
6414 fprintf(f,
":%d:%d:", mb_len,
len);
6416 while (n-- > 0) { fputc(*bp++, f); }
6421 len = enclen(enc, bp, bpend);
6422 p_string(f,
len, bp);
6426 GET_LENGTH_INC(
len, bp);
6427 p_len_string(f,
len, 1, bp);
6432 n = bitset_on_num((BitSetRef )bp);
6434 fprintf(f,
":%d", n);
6438 n = bitset_on_num((BitSetRef )bp);
6440 fprintf(f,
":%d", n);
6444 case OP_CCLASS_MB_NOT:
6445 GET_LENGTH_INC(
len, bp);
6447# ifndef PLATFORM_UNALIGNED_WORD_ACCESS
6450 GET_CODE_POINT(code, q);
6452 fprintf(f,
":%d:%d", (
int )code,
len);
6456 case OP_CCLASS_MIX_NOT:
6457 n = bitset_on_num((BitSetRef )bp);
6459 GET_LENGTH_INC(
len, bp);
6461# ifndef PLATFORM_UNALIGNED_WORD_ACCESS
6464 GET_CODE_POINT(code, q);
6466 fprintf(f,
":%d:%d:%d", n, (
int )code,
len);
6469 case OP_BACKREFN_IC:
6470 mem = *((MemNumType* )bp);
6472 fprintf(f,
":%d", mem);
6475 case OP_BACKREF_MULTI_IC:
6476 case OP_BACKREF_MULTI:
6478 GET_LENGTH_INC(
len, bp);
6479 for (i = 0; i <
len; i++) {
6480 GET_MEMNUM_INC(mem, bp);
6481 if (i > 0) fputs(
", ", f);
6482 fprintf(f,
"%d", mem);
6486 case OP_BACKREF_WITH_LEVEL:
6488 OnigOptionType option;
6491 GET_OPTION_INC(option, bp);
6492 fprintf(f,
":%d", option);
6493 GET_LENGTH_INC(level, bp);
6494 fprintf(f,
":%d", level);
6497 GET_LENGTH_INC(
len, bp);
6498 for (i = 0; i <
len; i++) {
6499 GET_MEMNUM_INC(mem, bp);
6500 if (i > 0) fputs(
", ", f);
6501 fprintf(f,
"%d", mem);
6509 mem = *((MemNumType* )bp);
6511 addr = *((RelAddrType* )bp);
6513 fprintf(f,
":%d:%d", mem, addr);
6517 case OP_PUSH_OR_JUMP_EXACT1:
6518 case OP_PUSH_IF_PEEK_NEXT:
6519 addr = *((RelAddrType* )bp);
6521 fprintf(f,
":(%s%d)", (addr >= 0) ?
"+" :
"", addr);
6526 case OP_LOOK_BEHIND:
6527 GET_LENGTH_INC(
len, bp);
6528 fprintf(f,
":%d",
len);
6531 case OP_PUSH_LOOK_BEHIND_NOT:
6532 GET_RELADDR_INC(addr, bp);
6533 GET_LENGTH_INC(
len, bp);
6534 fprintf(f,
":%d:(%s%d)",
len, (addr >= 0) ?
"+" :
"", addr);
6537 case OP_STATE_CHECK_PUSH:
6538 case OP_STATE_CHECK_PUSH_OR_JUMP:
6539 scn = *((StateCheckNumType* )bp);
6540 bp += SIZE_STATE_CHECK_NUM;
6541 addr = *((RelAddrType* )bp);
6543 fprintf(f,
":%d:(%s%d)", scn, (addr >= 0) ?
"+" :
"", addr);
6547 GET_MEMNUM_INC(mem, bp);
6548 GET_RELADDR_INC(addr, bp);
6549 fprintf(f,
":%d:(%s%d)", mem, (addr >= 0) ?
"+" :
"", addr);
6553 fprintf(stderr,
"onig_print_compiled_byte_code: undefined code %d\n",
6558 if (nextp) *nextp = bp;
6561# ifdef ONIG_DEBUG_COMPILE
6563print_compiled_byte_code_list(
FILE* f,
regex_t* reg)
6567 UChar* end = reg->p + reg->used;
6569 fprintf(f,
"code length: %d", reg->used);
6575 fprintf(f,
"\n%ld:", bp - reg->p);
6577 fprintf(f,
" %ld:", bp - reg->p);
6578 onig_print_compiled_byte_code(f, bp, end, &bp, reg->enc);
6585# ifdef ONIG_DEBUG_PARSE_TREE
6587print_indent_tree(
FILE* f,
Node* node,
int indent)
6589 int i,
type, container_p = 0;
6594 if (IS_NULL(node)) {
6595 fprintf(f,
"ERROR: null node!!!\n");
6603 if (NTYPE(node) == NT_LIST)
6604 fprintf(f,
"<list:%"PRIxPTR
">\n", (intptr_t )node);
6606 fprintf(f,
"<alt:%"PRIxPTR
">\n", (intptr_t )node);
6608 print_indent_tree(f, NCAR(node), indent + add);
6609 while (IS_NOT_NULL(node = NCDR(node))) {
6610 if (NTYPE(node) != type) {
6611 fprintf(f,
"ERROR: list/alt right is not a cons. %d\n", NTYPE(node));
6614 print_indent_tree(f, NCAR(node), indent + add);
6619 fprintf(f,
"<string%s:%"PRIxPTR
">",
6620 (NSTRING_IS_RAW(node) ?
"-raw" :
""), (intptr_t )node);
6621 for (p = NSTR(node)->s; p < NSTR(node)->end; p++) {
6622 if (*p >= 0x20 && *p < 0x7f)
6625 fprintf(f,
" 0x%02x", *p);
6631 fprintf(f,
"<cclass:%"PRIxPTR
">", (intptr_t )node);
6632 if (IS_NCCLASS_NOT(NCCLASS(node))) fputs(
"not ", f);
6633 if (NCCLASS(node)->mbuf) {
6634 BBuf* bbuf = NCCLASS(node)->mbuf;
6635 OnigCodePoint* data = (OnigCodePoint* )bbuf->p;
6636 OnigCodePoint* end = (OnigCodePoint* )(bbuf->p + bbuf->used);
6637 fprintf(f,
"%d", *data++);
6638 for (; data < end; data+=2) {
6640 fprintf(f,
"%04x-%04x", data[0], data[1]);
6646 fprintf(f,
"<ctype:%"PRIxPTR
"> ", (intptr_t )node);
6647 switch (NCTYPE(node)->ctype) {
6648 case ONIGENC_CTYPE_WORD:
6649 if (NCTYPE(node)->not != 0)
6650 fputs(
"not word", f);
6656 fprintf(f,
"ERROR: undefined ctype.\n");
6662 fprintf(f,
"<anychar:%"PRIxPTR
">", (intptr_t )node);
6666 fprintf(f,
"<anchor:%"PRIxPTR
"> ", (intptr_t )node);
6667 switch (NANCHOR(node)->type) {
6668 case ANCHOR_BEGIN_BUF: fputs(
"begin buf", f);
break;
6669 case ANCHOR_END_BUF: fputs(
"end buf", f);
break;
6670 case ANCHOR_BEGIN_LINE: fputs(
"begin line", f);
break;
6671 case ANCHOR_END_LINE: fputs(
"end line", f);
break;
6672 case ANCHOR_SEMI_END_BUF: fputs(
"semi end buf", f);
break;
6673 case ANCHOR_BEGIN_POSITION: fputs(
"begin position", f);
break;
6675 case ANCHOR_WORD_BOUND: fputs(
"word bound", f);
break;
6676 case ANCHOR_NOT_WORD_BOUND: fputs(
"not word bound", f);
break;
6677# ifdef USE_WORD_BEGIN_END
6678 case ANCHOR_WORD_BEGIN: fputs(
"word begin", f);
break;
6679 case ANCHOR_WORD_END: fputs(
"word end", f);
break;
6681 case ANCHOR_PREC_READ: fputs(
"prec read", f); container_p = TRUE;
break;
6682 case ANCHOR_PREC_READ_NOT: fputs(
"prec read not", f); container_p = TRUE;
break;
6683 case ANCHOR_LOOK_BEHIND: fputs(
"look_behind", f); container_p = TRUE;
break;
6684 case ANCHOR_LOOK_BEHIND_NOT: fputs(
"look_behind_not",f); container_p = TRUE;
break;
6685 case ANCHOR_KEEP: fputs(
"keep",f);
break;
6688 fprintf(f,
"ERROR: undefined anchor type.\n");
6698 fprintf(f,
"<backref:%"PRIxPTR
">", (intptr_t )node);
6699 for (i = 0; i < br->back_num; i++) {
6700 if (i > 0) fputs(
", ", f);
6701 fprintf(f,
"%d", p[i]);
6706# ifdef USE_SUBEXP_CALL
6710 fprintf(f,
"<call:%"PRIxPTR
">", (intptr_t )node);
6711 p_string(f, cn->name_end - cn->name, cn->name);
6717 fprintf(f,
"<quantifier:%"PRIxPTR
">{%d,%d}%s\n", (intptr_t )node,
6718 NQTFR(node)->lower, NQTFR(node)->upper,
6719 (NQTFR(node)->greedy ?
"" :
"?"));
6720 print_indent_tree(f, NQTFR(node)->target, indent + add);
6724 fprintf(f,
"<enclose:%"PRIxPTR
"> ", (intptr_t )node);
6725 switch (NENCLOSE(node)->type) {
6726 case ENCLOSE_OPTION:
6727 fprintf(f,
"option:%d", NENCLOSE(node)->option);
6729 case ENCLOSE_MEMORY:
6730 fprintf(f,
"memory:%d", NENCLOSE(node)->regnum);
6732 case ENCLOSE_STOP_BACKTRACK:
6733 fprintf(f,
"stop-bt");
6735 case ENCLOSE_CONDITION:
6736 fprintf(f,
"condition:%d", NENCLOSE(node)->regnum);
6738 case ENCLOSE_ABSENT:
6739 fprintf(f,
"absent");
6746 print_indent_tree(f, NENCLOSE(node)->target, indent + add);
6750 fprintf(f,
"print_indent_tree: undefined node type %d\n", NTYPE(node));
6754 if (type != NT_LIST && type != NT_ALT && type != NT_QTFR &&
6758 if (container_p) print_indent_tree(f, NANCHOR(node)->target, indent + add);
6766 print_indent_tree(f, node, 0);
#define xfree
Old name of ruby_xfree.
#define xrealloc
Old name of ruby_xrealloc.
#define xmalloc
Old name of ruby_xmalloc.
int len
Length of the buffer.
VALUE type(ANYARGS)
ANYARGS-ed function type.