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);
1359 len += (SIZE_OP_MEMORY_START_PUSH + SIZE_OP_RETURN);
1360 if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
1361 len += (IS_ENCLOSE_RECURSION(node)
1362 ? SIZE_OP_MEMORY_END_PUSH_REC : SIZE_OP_MEMORY_END_PUSH);
1364 len += (IS_ENCLOSE_RECURSION(node)
1365 ? SIZE_OP_MEMORY_END_REC : SIZE_OP_MEMORY_END);
1367 r = add_opcode_rel_addr(reg, OP_JUMP,
len);
1371 if (BIT_STATUS_AT(reg->bt_mem_start, node->regnum))
1372 r = add_opcode(reg, OP_MEMORY_START_PUSH);
1374 r = add_opcode(reg, OP_MEMORY_START);
1376 r = add_mem_num(reg, node->regnum);
1378 r = compile_tree(node->target, reg);
1380#ifdef USE_SUBEXP_CALL
1381 if (IS_ENCLOSE_CALLED(node)) {
1382 if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
1383 r = add_opcode(reg, (IS_ENCLOSE_RECURSION(node)
1384 ? OP_MEMORY_END_PUSH_REC : OP_MEMORY_END_PUSH));
1386 r = add_opcode(reg, (IS_ENCLOSE_RECURSION(node)
1387 ? OP_MEMORY_END_REC : OP_MEMORY_END));
1390 r = add_mem_num(reg, node->regnum);
1392 r = add_opcode(reg, OP_RETURN);
1394 else if (IS_ENCLOSE_RECURSION(node)) {
1395 if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
1396 r = add_opcode(reg, OP_MEMORY_END_PUSH_REC);
1398 r = add_opcode(reg, OP_MEMORY_END_REC);
1400 r = add_mem_num(reg, node->regnum);
1405 if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
1406 r = add_opcode(reg, OP_MEMORY_END_PUSH);
1408 r = add_opcode(reg, OP_MEMORY_END);
1410 r = add_mem_num(reg, node->regnum);
1414 case ENCLOSE_STOP_BACKTRACK:
1418#ifndef USE_MATCH_CACHE
1419 if (IS_ENCLOSE_STOP_BT_SIMPLE_REPEAT(node)) {
1420 QtfrNode* qn = NQTFR(node->target);
1421 r = compile_tree_n_times(qn->target, qn->lower, reg);
1424 len = compile_length_tree(qn->target, reg);
1427 r = add_opcode_rel_addr(reg, OP_PUSH,
len + SIZE_OP_POP + SIZE_OP_JUMP);
1429 r = compile_tree(qn->target, reg);
1431 r = add_opcode(reg, OP_POP);
1433 r = add_opcode_rel_addr(reg, OP_JUMP,
1434 -((
int )SIZE_OP_PUSH +
len + (
int )SIZE_OP_POP + (
int )SIZE_OP_JUMP));
1438 r = add_opcode(reg, OP_PUSH_STOP_BT);
1440 r = compile_tree(node->target, reg);
1442 r = add_opcode(reg, OP_POP_STOP_BT);
1443#ifndef USE_MATCH_CACHE
1448 case ENCLOSE_CONDITION:
1449 r = add_opcode(reg, OP_CONDITION);
1451 r = add_mem_num(reg, node->regnum);
1454 if (NTYPE(node->target) == NT_ALT) {
1455 Node* x = node->target;
1458 len = compile_length_tree(NCAR(x), reg);
1460 if (NCDR(x) == NULL)
return ONIGERR_PARSER_BUG;
1462 len2 = compile_length_tree(NCAR(x), reg);
1463 if (len2 < 0)
return len2;
1464 if (NCDR(x) != NULL)
return ONIGERR_INVALID_CONDITION_PATTERN;
1467 r = add_rel_addr(reg,
len + SIZE_OP_JUMP);
1469 r = compile_tree(NCAR(x), reg);
1471 r = add_opcode_rel_addr(reg, OP_JUMP, len2);
1474 r = compile_tree(NCAR(x), reg);
1477 return ONIGERR_PARSER_BUG;
1481 case ENCLOSE_ABSENT:
1482 len = compile_length_tree(node->target, reg);
1485 r = add_opcode(reg, OP_PUSH_ABSENT_POS);
1487 r = add_opcode_rel_addr(reg, OP_ABSENT,
len + SIZE_OP_ABSENT_END);
1489 r = compile_tree(node->target, reg);
1491 r = add_opcode(reg, OP_ABSENT_END);
1495 return ONIGERR_TYPE_BUG;
1509 tlen = compile_length_tree(node->target, reg);
1510 if (tlen < 0)
return tlen;
1513 switch (node->type) {
1514 case ANCHOR_PREC_READ:
1515 len = SIZE_OP_PUSH_POS + tlen + SIZE_OP_POP_POS;
1517 case ANCHOR_PREC_READ_NOT:
1518 len = SIZE_OP_PUSH_POS_NOT + tlen + SIZE_OP_FAIL_POS;
1520 case ANCHOR_LOOK_BEHIND:
1521 len = SIZE_OP_LOOK_BEHIND + tlen;
1523 case ANCHOR_LOOK_BEHIND_NOT:
1524 len = SIZE_OP_PUSH_LOOK_BEHIND_NOT + tlen + SIZE_OP_FAIL_LOOK_BEHIND_NOT;
1540 switch (node->type) {
1541 case ANCHOR_BEGIN_BUF: r = add_opcode(reg, OP_BEGIN_BUF);
break;
1542 case ANCHOR_END_BUF: r = add_opcode(reg, OP_END_BUF);
break;
1543 case ANCHOR_BEGIN_LINE: r = add_opcode(reg, OP_BEGIN_LINE);
break;
1544 case ANCHOR_END_LINE: r = add_opcode(reg, OP_END_LINE);
break;
1545 case ANCHOR_SEMI_END_BUF: r = add_opcode(reg, OP_SEMI_END_BUF);
break;
1546 case ANCHOR_BEGIN_POSITION: r = add_opcode(reg, OP_BEGIN_POSITION);
break;
1548 case ANCHOR_WORD_BOUND:
1549 if (node->ascii_range) r = add_opcode(reg, OP_ASCII_WORD_BOUND);
1550 else r = add_opcode(reg, OP_WORD_BOUND);
1552 case ANCHOR_NOT_WORD_BOUND:
1553 if (node->ascii_range) r = add_opcode(reg, OP_NOT_ASCII_WORD_BOUND);
1554 else r = add_opcode(reg, OP_NOT_WORD_BOUND);
1556#ifdef USE_WORD_BEGIN_END
1557 case ANCHOR_WORD_BEGIN:
1558 if (node->ascii_range) r = add_opcode(reg, OP_ASCII_WORD_BEGIN);
1559 else r = add_opcode(reg, OP_WORD_BEGIN);
1561 case ANCHOR_WORD_END:
1562 if (node->ascii_range) r = add_opcode(reg, OP_ASCII_WORD_END);
1563 else r = add_opcode(reg, OP_WORD_END);
1566 case ANCHOR_KEEP: r = add_opcode(reg, OP_KEEP);
break;
1568 case ANCHOR_PREC_READ:
1569 r = add_opcode(reg, OP_PUSH_POS);
1571 r = compile_tree(node->target, reg);
1573 r = add_opcode(reg, OP_POP_POS);
1576 case ANCHOR_PREC_READ_NOT:
1577 len = compile_length_tree(node->target, reg);
1579 r = add_opcode_rel_addr(reg, OP_PUSH_POS_NOT,
len + SIZE_OP_FAIL_POS);
1581 r = compile_tree(node->target, reg);
1583 r = add_opcode(reg, OP_FAIL_POS);
1586 case ANCHOR_LOOK_BEHIND:
1589 r = add_opcode(reg, OP_LOOK_BEHIND);
1591 if (node->char_len < 0) {
1592 r = get_char_length_tree(node->target, reg, &n);
1593 if (r)
return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
1597 r = add_length(reg, n);
1599 r = compile_tree(node->target, reg);
1603 case ANCHOR_LOOK_BEHIND_NOT:
1606 len = compile_length_tree(node->target, reg);
1607 r = add_opcode_rel_addr(reg, OP_PUSH_LOOK_BEHIND_NOT,
1608 len + SIZE_OP_FAIL_LOOK_BEHIND_NOT);
1610 if (node->char_len < 0) {
1611 r = get_char_length_tree(node->target, reg, &n);
1612 if (r)
return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
1616 r = add_length(reg, n);
1618 r = compile_tree(node->target, reg);
1620 r = add_opcode(reg, OP_FAIL_LOOK_BEHIND_NOT);
1625 return ONIGERR_TYPE_BUG;
1642 r = compile_length_tree(NCAR(node), reg);
1643 if (r < 0)
return r;
1645 }
while (IS_NOT_NULL(node = NCDR(node)));
1654 r = compile_length_tree(NCAR(node), reg);
1655 if (r < 0)
return r;
1658 }
while (IS_NOT_NULL(node = NCDR(node)));
1660 r += (SIZE_OP_PUSH + SIZE_OP_JUMP) * (n - 1);
1665 if (NSTRING_IS_RAW(node))
1666 r = compile_length_string_raw_node(NSTR(node), reg);
1668 r = compile_length_string_node(node, reg);
1672 r = compile_length_cclass_node(NCCLASS(node), reg);
1684#ifdef USE_BACKREF_WITH_LEVEL
1685 if (IS_BACKREF_NEST_LEVEL(br)) {
1686 r = SIZE_OPCODE + SIZE_OPTION + SIZE_LENGTH +
1687 SIZE_LENGTH + (SIZE_MEMNUM * br->back_num);
1691 if (br->back_num == 1) {
1692 r = ((!IS_IGNORECASE(reg->options) && br->back_static[0] <= 2)
1693 ? SIZE_OPCODE : (SIZE_OPCODE + SIZE_MEMNUM));
1696 r = SIZE_OPCODE + SIZE_LENGTH + (SIZE_MEMNUM * br->back_num);
1701#ifdef USE_SUBEXP_CALL
1708 r = compile_length_quantifier_node(NQTFR(node), reg);
1712 r = compile_length_enclose_node(NENCLOSE(node), reg);
1716 r = compile_length_anchor_node(NANCHOR(node), reg);
1720 return ONIGERR_TYPE_BUG;
1736 r = compile_tree(NCAR(node), reg);
1737 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
1745 len += compile_length_tree(NCAR(x), reg);
1746 if (NCDR(x) != NULL) {
1747 len += SIZE_OP_PUSH + SIZE_OP_JUMP;
1749 }
while (IS_NOT_NULL(x = NCDR(x)));
1750 pos = reg->used +
len;
1753 len = compile_length_tree(NCAR(node), reg);
1754 if (IS_NOT_NULL(NCDR(node))) {
1755 r = add_opcode_rel_addr(reg, OP_PUSH,
len + SIZE_OP_JUMP);
1758 r = compile_tree(NCAR(node), reg);
1760 if (IS_NOT_NULL(NCDR(node))) {
1761 len = pos - (reg->used + SIZE_OP_JUMP);
1762 r = add_opcode_rel_addr(reg, OP_JUMP,
len);
1765 }
while (IS_NOT_NULL(node = NCDR(node)));
1770 if (NSTRING_IS_RAW(node))
1771 r = compile_string_raw_node(NSTR(node), reg);
1773 r = compile_string_node(node, reg);
1777 r = compile_cclass_node(NCCLASS(node), reg);
1784 switch (NCTYPE(node)->ctype) {
1785 case ONIGENC_CTYPE_WORD:
1786 if (NCTYPE(node)->ascii_range != 0) {
1787 if (NCTYPE(node)->not != 0) op = OP_NOT_ASCII_WORD;
1788 else op = OP_ASCII_WORD;
1791 if (NCTYPE(node)->not != 0) op = OP_NOT_WORD;
1796 return ONIGERR_TYPE_BUG;
1799 r = add_opcode(reg, op);
1804 if (IS_MULTILINE(reg->options))
1805 r = add_opcode(reg, OP_ANYCHAR_ML);
1807 r = add_opcode(reg, OP_ANYCHAR);
1814#ifdef USE_BACKREF_WITH_LEVEL
1815 if (IS_BACKREF_NEST_LEVEL(br)) {
1816 r = add_opcode(reg, OP_BACKREF_WITH_LEVEL);
1818 r = add_option(reg, (reg->options & ONIG_OPTION_IGNORECASE));
1820 r = add_length(reg, br->nest_level);
1823 goto add_bacref_mems;
1827 if (br->back_num == 1) {
1828 n = br->back_static[0];
1829 if (IS_IGNORECASE(reg->options)) {
1830 r = add_opcode(reg, OP_BACKREFN_IC);
1832 r = add_mem_num(reg, n);
1836 case 1: r = add_opcode(reg, OP_BACKREF1);
break;
1837 case 2: r = add_opcode(reg, OP_BACKREF2);
break;
1839 r = add_opcode(reg, OP_BACKREFN);
1841 r = add_mem_num(reg, n);
1850 if (IS_IGNORECASE(reg->options)) {
1851 r = add_opcode(reg, OP_BACKREF_MULTI_IC);
1854 r = add_opcode(reg, OP_BACKREF_MULTI);
1858#ifdef USE_BACKREF_WITH_LEVEL
1861 r = add_length(reg, br->back_num);
1864 for (i = br->back_num - 1; i >= 0; i--) {
1865 r = add_mem_num(reg, p[i]);
1872#ifdef USE_SUBEXP_CALL
1874 r = compile_call(NCALL(node), reg);
1879 r = compile_quantifier_node(NQTFR(node), reg);
1883 r = compile_enclose_node(NENCLOSE(node), reg);
1887 r = compile_anchor_node(NANCHOR(node), reg);
1892 fprintf(stderr,
"compile_tree: undefined node type %d\n", NTYPE(node));
1900#ifdef USE_NAMED_GROUP
1906 Node* node = *plink;
1908 switch (NTYPE(node)) {
1912 r = noname_disable_map(&(NCAR(node)), map, counter);
1913 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
1918 Node** ptarget = &(NQTFR(node)->target);
1919 Node* old = *ptarget;
1920 r = noname_disable_map(ptarget, map, counter);
1921 if (*ptarget != old && NTYPE(*ptarget) == NT_QTFR) {
1922 onig_reduce_nested_quantifier(node, *ptarget);
1930 if (en->type == ENCLOSE_MEMORY) {
1931 if (IS_ENCLOSE_NAMED_GROUP(en)) {
1933 map[en->regnum].new_val = *counter;
1934 en->regnum = *counter;
1936 else if (en->regnum != 0) {
1937 *plink = en->target;
1938 en->target = NULL_NODE;
1939 onig_node_free(node);
1940 r = noname_disable_map(plink, map, counter);
1944 r = noname_disable_map(&(en->target), map, counter);
1949 if (NANCHOR(node)->target)
1950 r = noname_disable_map(&(NANCHOR(node)->target), map, counter);
1963 int i, pos, n, old_num;
1967 if (! IS_BACKREF_NAME_REF(bn))
1968 return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
1970 old_num = bn->back_num;
1971 if (IS_NULL(bn->back_dynamic))
1972 backs = bn->back_static;
1974 backs = bn->back_dynamic;
1976 for (i = 0, pos = 0; i < old_num; i++) {
1977 if (backs[i] > num_mem)
return ONIGERR_INVALID_BACKREF;
1978 n = map[backs[i]].new_val;
1994 switch (NTYPE(node)) {
1998 r = renumber_by_map(NCAR(node), map, num_mem);
1999 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
2002 r = renumber_by_map(NQTFR(node)->target, map, num_mem);
2007 if (en->type == ENCLOSE_CONDITION) {
2008 if (en->regnum > num_mem)
return ONIGERR_INVALID_BACKREF;
2009 en->regnum = map[en->regnum].new_val;
2011 r = renumber_by_map(en->target, map, num_mem);
2016 r = renumber_node_backref(node, map, num_mem);
2020 if (NANCHOR(node)->target)
2021 r = renumber_by_map(NANCHOR(node)->target, map, num_mem);
2032numbered_ref_check(
Node* node)
2036 switch (NTYPE(node)) {
2040 r = numbered_ref_check(NCAR(node));
2041 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
2044 r = numbered_ref_check(NQTFR(node)->target);
2047 r = numbered_ref_check(NENCLOSE(node)->target);
2051 if (! IS_BACKREF_NAME_REF(NBREF(node)))
2052 return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
2056 if (NANCHOR(node)->target)
2057 r = numbered_ref_check(NANCHOR(node)->target);
2070 int r, i, pos, counter;
2075 CHECK_NULL_RETURN_MEMERR(map);
2076 for (i = 1; i <= env->num_mem; i++) {
2080 r = noname_disable_map(root, map, &counter);
2081 if (r != 0)
return r;
2083 r = renumber_by_map(*root, map, env->num_mem);
2084 if (r != 0)
return r;
2086 for (i = 1, pos = 1; i <= env->num_mem; i++) {
2087 if (map[i].new_val > 0) {
2088 SCANENV_MEM_NODES(env)[pos] = SCANENV_MEM_NODES(env)[i];
2093 loc = env->capture_history;
2094 BIT_STATUS_CLEAR(env->capture_history);
2095 for (i = 1; i <= ONIG_MAX_CAPTURE_HISTORY_GROUP; i++) {
2096 if (BIT_STATUS_AT(loc, i)) {
2097 BIT_STATUS_ON_AT_SIMPLE(env->capture_history, map[i].new_val);
2101 env->num_mem = env->num_named;
2102 reg->num_mem = env->num_named;
2104 return onig_renumber_name_table(reg, map);
2108#ifdef USE_SUBEXP_CALL
2116 for (i = 0; i < uslist->num; i++) {
2117 en = NENCLOSE(uslist->us[i].target);
2118 if (! IS_ENCLOSE_ADDR_FIXED(en))
return ONIGERR_PARSER_BUG;
2119 addr = en->call_addr;
2120 offset = uslist->us[i].offset;
2122 BBUF_WRITE(reg, offset, &addr, SIZE_ABSADDR);
2128#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
2130quantifiers_memory_node_info(
Node* node)
2134 switch (NTYPE(node)) {
2140 v = quantifiers_memory_node_info(NCAR(node));
2142 }
while (v >= 0 && IS_NOT_NULL(node = NCDR(node)));
2146# ifdef USE_SUBEXP_CALL
2148 if (IS_CALL_RECURSION(NCALL(node))) {
2149 return NQ_TARGET_IS_EMPTY_REC;
2152 r = quantifiers_memory_node_info(NCALL(node)->target);
2159 if (qn->upper != 0) {
2160 r = quantifiers_memory_node_info(qn->target);
2169 case ENCLOSE_MEMORY:
2170 return NQ_TARGET_IS_EMPTY_MEM;
2173 case ENCLOSE_OPTION:
2174 case ENCLOSE_STOP_BACKTRACK:
2175 case ENCLOSE_CONDITION:
2176 case ENCLOSE_ABSENT:
2177 r = quantifiers_memory_node_info(en->target);
2200get_min_match_length(
Node* node, OnigDistance *min,
ScanEnv* env)
2206 switch (NTYPE(node)) {
2211 Node** nodes = SCANENV_MEM_NODES(env);
2213 if (br->state & NST_RECURSION)
break;
2215 backs = BACKREFS_P(br);
2216 if (backs[0] > env->num_mem)
return ONIGERR_INVALID_BACKREF;
2217 r = get_min_match_length(nodes[backs[0]], min, env);
2219 for (i = 1; i < br->back_num; i++) {
2220 if (backs[i] > env->num_mem)
return ONIGERR_INVALID_BACKREF;
2221 r = get_min_match_length(nodes[backs[i]], &tmin, env);
2223 if (*min > tmin) *min = tmin;
2228#ifdef USE_SUBEXP_CALL
2230 if (IS_CALL_RECURSION(NCALL(node))) {
2232 if (IS_ENCLOSE_MIN_FIXED(en))
2236 r = get_min_match_length(NCALL(node)->target, min, env);
2242 r = get_min_match_length(NCAR(node), &tmin, env);
2243 if (r == 0) *min += tmin;
2244 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
2253 r = get_min_match_length(x, &tmin, env);
2255 if (y == node) *min = tmin;
2256 else if (*min > tmin) *min = tmin;
2257 }
while (r == 0 && IS_NOT_NULL(y = NCDR(y)));
2264 *min = sn->end - sn->s;
2281 if (qn->lower > 0) {
2282 r = get_min_match_length(qn->target, min, env);
2284 *min = distance_multiply(*min, qn->lower);
2293 case ENCLOSE_MEMORY:
2294 if (IS_ENCLOSE_MIN_FIXED(en))
2297 if (IS_ENCLOSE_MARK1(NENCLOSE(node)))
2300 SET_ENCLOSE_STATUS(node, NST_MARK1);
2301 r = get_min_match_length(en->target, min, env);
2302 CLEAR_ENCLOSE_STATUS(node, NST_MARK1);
2305 SET_ENCLOSE_STATUS(node, NST_MIN_FIXED);
2311 case ENCLOSE_OPTION:
2312 case ENCLOSE_STOP_BACKTRACK:
2313 case ENCLOSE_CONDITION:
2314 r = get_min_match_length(en->target, min, env);
2317 case ENCLOSE_ABSENT:
2332get_max_match_length(
Node* node, OnigDistance *max,
ScanEnv* env)
2338 switch (NTYPE(node)) {
2341 r = get_max_match_length(NCAR(node), &tmax, env);
2343 *max = distance_add(*max, tmax);
2344 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
2349 r = get_max_match_length(NCAR(node), &tmax, env);
2350 if (r == 0 && *max < tmax) *max = tmax;
2351 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
2357 *max = sn->end - sn->s;
2362 *max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
2367 *max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
2374 Node** nodes = SCANENV_MEM_NODES(env);
2376 if (br->state & NST_RECURSION) {
2377 *max = ONIG_INFINITE_DISTANCE;
2380 backs = BACKREFS_P(br);
2381 for (i = 0; i < br->back_num; i++) {
2382 if (backs[i] > env->num_mem)
return ONIGERR_INVALID_BACKREF;
2383 r = get_max_match_length(nodes[backs[i]], &tmax, env);
2385 if (*max < tmax) *max = tmax;
2390#ifdef USE_SUBEXP_CALL
2392 if (! IS_CALL_RECURSION(NCALL(node)))
2393 r = get_max_match_length(NCALL(node)->target, max, env);
2395 *max = ONIG_INFINITE_DISTANCE;
2403 if (qn->upper != 0) {
2404 r = get_max_match_length(qn->target, max, env);
2405 if (r == 0 && *max != 0) {
2406 if (! IS_REPEAT_INFINITE(qn->upper))
2407 *max = distance_multiply(*max, qn->upper);
2409 *max = ONIG_INFINITE_DISTANCE;
2419 case ENCLOSE_MEMORY:
2420 if (IS_ENCLOSE_MAX_FIXED(en))
2423 if (IS_ENCLOSE_MARK1(NENCLOSE(node)))
2424 *max = ONIG_INFINITE_DISTANCE;
2426 SET_ENCLOSE_STATUS(node, NST_MARK1);
2427 r = get_max_match_length(en->target, max, env);
2428 CLEAR_ENCLOSE_STATUS(node, NST_MARK1);
2431 SET_ENCLOSE_STATUS(node, NST_MAX_FIXED);
2437 case ENCLOSE_OPTION:
2438 case ENCLOSE_STOP_BACKTRACK:
2439 case ENCLOSE_CONDITION:
2440 r = get_max_match_length(en->target, max, env);
2443 case ENCLOSE_ABSENT:
2457#define GET_CHAR_LEN_VARLEN -1
2458#define GET_CHAR_LEN_TOP_ALT_VARLEN -2
2462get_char_length_tree1(
Node* node,
regex_t* reg,
int*
len,
int level)
2469 switch (NTYPE(node)) {
2472 r = get_char_length_tree1(NCAR(node), reg, &tlen, level);
2474 *
len = (int )distance_add(*
len, tlen);
2475 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
2483 r = get_char_length_tree1(NCAR(node), reg, &tlen, level);
2484 while (r == 0 && IS_NOT_NULL(node = NCDR(node))) {
2485 r = get_char_length_tree1(NCAR(node), reg, &tlen2, level);
2494 r = GET_CHAR_LEN_TOP_ALT_VARLEN;
2496 r = GET_CHAR_LEN_VARLEN;
2508 while (s < sn->end) {
2509 s += enclen(reg->enc, s, sn->end);
2518 if (qn->lower == qn->upper) {
2519 r = get_char_length_tree1(qn->target, reg, &tlen, level);
2521 *
len = (int )distance_multiply(tlen, qn->lower);
2524 r = GET_CHAR_LEN_VARLEN;
2528#ifdef USE_SUBEXP_CALL
2530 if (! IS_CALL_RECURSION(NCALL(node)))
2531 r = get_char_length_tree1(NCALL(node)->target, reg,
len, level);
2533 r = GET_CHAR_LEN_VARLEN;
2550 case ENCLOSE_MEMORY:
2551#ifdef USE_SUBEXP_CALL
2552 if (IS_ENCLOSE_CLEN_FIXED(en))
2553 *
len = en->char_len;
2555 r = get_char_length_tree1(en->target, reg,
len, level);
2557 en->char_len = *
len;
2558 SET_ENCLOSE_STATUS(node, NST_CLEN_FIXED);
2563 case ENCLOSE_OPTION:
2564 case ENCLOSE_STOP_BACKTRACK:
2565 case ENCLOSE_CONDITION:
2566 r = get_char_length_tree1(en->target, reg,
len, level);
2568 case ENCLOSE_ABSENT:
2579 r = GET_CHAR_LEN_VARLEN;
2589 return get_char_length_tree1(node, reg,
len, 0);
2609 if (NCTYPE(y)->ctype == NCTYPE(x)->ctype &&
2610 NCTYPE(y)->not != NCTYPE(x)->not &&
2611 NCTYPE(y)->ascii_range == NCTYPE(x)->ascii_range)
2621 tmp = x; x = y; y = tmp;
2641 switch (NCTYPE(y)->ctype) {
2642 case ONIGENC_CTYPE_WORD:
2643 if (NCTYPE(y)->not == 0) {
2644 if (IS_NULL(xc->mbuf) && !IS_NCCLASS_NOT(xc)) {
2645 for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
2646 if (BITSET_AT(xc->bs, i)) {
2647 if (NCTYPE(y)->ascii_range) {
2648 if (IS_CODE_SB_WORD(reg->enc, i))
return 0;
2651 if (ONIGENC_IS_CODE_WORD(reg->enc, i))
return 0;
2660 if (IS_NOT_NULL(xc->mbuf))
return 0;
2661 for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
2663 if (NCTYPE(y)->ascii_range)
2664 is_word = IS_CODE_SB_WORD(reg->enc, i);
2666 is_word = ONIGENC_IS_CODE_WORD(reg->enc, i);
2668 if (!IS_NCCLASS_NOT(xc)) {
2669 if (BITSET_AT(xc->bs, i))
2673 if (! BITSET_AT(xc->bs, i))
2692 for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
2693 v = BITSET_AT(xc->bs, i);
2694 if ((v != 0 && !IS_NCCLASS_NOT(xc)) ||
2695 (v == 0 && IS_NCCLASS_NOT(xc))) {
2696 v = BITSET_AT(yc->bs, i);
2697 if ((v != 0 && !IS_NCCLASS_NOT(yc)) ||
2698 (v == 0 && IS_NCCLASS_NOT(yc)))
2702 if ((IS_NULL(xc->mbuf) && !IS_NCCLASS_NOT(xc)) ||
2703 (IS_NULL(yc->mbuf) && !IS_NCCLASS_NOT(yc)))
2722 if (NSTRING_LEN(x) == 0)
2727 switch (NCTYPE(y)->ctype) {
2728 case ONIGENC_CTYPE_WORD:
2729 if (NCTYPE(y)->ascii_range) {
2730 if (ONIGENC_IS_MBC_ASCII_WORD(reg->enc, xs->s, xs->end))
2731 return NCTYPE(y)->not;
2733 return !(NCTYPE(y)->not);
2736 if (ONIGENC_IS_MBC_WORD(reg->enc, xs->s, xs->end))
2737 return NCTYPE(y)->not;
2739 return !(NCTYPE(y)->not);
2751 code = ONIGENC_MBC_TO_CODE(reg->enc, xs->s,
2752 xs->s + ONIGENC_MBC_MAXLEN(reg->enc));
2753 return (onig_is_code_in_cc(reg->enc, code, cc) != 0 ? 0 : 1);
2761 len = NSTRING_LEN(x);
2762 if (
len > NSTRING_LEN(y))
len = NSTRING_LEN(y);
2763 if (NSTRING_IS_AMBIG(x) || NSTRING_IS_AMBIG(y)) {
2768 for (i = 0, p = ys->s, q = xs->s; (OnigDistance )i <
len; i++, p++, q++) {
2769 if (*p != *q)
return 1;
2789get_head_value_node(
Node* node,
int exact,
regex_t* reg)
2791 Node* n = NULL_NODE;
2793 switch (NTYPE(node)) {
2797#ifdef USE_SUBEXP_CALL
2810 n = get_head_value_node(NCAR(node), exact, reg);
2816 if (sn->end <= sn->s)
2820 NSTRING_IS_RAW(node) || !IS_IGNORECASE(reg->options)) {
2829 if (qn->lower > 0) {
2830#ifdef USE_OP_PUSH_OR_JUMP_EXACT
2831 if (IS_NOT_NULL(qn->head_exact))
2835 n = get_head_value_node(qn->target, exact, reg);
2844 case ENCLOSE_OPTION:
2846 OnigOptionType options = reg->options;
2848 reg->options = NENCLOSE(node)->option;
2849 n = get_head_value_node(NENCLOSE(node)->target, exact, reg);
2850 reg->options = options;
2854 case ENCLOSE_MEMORY:
2855 case ENCLOSE_STOP_BACKTRACK:
2856 case ENCLOSE_CONDITION:
2857 n = get_head_value_node(en->target, exact, reg);
2860 case ENCLOSE_ABSENT:
2867 if (NANCHOR(node)->type == ANCHOR_PREC_READ)
2868 n = get_head_value_node(NANCHOR(node)->target, exact, reg);
2879check_type_tree(
Node* node,
int type_mask,
int enclose_mask,
int anchor_mask)
2884 if ((NTYPE2BIT(type) & type_mask) == 0)
2891 r = check_type_tree(NCAR(node), type_mask, enclose_mask,
2893 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
2897 r = check_type_tree(NQTFR(node)->target, type_mask, enclose_mask,
2904 if ((en->type & enclose_mask) == 0)
2907 r = check_type_tree(en->target, type_mask, enclose_mask, anchor_mask);
2912 type = NANCHOR(node)->type;
2913 if ((type & anchor_mask) == 0)
2916 if (NANCHOR(node)->target)
2917 r = check_type_tree(NANCHOR(node)->target,
2918 type_mask, enclose_mask, anchor_mask);
2927#ifdef USE_SUBEXP_CALL
2929# define RECURSION_EXIST 1
2930# define RECURSION_INFINITE 2
2933subexp_inf_recursive_check(
Node* node,
ScanEnv* env,
int head)
2948 ret = subexp_inf_recursive_check(NCAR(x), env, head);
2949 if (ret < 0 || ret == RECURSION_INFINITE)
return ret;
2952 ret = get_min_match_length(NCAR(x), &min, env);
2953 if (ret != 0)
return ret;
2954 if (min != 0) head = 0;
2956 }
while (IS_NOT_NULL(x = NCDR(x)));
2963 r = RECURSION_EXIST;
2965 ret = subexp_inf_recursive_check(NCAR(node), env, head);
2966 if (ret < 0 || ret == RECURSION_INFINITE)
return ret;
2968 }
while (IS_NOT_NULL(node = NCDR(node)));
2973 r = subexp_inf_recursive_check(NQTFR(node)->target, env, head);
2974 if (r == RECURSION_EXIST) {
2975 if (NQTFR(node)->lower == 0) r = 0;
2983 case ANCHOR_PREC_READ:
2984 case ANCHOR_PREC_READ_NOT:
2985 case ANCHOR_LOOK_BEHIND:
2986 case ANCHOR_LOOK_BEHIND_NOT:
2987 r = subexp_inf_recursive_check(an->target, env, head);
2994 r = subexp_inf_recursive_check(NCALL(node)->target, env, head);
2998 if (IS_ENCLOSE_MARK2(NENCLOSE(node)))
3000 else if (IS_ENCLOSE_MARK1(NENCLOSE(node)))
3001 return (head == 0 ? RECURSION_EXIST : RECURSION_INFINITE);
3003 SET_ENCLOSE_STATUS(node, NST_MARK2);
3004 r = subexp_inf_recursive_check(NENCLOSE(node)->target, env, head);
3005 CLEAR_ENCLOSE_STATUS(node, NST_MARK2);
3017subexp_inf_recursive_check_trav(
Node* node,
ScanEnv* env)
3027 r = subexp_inf_recursive_check_trav(NCAR(node), env);
3028 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
3032 r = subexp_inf_recursive_check_trav(NQTFR(node)->target, env);
3039 case ANCHOR_PREC_READ:
3040 case ANCHOR_PREC_READ_NOT:
3041 case ANCHOR_LOOK_BEHIND:
3042 case ANCHOR_LOOK_BEHIND_NOT:
3043 r = subexp_inf_recursive_check_trav(an->target, env);
3053 if (IS_ENCLOSE_RECURSION(en)) {
3054 SET_ENCLOSE_STATUS(node, NST_MARK1);
3055 r = subexp_inf_recursive_check(en->target, env, 1);
3056 if (r > 0)
return ONIGERR_NEVER_ENDING_RECURSION;
3057 CLEAR_ENCLOSE_STATUS(node, NST_MARK1);
3059 r = subexp_inf_recursive_check_trav(en->target, env);
3072subexp_recursive_check(
Node* node)
3076 switch (NTYPE(node)) {
3080 r |= subexp_recursive_check(NCAR(node));
3081 }
while (IS_NOT_NULL(node = NCDR(node)));
3085 r = subexp_recursive_check(NQTFR(node)->target);
3092 case ANCHOR_PREC_READ:
3093 case ANCHOR_PREC_READ_NOT:
3094 case ANCHOR_LOOK_BEHIND:
3095 case ANCHOR_LOOK_BEHIND_NOT:
3096 r = subexp_recursive_check(an->target);
3103 r = subexp_recursive_check(NCALL(node)->target);
3104 if (r != 0) SET_CALL_RECURSION(node);
3108 if (IS_ENCLOSE_MARK2(NENCLOSE(node)))
3110 else if (IS_ENCLOSE_MARK1(NENCLOSE(node)))
3113 SET_ENCLOSE_STATUS(node, NST_MARK2);
3114 r = subexp_recursive_check(NENCLOSE(node)->target);
3115 CLEAR_ENCLOSE_STATUS(node, NST_MARK2);
3128subexp_recursive_check_trav(
Node* node,
ScanEnv* env)
3130# define FOUND_CALLED_NODE 1
3142 ret = subexp_recursive_check_trav(NCAR(node), env);
3143 if (ret == FOUND_CALLED_NODE) r = FOUND_CALLED_NODE;
3144 else if (ret < 0)
return ret;
3145 }
while (IS_NOT_NULL(node = NCDR(node)));
3150 r = subexp_recursive_check_trav(NQTFR(node)->target, env);
3151 if (NQTFR(node)->upper == 0) {
3152 if (r == FOUND_CALLED_NODE)
3153 NQTFR(node)->is_referred = 1;
3161 case ANCHOR_PREC_READ:
3162 case ANCHOR_PREC_READ_NOT:
3163 case ANCHOR_LOOK_BEHIND:
3164 case ANCHOR_LOOK_BEHIND_NOT:
3165 r = subexp_recursive_check_trav(an->target, env);
3175 if (! IS_ENCLOSE_RECURSION(en)) {
3176 if (IS_ENCLOSE_CALLED(en)) {
3177 SET_ENCLOSE_STATUS(node, NST_MARK1);
3178 r = subexp_recursive_check(en->target);
3179 if (r != 0) SET_ENCLOSE_STATUS(node, NST_RECURSION);
3180 CLEAR_ENCLOSE_STATUS(node, NST_MARK1);
3183 r = subexp_recursive_check_trav(en->target, env);
3184 if (IS_ENCLOSE_CALLED(en))
3185 r |= FOUND_CALLED_NODE;
3206 r = setup_subexp_call(NCAR(node), env);
3207 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
3212 r = setup_subexp_call(NCAR(node), env);
3213 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
3217 r = setup_subexp_call(NQTFR(node)->target, env);
3220 r = setup_subexp_call(NENCLOSE(node)->target, env);
3226 Node** nodes = SCANENV_MEM_NODES(env);
3228 if (cn->group_num != 0) {
3229 int gnum = cn->group_num;
3231# ifdef USE_NAMED_GROUP
3232 if (env->num_named > 0 &&
3233 IS_SYNTAX_BV(env->syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
3234 !ONIG_IS_OPTION_ON(env->option, ONIG_OPTION_CAPTURE_GROUP)) {
3235 return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
3238 if (gnum > env->num_mem) {
3239 onig_scan_env_set_error_string(env,
3240 ONIGERR_UNDEFINED_GROUP_REFERENCE, cn->name, cn->name_end);
3241 return ONIGERR_UNDEFINED_GROUP_REFERENCE;
3244# ifdef USE_NAMED_GROUP
3247 cn->target = nodes[cn->group_num];
3248 if (IS_NULL(cn->target)) {
3249 onig_scan_env_set_error_string(env,
3250 ONIGERR_UNDEFINED_NAME_REFERENCE, cn->name, cn->name_end);
3251 return ONIGERR_UNDEFINED_NAME_REFERENCE;
3253 SET_ENCLOSE_STATUS(cn->target, NST_CALLED);
3254 BIT_STATUS_ON_AT(env->bt_mem_start, cn->group_num);
3255 cn->unset_addr_list = env->unset_addr_list;
3257# ifdef USE_NAMED_GROUP
3258# ifdef USE_PERL_SUBEXP_CALL
3259 else if (cn->name == cn->name_end) {
3266 int n = onig_name_to_group_numbers(env->reg, cn->name, cn->name_end,
3269 onig_scan_env_set_error_string(env,
3270 ONIGERR_UNDEFINED_NAME_REFERENCE, cn->name, cn->name_end);
3271 return ONIGERR_UNDEFINED_NAME_REFERENCE;
3274 ! IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME_CALL)) {
3275 onig_scan_env_set_error_string(env,
3276 ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL, cn->name, cn->name_end);
3277 return ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL;
3280 cn->group_num = refs[0];
3293 case ANCHOR_PREC_READ:
3294 case ANCHOR_PREC_READ_NOT:
3295 case ANCHOR_LOOK_BEHIND:
3296 case ANCHOR_LOOK_BEHIND_NOT:
3297 r = setup_subexp_call(an->target, env);
3311#define IN_ALT (1<<0)
3312#define IN_NOT (1<<1)
3313#define IN_REPEAT (1<<2)
3314#define IN_VAR_REPEAT (1<<3)
3315#define IN_CALL (1<<4)
3316#define IN_RECCALL (1<<5)
3317#define IN_LOOK_BEHIND (1<<6)
3324divide_look_behind_alternatives(
Node* node)
3326 Node *head, *np, *insert_node;
3328 int anc_type = an->type;
3332 swap_node(node, head);
3334 NANCHOR(head)->target = np;
3337 while ((np = NCDR(np)) != NULL_NODE) {
3338 insert_node = onig_node_new_anchor(anc_type);
3339 CHECK_NULL_RETURN_MEMERR(insert_node);
3340 NANCHOR(insert_node)->target = NCAR(np);
3341 NCAR(np) = insert_node;
3344 if (anc_type == ANCHOR_LOOK_BEHIND_NOT) {
3347 SET_NTYPE(np, NT_LIST);
3348 }
while ((np = NCDR(np)) != NULL_NODE);
3359 r = get_char_length_tree(an->target, reg, &
len);
3362 else if (r == GET_CHAR_LEN_VARLEN)
3363 r = ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
3364 else if (r == GET_CHAR_LEN_TOP_ALT_VARLEN) {
3365 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND))
3366 r = divide_look_behind_alternatives(node);
3368 r = ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
3381 if (type == NT_QTFR) {
3383 if (qn->greedy && IS_REPEAT_INFINITE(qn->upper)) {
3384#ifdef USE_QTFR_PEEK_NEXT
3385 Node* n = get_head_value_node(next_node, 1, reg);
3387 if (IS_NOT_NULL(n) && NSTR(n)->s[0] !=
'\0') {
3388 qn->next_head_exact = n;
3392 if (qn->lower <= 1) {
3393 int ttype = NTYPE(qn->target);
3394 if (IS_NODE_TYPE_SIMPLE(ttype)) {
3396 x = get_head_value_node(qn->target, 0, reg);
3397 if (IS_NOT_NULL(x)) {
3398 y = get_head_value_node(next_node, 0, reg);
3399 if (IS_NOT_NULL(y) && is_not_included(x, y, reg)) {
3400 Node* en = onig_node_new_enclose(ENCLOSE_STOP_BACKTRACK);
3401 CHECK_NULL_RETURN_MEMERR(en);
3402 SET_ENCLOSE_STATUS(en, NST_STOP_BT_SIMPLE_REPEAT);
3403 swap_node(node, en);
3404 NENCLOSE(node)->target = en;
3411 else if (type == NT_ENCLOSE) {
3413 if (en->type == ENCLOSE_MEMORY && !IS_ENCLOSE_CALLED(en)) {
3423update_string_node_case_fold(
regex_t* reg,
Node *node)
3425 UChar *p, *end, buf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
3426 UChar *sbuf, *ebuf, *sp;
3428 OnigDistance sbuf_size;
3432 sbuf_size = (end - sn->s) * 2;
3433 sbuf = (UChar* )
xmalloc(sbuf_size);
3434 CHECK_NULL_RETURN_MEMERR(sbuf);
3435 ebuf = sbuf + sbuf_size;
3440 len = ONIGENC_MBC_CASE_FOLD(reg->enc, reg->case_fold_flag, &p, end, buf);
3441 for (i = 0; i <
len; i++) {
3443 UChar* p = (UChar* )
xrealloc(sbuf, sbuf_size * 2);
3446 return ONIGERR_MEMORY;
3449 sp = sbuf + sbuf_size;
3451 ebuf = sbuf + sbuf_size;
3458 r = onig_node_str_set(node, sbuf, sp);
3465expand_case_fold_make_rem_string(
Node** rnode, UChar *s, UChar *end,
3471 node = onig_node_new_str(s, end);
3472 if (IS_NULL(node))
return ONIGERR_MEMORY;
3474 r = update_string_node_case_fold(reg, node);
3476 onig_node_free(node);
3480 NSTRING_SET_AMBIG(node);
3481 NSTRING_SET_DONT_GET_OPT_INFO(node);
3492 for (i = 0; i < item_num; i++) {
3493 if (items[i].byte_len != slen) {
3496 if (items[i].code_len != 1) {
3505 UChar *p,
int slen, UChar *end,
3508 int r, i, j,
len, varlen;
3509 Node *anode, *var_anode, *snode, *xnode, *an;
3510 UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
3512 *rnode = var_anode = NULL_NODE;
3515 for (i = 0; i < item_num; i++) {
3516 if (items[i].byte_len != slen) {
3523 *rnode = var_anode = onig_node_new_alt(NULL_NODE, NULL_NODE);
3524 if (IS_NULL(var_anode))
return ONIGERR_MEMORY;
3526 xnode = onig_node_new_list(NULL, NULL);
3527 if (IS_NULL(xnode))
goto mem_err;
3528 NCAR(var_anode) = xnode;
3530 anode = onig_node_new_alt(NULL_NODE, NULL_NODE);
3531 if (IS_NULL(anode))
goto mem_err;
3532 NCAR(xnode) = anode;
3535 *rnode = anode = onig_node_new_alt(NULL_NODE, NULL_NODE);
3536 if (IS_NULL(anode))
return ONIGERR_MEMORY;
3539 snode = onig_node_new_str(p, p + slen);
3540 if (IS_NULL(snode))
goto mem_err;
3542 NCAR(anode) = snode;
3544 for (i = 0; i < item_num; i++) {
3545 snode = onig_node_new_str(NULL, NULL);
3546 if (IS_NULL(snode))
goto mem_err;
3548 for (j = 0; j < items[i].code_len; j++) {
3549 len = ONIGENC_CODE_TO_MBC(reg->enc, items[i].code[j], buf);
3555 r = onig_node_str_cat(snode, buf, buf +
len);
3556 if (r != 0)
goto mem_err2;
3559 an = onig_node_new_alt(NULL_NODE, NULL_NODE);
3564 if (items[i].byte_len != slen) {
3566 UChar *q = p + items[i].byte_len;
3569 r = expand_case_fold_make_rem_string(&rem, q, end, reg);
3575 xnode = onig_node_list_add(NULL_NODE, snode);
3576 if (IS_NULL(xnode)) {
3578 onig_node_free(rem);
3581 if (IS_NULL(onig_node_list_add(xnode, rem))) {
3583 onig_node_free(xnode);
3584 onig_node_free(rem);
3594 NCDR(var_anode) = an;
3607 onig_node_free(snode);
3610 onig_node_free(*rnode);
3612 return ONIGERR_MEMORY;
3615#define THRESHOLD_CASE_FOLD_ALT_FOR_EXPANSION 8
3618expand_case_fold_string(
Node* node,
regex_t* reg,
int state)
3620 int r, n,
len, alt_num;
3622 int is_in_look_behind;
3623 UChar *start, *end, *p;
3624 Node *top_root, *root, *snode, *prev_node;
3628 if (NSTRING_IS_AMBIG(node))
return 0;
3634 if (start >= end)
return 0;
3636 is_in_look_behind = (state & IN_LOOK_BEHIND) != 0;
3639 top_root = root = prev_node = snode = NULL_NODE;
3643 n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(reg->enc, reg->case_fold_flag,
3650 len = enclen(reg->enc, p, end);
3652 varlen = is_case_fold_variable_len(n, items,
len);
3653 if (n == 0 || varlen == 0 || is_in_look_behind) {
3654 if (IS_NULL(snode)) {
3655 if (IS_NULL(root) && IS_NOT_NULL(prev_node)) {
3656 onig_node_free(top_root);
3657 top_root = root = onig_node_list_add(NULL_NODE, prev_node);
3658 if (IS_NULL(root)) {
3659 onig_node_free(prev_node);
3664 prev_node = snode = onig_node_new_str(NULL, NULL);
3665 if (IS_NULL(snode))
goto mem_err;
3666 if (IS_NOT_NULL(root)) {
3667 if (IS_NULL(onig_node_list_add(root, snode))) {
3668 onig_node_free(snode);
3674 r = onig_node_str_cat(snode, p, p +
len);
3675 if (r != 0)
goto err;
3679 if (alt_num > THRESHOLD_CASE_FOLD_ALT_FOR_EXPANSION)
break;
3681 if (IS_NOT_NULL(snode)) {
3682 r = update_string_node_case_fold(reg, snode);
3684 NSTRING_SET_AMBIG(snode);
3687 if (IS_NULL(root) && IS_NOT_NULL(prev_node)) {
3688 onig_node_free(top_root);
3689 top_root = root = onig_node_list_add(NULL_NODE, prev_node);
3690 if (IS_NULL(root)) {
3691 onig_node_free(prev_node);
3696 r = expand_case_fold_string_alt(n, items, p,
len, end, reg, &prev_node);
3697 if (r < 0)
goto mem_err;
3699 if (IS_NULL(root)) {
3700 top_root = prev_node;
3703 if (IS_NULL(onig_node_list_add(root, prev_node))) {
3704 onig_node_free(prev_node);
3709 root = NCAR(prev_node);
3712 if (IS_NOT_NULL(root)) {
3713 if (IS_NULL(onig_node_list_add(root, prev_node))) {
3714 onig_node_free(prev_node);
3725 if (IS_NOT_NULL(snode)) {
3726 r = update_string_node_case_fold(reg, snode);
3728 NSTRING_SET_AMBIG(snode);
3735 r = expand_case_fold_make_rem_string(&srem, p, end, reg);
3736 if (r != 0)
goto mem_err;
3738 if (IS_NOT_NULL(prev_node) && IS_NULL(root)) {
3739 onig_node_free(top_root);
3740 top_root = root = onig_node_list_add(NULL_NODE, prev_node);
3741 if (IS_NULL(root)) {
3742 onig_node_free(srem);
3743 onig_node_free(prev_node);
3748 if (IS_NULL(root)) {
3752 if (IS_NULL(onig_node_list_add(root, srem))) {
3753 onig_node_free(srem);
3760 top_root = (IS_NOT_NULL(top_root) ? top_root : prev_node);
3761 swap_node(node, top_root);
3762 onig_node_free(top_root);
3769 onig_node_free(top_root);
3774#ifdef USE_COMBINATION_EXPLOSION_CHECK
3776# define CEC_THRES_NUM_BIG_REPEAT 512
3777# define CEC_INFINITE_NUM 0x7fffffff
3779# define CEC_IN_INFINITE_REPEAT (1<<0)
3780# define CEC_IN_FINITE_REPEAT (1<<1)
3781# define CEC_CONT_BIG_REPEAT (1<<2)
3784setup_comb_exp_check(
Node* node,
int state,
ScanEnv* env)
3794 r = setup_comb_exp_check(NCAR(node), r, env);
3795 }
while (r >= 0 && IS_NOT_NULL(node = NCDR(node)));
3803 ret = setup_comb_exp_check(NCAR(node), state, env);
3805 }
while (ret >= 0 && IS_NOT_NULL(node = NCDR(node)));
3811 int child_state = state;
3814 Node* target = qn->target;
3817 if (! IS_REPEAT_INFINITE(qn->upper)) {
3818 if (qn->upper > 1) {
3820 child_state |= CEC_IN_FINITE_REPEAT;
3823 if (env->backrefed_mem == 0) {
3824 if (NTYPE(qn->target) == NT_ENCLOSE) {
3826 if (en->type == ENCLOSE_MEMORY) {
3827 if (NTYPE(en->target) == NT_QTFR) {
3829 if (IS_REPEAT_INFINITE(q->upper)
3830 && q->greedy == qn->greedy) {
3831 qn->upper = (qn->lower == 0 ? 1 : qn->lower);
3833 child_state = state;
3842 if (state & CEC_IN_FINITE_REPEAT) {
3843 qn->comb_exp_check_num = -1;
3846 if (IS_REPEAT_INFINITE(qn->upper)) {
3847 var_num = CEC_INFINITE_NUM;
3848 child_state |= CEC_IN_INFINITE_REPEAT;
3851 var_num = qn->upper - qn->lower;
3854 if (var_num >= CEC_THRES_NUM_BIG_REPEAT)
3855 add_state |= CEC_CONT_BIG_REPEAT;
3857 if (((state & CEC_IN_INFINITE_REPEAT) != 0 && var_num != 0) ||
3858 ((state & CEC_CONT_BIG_REPEAT) != 0 &&
3859 var_num >= CEC_THRES_NUM_BIG_REPEAT)) {
3860 if (qn->comb_exp_check_num == 0) {
3861 env->num_comb_exp_check++;
3862 qn->comb_exp_check_num = env->num_comb_exp_check;
3863 if (env->curr_max_regnum > env->comb_exp_max_regnum)
3864 env->comb_exp_max_regnum = env->curr_max_regnum;
3869 r = setup_comb_exp_check(target, child_state, env);
3879 case ENCLOSE_MEMORY:
3881 if (env->curr_max_regnum < en->regnum)
3882 env->curr_max_regnum = en->regnum;
3884 r = setup_comb_exp_check(en->target, state, env);
3889 r = setup_comb_exp_check(en->target, state, env);
3895# ifdef USE_SUBEXP_CALL
3897 if (IS_CALL_RECURSION(NCALL(node)))
3898 env->has_recursion = 1;
3900 r = setup_comb_exp_check(NCALL(node)->target, state, env);
3931 Node* prev = NULL_NODE;
3933 r = setup_tree(NCAR(node), reg, state, env);
3934 if (IS_NOT_NULL(prev) && r == 0) {
3935 r = next_setup(prev, NCAR(node), reg);
3938 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
3944 r = setup_tree(NCAR(node), reg, (state | IN_ALT), env);
3945 }
while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
3952 if (IS_IGNORECASE(reg->options) && !NSTRING_IS_RAW(node)) {
3953 r = expand_case_fold_string(node, reg, state);
3961#ifdef USE_SUBEXP_CALL
3970 Node** nodes = SCANENV_MEM_NODES(env);
3973 for (i = 0; i < br->back_num; i++) {
3974 if (p[i] > env->num_mem)
return ONIGERR_INVALID_BACKREF;
3975 BIT_STATUS_ON_AT(env->backrefed_mem, p[i]);
3976 BIT_STATUS_ON_AT(env->bt_mem_start, p[i]);
3977#ifdef USE_BACKREF_WITH_LEVEL
3978 if (IS_BACKREF_NEST_LEVEL(br)) {
3979 BIT_STATUS_ON_AT(env->bt_mem_end, p[i]);
3982 SET_ENCLOSE_STATUS(nodes[p[i]], NST_MEM_BACKREFED);
3991 Node* target = qn->target;
3993 if ((state & IN_REPEAT) != 0) {
3994 qn->state |= NST_IN_REPEAT;
3997 if (IS_REPEAT_INFINITE(qn->upper) || qn->upper >= 1) {
3998 r = get_min_match_length(target, &d, env);
4001 qn->target_empty_info = NQ_TARGET_IS_EMPTY;
4002#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
4003 r = quantifiers_memory_node_info(target);
4006 qn->target_empty_info = r;
4010 r = get_max_match_length(target, &d, env);
4011 if (r == 0 && d == 0) {
4014 if (qn->lower > 1) qn->lower = 1;
4015 if (NTYPE(target) == NT_STR) {
4016 qn->upper = qn->lower = 0;
4024 if (qn->lower != qn->upper)
4025 state |= IN_VAR_REPEAT;
4026 r = setup_tree(target, reg, state, env);
4030#define EXPAND_STRING_MAX_LENGTH 100
4031 if (NTYPE(target) == NT_STR) {
4032 if (qn->lower > 1) {
4033 int i, n = qn->lower;
4034 OnigDistance
len = NSTRING_LEN(target);
4038 np = onig_node_new_str(sn->s, sn->end);
4039 if (IS_NULL(np))
return ONIGERR_MEMORY;
4040 NSTR(np)->flag = sn->flag;
4042 for (i = 1; i < n && (i+1) *
len <= EXPAND_STRING_MAX_LENGTH; i++) {
4043 r = onig_node_str_cat(np, sn->s, sn->end);
4049 if (i < qn->upper || IS_REPEAT_INFINITE(qn->upper)) {
4053 if (! IS_REPEAT_INFINITE(qn->upper))
4056 np1 = onig_node_new_list(np, NULL);
4059 return ONIGERR_MEMORY;
4061 swap_node(np1, node);
4062 np2 = onig_node_list_add(node, np1);
4064 onig_node_free(np1);
4065 return ONIGERR_MEMORY;
4069 swap_node(np, node);
4076#ifdef USE_OP_PUSH_OR_JUMP_EXACT
4077 if (qn->greedy && (qn->target_empty_info != 0)) {
4078 if (NTYPE(target) == NT_QTFR) {
4080 if (IS_NOT_NULL(tqn->head_exact)) {
4081 qn->head_exact = tqn->head_exact;
4082 tqn->head_exact = NULL;
4086 qn->head_exact = get_head_value_node(qn->target, 1, reg);
4098 case ENCLOSE_OPTION:
4100 OnigOptionType options = reg->options;
4101 reg->options = NENCLOSE(node)->option;
4102 r = setup_tree(NENCLOSE(node)->target, reg, state, env);
4103 reg->options = options;
4107 case ENCLOSE_MEMORY:
4108 if ((state & (IN_ALT | IN_NOT | IN_VAR_REPEAT | IN_CALL)) != 0) {
4109 BIT_STATUS_ON_AT(env->bt_mem_start, en->regnum);
4112 if (IS_ENCLOSE_CALLED(en))
4114 if (IS_ENCLOSE_RECURSION(en))
4115 state |= IN_RECCALL;
4116 else if ((state & IN_RECCALL) != 0)
4117 SET_CALL_RECURSION(node);
4118 r = setup_tree(en->target, reg, state, env);
4121 case ENCLOSE_STOP_BACKTRACK:
4123 Node* target = en->target;
4124 r = setup_tree(target, reg, state, env);
4125 if (NTYPE(target) == NT_QTFR) {
4127 if (IS_REPEAT_INFINITE(tqn->upper) && tqn->lower <= 1 &&
4129 int qtype = NTYPE(tqn->target);
4130 if (IS_NODE_TYPE_SIMPLE(qtype))
4131 SET_ENCLOSE_STATUS(node, NST_STOP_BT_SIMPLE_REPEAT);
4137 case ENCLOSE_CONDITION:
4138#ifdef USE_NAMED_GROUP
4139 if (! IS_ENCLOSE_NAME_REF(NENCLOSE(node)) &&
4140 env->num_named > 0 &&
4141 IS_SYNTAX_BV(env->syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
4142 !ONIG_IS_OPTION_ON(env->option, ONIG_OPTION_CAPTURE_GROUP)) {
4143 return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
4146 if (NENCLOSE(node)->regnum > env->num_mem)
4147 return ONIGERR_INVALID_BACKREF;
4148 r = setup_tree(NENCLOSE(node)->target, reg, state, env);
4151 case ENCLOSE_ABSENT:
4152 r = setup_tree(NENCLOSE(node)->target, reg, state, env);
4163 case ANCHOR_PREC_READ:
4164 r = setup_tree(an->target, reg, state, env);
4166 case ANCHOR_PREC_READ_NOT:
4167 r = setup_tree(an->target, reg, (state | IN_NOT), env);
4171#define ALLOWED_TYPE_IN_LB \
4172 ( BIT_NT_LIST | BIT_NT_ALT | BIT_NT_STR | BIT_NT_CCLASS | BIT_NT_CTYPE | \
4173 BIT_NT_CANY | BIT_NT_ANCHOR | BIT_NT_ENCLOSE | BIT_NT_QTFR | BIT_NT_CALL )
4175#define ALLOWED_ENCLOSE_IN_LB ( ENCLOSE_MEMORY | ENCLOSE_OPTION )
4176#define ALLOWED_ENCLOSE_IN_LB_NOT ENCLOSE_OPTION
4178#define ALLOWED_ANCHOR_IN_LB \
4179( ANCHOR_LOOK_BEHIND | ANCHOR_LOOK_BEHIND_NOT | ANCHOR_BEGIN_LINE | \
4180 ANCHOR_END_LINE | ANCHOR_BEGIN_BUF | ANCHOR_BEGIN_POSITION | ANCHOR_KEEP | \
4181 ANCHOR_WORD_BOUND | ANCHOR_NOT_WORD_BOUND | \
4182 ANCHOR_WORD_BEGIN | ANCHOR_WORD_END )
4183#define ALLOWED_ANCHOR_IN_LB_NOT \
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 )
4189 case ANCHOR_LOOK_BEHIND:
4191 r = check_type_tree(an->target, ALLOWED_TYPE_IN_LB,
4192 ALLOWED_ENCLOSE_IN_LB, ALLOWED_ANCHOR_IN_LB);
4193 if (r < 0)
return r;
4194 if (r > 0)
return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
4195 if (NTYPE(node) != NT_ANCHOR)
goto restart;
4196 r = setup_tree(an->target, reg, (state | IN_LOOK_BEHIND), env);
4197 if (r != 0)
return r;
4198 r = setup_look_behind(node, reg, env);
4202 case ANCHOR_LOOK_BEHIND_NOT:
4204 r = check_type_tree(an->target, ALLOWED_TYPE_IN_LB,
4205 ALLOWED_ENCLOSE_IN_LB_NOT, ALLOWED_ANCHOR_IN_LB_NOT);
4206 if (r < 0)
return r;
4207 if (r > 0)
return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
4208 if (NTYPE(node) != NT_ANCHOR)
goto restart;
4209 r = setup_tree(an->target, reg, (state | IN_NOT | IN_LOOK_BEHIND),
4211 if (r != 0)
return r;
4212 r = setup_look_behind(node, reg, env);
4228set_bm_skip(UChar* s, UChar* end,
regex_t* reg,
4229 UChar skip[],
int ignore_case)
4231 OnigDistance i,
len;
4232 int clen, flen, n, j, k;
4233 UChar *p, buf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
4238 if (
len >= ONIG_CHAR_TABLE_SIZE) {
4240 return ONIGERR_TYPE_BUG;
4244 for (i = 0; i <
len; i += clen) {
4246 n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
4248 clen = enclen(enc, p, end);
4250 clen = (int )(end - p);
4252 for (j = 0; j < n; j++) {
4253 if ((items[j].code_len != 1) || (items[j].byte_len != clen)) {
4258 flen = ONIGENC_CODE_TO_MBC(enc, items[j].code[0], buf);
4270 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
4271 skip[i] = (UChar )(
len + 1);
4273 for (i = 0; i <
len; i += clen) {
4276 n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
4278 clen = enclen(enc, p, end);
4280 clen = (int )(end - p);
4282 for (j = 0; j < clen; j++) {
4283 skip[s[i + j]] = (UChar )(
len - i - j);
4284 for (k = 0; k < n; k++) {
4285 ONIGENC_CODE_TO_MBC(enc, items[k].code[0], buf);
4286 skip[buf[j]] = (UChar )(
len - i - j);
4302 OnigOptionType options;
4303 OnigCaseFoldType case_fold_flag;
4319 UChar s[OPT_EXACT_MAXLEN];
4327 UChar map[ONIG_CHAR_TABLE_SIZE];
4345 static const short int ByteValTable[] = {
4346 5, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10, 1, 1, 10, 1, 1,
4347 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4348 12, 4, 7, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5,
4349 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5,
4350 5, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
4351 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 5, 5, 5,
4352 5, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
4353 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 1
4356 if (i < numberof(ByteValTable)) {
4357 if (i == 0 && ONIGENC_MBC_MINLEN(enc) > 1)
4360 return (
int )ByteValTable[i];
4370 static const short int dist_vals[] = {
4371 1000, 500, 333, 250, 200, 167, 143, 125, 111, 100,
4372 91, 83, 77, 71, 67, 63, 59, 56, 53, 50,
4373 48, 45, 43, 42, 40, 38, 37, 36, 34, 33,
4374 32, 31, 30, 29, 29, 28, 27, 26, 26, 25,
4375 24, 24, 23, 23, 22, 22, 21, 21, 20, 20,
4376 20, 19, 19, 19, 18, 18, 18, 17, 17, 17,
4377 16, 16, 16, 16, 15, 15, 15, 15, 14, 14,
4378 14, 14, 14, 14, 13, 13, 13, 13, 13, 13,
4379 12, 12, 12, 12, 12, 12, 11, 11, 11, 11,
4380 11, 11, 11, 11, 11, 10, 10, 10, 10, 10
4385 if (mm->max == ONIG_INFINITE_DISTANCE)
return 0;
4387 d = mm->max - mm->min;
4388 if (d < numberof(dist_vals))
4390 return (
int )dist_vals[d];
4398 if (v2 <= 0)
return -1;
4399 if (v1 <= 0)
return 1;
4401 v1 *= distance_value(d1);
4402 v2 *= distance_value(d2);
4404 if (v2 > v1)
return 1;
4405 if (v2 < v1)
return -1;
4407 if (d2->min < d1->min)
return 1;
4408 if (d2->min > d1->min)
return -1;
4415 return (a->min == b->min && a->max == b->max) ? 1 : 0;
4420set_mml(
MinMaxLen* mml, OnigDistance min, OnigDistance max)
4429 mml->min = mml->max = 0;
4435 to->min = from->min;
4436 to->max = from->max;
4442 to->min = distance_add(to->min, from->min);
4443 to->max = distance_add(to->max, from->max);
4450 to->min = distance_add(to->min,
len);
4451 to->max = distance_add(to->max,
len);
4458 if (to->min > from->min) to->min = from->min;
4459 if (to->max < from->max) to->max = from->max;
4471 anc->left_anchor = 0;
4472 anc->right_anchor = 0;
4483 OnigDistance left_len, OnigDistance right_len)
4485 clear_opt_anc_info(to);
4487 to->left_anchor = left->left_anchor;
4488 if (left_len == 0) {
4489 to->left_anchor |= right->left_anchor;
4492 to->right_anchor = right->right_anchor;
4493 if (right_len == 0) {
4494 to->right_anchor |= left->right_anchor;
4497 to->right_anchor |= (left->right_anchor & ANCHOR_PREC_READ_NOT);
4502is_left_anchor(
int anc)
4504 if (anc == ANCHOR_END_BUF || anc == ANCHOR_SEMI_END_BUF ||
4505 anc == ANCHOR_END_LINE || anc == ANCHOR_PREC_READ ||
4506 anc == ANCHOR_PREC_READ_NOT)
4515 if ((to->left_anchor & anc) != 0)
return 1;
4517 return ((to->right_anchor & anc) != 0 ? 1 : 0);
4523 if (is_left_anchor(anc))
4524 to->left_anchor |= anc;
4526 to->right_anchor |= anc;
4532 if (is_left_anchor(anc))
4533 to->left_anchor &= ~anc;
4535 to->right_anchor &= ~anc;
4541 to->left_anchor &= add->left_anchor;
4542 to->right_anchor &= add->right_anchor;
4548 return (ex->len >= OPT_EXACT_MAXLEN ? 1 : 0);
4554 clear_mml(&ex->mmd);
4555 clear_opt_anc_info(&ex->anc);
4557 ex->ignore_case = -1;
4575 if (to->ignore_case < 0)
4576 to->ignore_case = add->ignore_case;
4577 else if (to->ignore_case != add->ignore_case)
4582 for (i = to->len; p < end; ) {
4583 len = enclen(enc, p, end);
4584 if (i +
len > OPT_EXACT_MAXLEN)
break;
4585 for (j = 0; j <
len && p < end; j++)
4590 to->reach_end = (p == end ? add->reach_end : 0);
4592 concat_opt_anc_info(&tanc, &to->anc, &add->anc, 1, 1);
4593 if (! to->reach_end) tanc.right_anchor = 0;
4594 copy_opt_anc_info(&to->anc, &tanc);
4598concat_opt_exact_info_str(
OptExactInfo* to, UChar* s, UChar* end,
4604 for (i = to->len, p = s; p < end && i < OPT_EXACT_MAXLEN; ) {
4605 len = enclen(enc, p, end);
4606 if (i +
len > OPT_EXACT_MAXLEN)
break;
4607 for (j = 0; j <
len && p < end; j++)
4619 if (add->len == 0 || to->len == 0) {
4620 clear_opt_exact_info(to);
4624 if (! is_equal_mml(&to->mmd, &add->mmd)) {
4625 clear_opt_exact_info(to);
4629 for (i = 0; i < to->len && i < add->len; ) {
4630 if (to->s[i] != add->s[i])
break;
4631 len = enclen(env->enc, to->s + i, to->s + to->len);
4633 for (j = 1; j <
len; j++) {
4634 if (to->s[i+j] != add->s[i+j])
break;
4640 if (! add->reach_end || i < add->
len || i < to->
len) {
4644 if (to->ignore_case < 0)
4645 to->ignore_case = add->ignore_case;
4646 else if (add->ignore_case >= 0)
4647 to->ignore_case |= add->ignore_case;
4649 alt_merge_opt_anc_info(&to->anc, &add->anc);
4650 if (! to->reach_end) to->anc.right_anchor = 0;
4665 copy_opt_exact_info(now, alt);
4668 else if (v1 <= 2 && v2 <= 2) {
4670 v2 = map_position_value(enc, now->s[0]);
4671 v1 = map_position_value(enc, alt->s[0]);
4673 if (now->len > 1) v1 += 5;
4674 if (alt->len > 1) v2 += 5;
4677 if (now->ignore_case <= 0) v1 *= 2;
4678 if (alt->ignore_case <= 0) v2 *= 2;
4680 if (comp_distance_value(&now->mmd, &alt->mmd, v1, v2) > 0)
4681 copy_opt_exact_info(now, alt);
4690 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4691 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4692 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4693 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4694 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
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
4709 xmemcpy(map, &clean_info,
sizeof(
OptMapInfo));
4721 if (map->map[c] == 0) {
4723 map->value += map_position_value(enc, c);
4728add_char_amb_opt_map_info(
OptMapInfo* map, UChar* p, UChar* end,
4732 UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
4735 add_char_opt_map_info(map, p[0], enc);
4737 case_fold_flag = DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag);
4738 n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, case_fold_flag, p, end, items);
4739 if (n < 0)
return n;
4741 for (i = 0; i < n; i++) {
4742 ONIGENC_CODE_TO_MBC(enc, items[i].code[0], buf);
4743 add_char_opt_map_info(map, buf[0], enc);
4752 const int z = 1<<15;
4756 if (alt->value == 0) return ;
4757 if (now->value == 0) {
4758 copy_opt_map_info(now, alt);
4762 v1 = z / now->value;
4763 v2 = z / alt->value;
4764 if (comp_distance_value(&now->mmd, &alt->mmd, v1, v2) > 0)
4765 copy_opt_map_info(now, alt);
4771#define COMP_EM_BASE 20
4774 if (m->value <= 0)
return -1;
4776 ve = COMP_EM_BASE * e->len * (e->ignore_case > 0 ? 1 : 2);
4777 vm = COMP_EM_BASE * 5 * 2 / m->value;
4778 return comp_distance_value(&e->mmd, &m->mmd, ve, vm);
4787 if (to->value == 0) return ;
4788 if (add->value == 0 || to->mmd.max < add->mmd.min) {
4789 clear_opt_map_info(to);
4793 alt_merge_mml(&to->mmd, &add->mmd);
4796 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) {
4801 val += map_position_value(enc, i);
4805 alt_merge_opt_anc_info(&to->anc, &add->anc);
4811 copy_mml(&(opt->exb.mmd), mmd);
4812 copy_mml(&(opt->expr.mmd), mmd);
4813 copy_mml(&(opt->map.mmd), mmd);
4819 clear_mml(&opt->len);
4820 clear_opt_anc_info(&opt->anc);
4821 clear_opt_exact_info(&opt->exb);
4822 clear_opt_exact_info(&opt->exm);
4823 clear_opt_exact_info(&opt->expr);
4824 clear_opt_map_info(&opt->map);
4836 int exb_reach, exm_reach;
4839 concat_opt_anc_info(&tanc, &to->anc, &add->anc, to->len.max, add->len.max);
4840 copy_opt_anc_info(&to->anc, &tanc);
4842 if (add->exb.len > 0 && to->len.max == 0) {
4843 concat_opt_anc_info(&tanc, &to->anc, &add->exb.anc,
4844 to->len.max, add->len.max);
4845 copy_opt_anc_info(&add->exb.anc, &tanc);
4848 if (add->map.value > 0 && to->len.max == 0) {
4849 if (add->map.mmd.max == 0)
4850 add->map.anc.left_anchor |= to->anc.left_anchor;
4853 exb_reach = to->exb.reach_end;
4854 exm_reach = to->exm.reach_end;
4856 if (add->len.max != 0)
4857 to->exb.reach_end = to->exm.reach_end = 0;
4859 if (add->exb.len > 0) {
4861 concat_opt_exact_info(&to->exb, &add->exb, enc);
4862 clear_opt_exact_info(&add->exb);
4864 else if (exm_reach) {
4865 concat_opt_exact_info(&to->exm, &add->exb, enc);
4866 clear_opt_exact_info(&add->exb);
4869 select_opt_exact_info(enc, &to->exm, &add->exb);
4870 select_opt_exact_info(enc, &to->exm, &add->exm);
4872 if (to->expr.len > 0) {
4873 if (add->len.max > 0) {
4874 if (to->expr.len > (
int )add->len.max)
4875 to->expr.len = (int )add->len.max;
4877 if (to->expr.mmd.max == 0)
4878 select_opt_exact_info(enc, &to->exb, &to->expr);
4880 select_opt_exact_info(enc, &to->exm, &to->expr);
4883 else if (add->expr.len > 0) {
4884 copy_opt_exact_info(&to->expr, &add->expr);
4887 select_opt_map_info(&to->map, &add->map);
4889 add_mml(&to->len, &add->len);
4895 alt_merge_opt_anc_info (&to->anc, &add->anc);
4896 alt_merge_opt_exact_info(&to->exb, &add->exb, env);
4897 alt_merge_opt_exact_info(&to->exm, &add->exm, env);
4898 alt_merge_opt_exact_info(&to->expr, &add->expr, env);
4899 alt_merge_opt_map_info(env->enc, &to->map, &add->map);
4901 alt_merge_mml(&to->len, &add->len);
4905#define MAX_NODE_OPT_INFO_REF_COUNT 5
4913 clear_node_opt_info(opt);
4914 set_bound_node_opt_info(opt, &env->mmd);
4924 copy_opt_env(&nenv, env);
4926 r = optimize_node_left(NCAR(nd), &nopt, &nenv);
4928 add_mml(&nenv.mmd, &nopt.len);
4929 concat_left_node_opt_info(env->enc, opt, &nopt);
4931 }
while (r == 0 && IS_NOT_NULL(nd = NCDR(nd)));
4941 r = optimize_node_left(NCAR(nd), &nopt, env);
4943 if (nd == node) copy_node_opt_info(opt, &nopt);
4944 else alt_merge_node_opt_info(opt, &nopt, env);
4946 }
while ((r == 0) && IS_NOT_NULL(nd = NCDR(nd)));
4953 OnigDistance slen = sn->end - sn->s;
4954 int is_raw = NSTRING_IS_RAW(node);
4956 if (! NSTRING_IS_AMBIG(node)) {
4957 concat_opt_exact_info_str(&opt->exb, sn->s, sn->end,
4959 opt->exb.ignore_case = 0;
4961 add_char_opt_map_info(&opt->map, *(sn->s), env->enc);
4963 set_mml(&opt->len, slen, slen);
4968 if (NSTRING_IS_DONT_GET_OPT_INFO(node)) {
4969 int n = onigenc_strlen(env->enc, sn->s, sn->end);
4970 max = (OnigDistance )ONIGENC_MBC_MAXLEN_DIST(env->enc) * (OnigDistance)n;
4973 concat_opt_exact_info_str(&opt->exb, sn->s, sn->end,
4975 opt->exb.ignore_case = 1;
4978 r = add_char_amb_opt_map_info(&opt->map, sn->s, sn->end,
4979 env->enc, env->case_fold_flag);
4986 set_mml(&opt->len, slen, max);
4989 if ((OnigDistance )opt->exb.len == slen)
4990 opt->exb.reach_end = 1;
5001 if (IS_NOT_NULL(cc->mbuf) || IS_NCCLASS_NOT(cc)) {
5002 OnigDistance min = ONIGENC_MBC_MINLEN(env->enc);
5003 OnigDistance max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
5005 set_mml(&opt->len, min, max);
5008 for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
5009 z = BITSET_AT(cc->bs, i);
5010 if ((z && !IS_NCCLASS_NOT(cc)) || (!z && IS_NCCLASS_NOT(cc))) {
5011 add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
5014 set_mml(&opt->len, 1, 1);
5024 max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
5029 maxcode = NCTYPE(node)->ascii_range ? 0x80 : SINGLE_BYTE_SIZE;
5030 switch (NCTYPE(node)->ctype) {
5031 case ONIGENC_CTYPE_WORD:
5032 if (NCTYPE(node)->not != 0) {
5033 for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
5034 if (! ONIGENC_IS_CODE_WORD(env->enc, i) || i >= maxcode) {
5035 add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
5040 for (i = 0; i < maxcode; i++) {
5041 if (ONIGENC_IS_CODE_WORD(env->enc, i)) {
5042 add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
5050 min = ONIGENC_MBC_MINLEN(env->enc);
5052 set_mml(&opt->len, min, max);
5058 OnigDistance min = ONIGENC_MBC_MINLEN(env->enc);
5059 OnigDistance max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
5060 set_mml(&opt->len, min, max);
5065 switch (NANCHOR(node)->type) {
5066 case ANCHOR_BEGIN_BUF:
5067 case ANCHOR_BEGIN_POSITION:
5068 case ANCHOR_BEGIN_LINE:
5069 case ANCHOR_END_BUF:
5070 case ANCHOR_SEMI_END_BUF:
5071 case ANCHOR_END_LINE:
5072 case ANCHOR_LOOK_BEHIND:
5073 case ANCHOR_PREC_READ_NOT:
5074 add_opt_anc_info(&opt->anc, NANCHOR(node)->type);
5077 case ANCHOR_PREC_READ:
5081 r = optimize_node_left(NANCHOR(node)->target, &nopt, env);
5083 if (nopt.exb.len > 0)
5084 copy_opt_exact_info(&opt->expr, &nopt.exb);
5085 else if (nopt.exm.len > 0)
5086 copy_opt_exact_info(&opt->expr, &nopt.exm);
5088 opt->expr.reach_end = 0;
5090 if (nopt.map.value > 0)
5091 copy_opt_map_info(&opt->map, &nopt.map);
5096 case ANCHOR_LOOK_BEHIND_NOT:
5105 OnigDistance min, max, tmin, tmax;
5106 Node** nodes = SCANENV_MEM_NODES(env->scan_env);
5109 if (br->state & NST_RECURSION) {
5110 set_mml(&opt->len, 0, ONIG_INFINITE_DISTANCE);
5113 backs = BACKREFS_P(br);
5114 r = get_min_match_length(nodes[backs[0]], &min, env->scan_env);
5116 r = get_max_match_length(nodes[backs[0]], &max, env->scan_env);
5118 for (i = 1; i < br->back_num; i++) {
5119 r = get_min_match_length(nodes[backs[i]], &tmin, env->scan_env);
5121 r = get_max_match_length(nodes[backs[i]], &tmax, env->scan_env);
5123 if (min > tmin) min = tmin;
5124 if (max < tmax) max = tmax;
5126 if (r == 0) set_mml(&opt->len, min, max);
5130#ifdef USE_SUBEXP_CALL
5132 if (IS_CALL_RECURSION(NCALL(node)))
5133 set_mml(&opt->len, 0, ONIG_INFINITE_DISTANCE);
5135 OnigOptionType save = env->options;
5136 env->options = NENCLOSE(NCALL(node)->target)->option;
5137 r = optimize_node_left(NCALL(node)->target, opt, env);
5138 env->options = save;
5146 OnigDistance min, max;
5150 r = optimize_node_left(qn->target, &nopt, env);
5153 if (qn->lower == 0 && IS_REPEAT_INFINITE(qn->upper)) {
5154 if (env->mmd.max == 0 &&
5155 NTYPE(qn->target) == NT_CANY && qn->greedy) {
5156 if (IS_MULTILINE(env->options))
5158 add_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR_ML);
5160 add_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR);
5164 if (qn->lower > 0) {
5165 copy_node_opt_info(opt, &nopt);
5166 if (nopt.exb.len > 0) {
5167 if (nopt.exb.reach_end) {
5168 for (i = 2; i <= qn->lower &&
5169 ! is_full_opt_exact_info(&opt->exb); i++) {
5170 concat_opt_exact_info(&opt->exb, &nopt.exb, env->enc);
5172 if (i < qn->lower) {
5173 opt->exb.reach_end = 0;
5178 if (qn->lower != qn->upper) {
5179 opt->exb.reach_end = 0;
5180 opt->exm.reach_end = 0;
5183 opt->exm.reach_end = 0;
5187 min = distance_multiply(nopt.len.min, qn->lower);
5188 if (IS_REPEAT_INFINITE(qn->upper))
5189 max = (nopt.len.max > 0 ? ONIG_INFINITE_DISTANCE : 0);
5191 max = distance_multiply(nopt.len.max, qn->upper);
5193 set_mml(&opt->len, min, max);
5202 case ENCLOSE_OPTION:
5204 OnigOptionType save = env->options;
5206 env->options = en->option;
5207 r = optimize_node_left(en->target, opt, env);
5208 env->options = save;
5212 case ENCLOSE_MEMORY:
5213#ifdef USE_SUBEXP_CALL
5215 if (en->opt_count > MAX_NODE_OPT_INFO_REF_COUNT) {
5216 OnigDistance min, max;
5219 max = ONIG_INFINITE_DISTANCE;
5220 if (IS_ENCLOSE_MIN_FIXED(en)) min = en->min_len;
5221 if (IS_ENCLOSE_MAX_FIXED(en)) max = en->max_len;
5222 set_mml(&opt->len, min, max);
5227 r = optimize_node_left(en->target, opt, env);
5229 if (is_set_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR_MASK)) {
5230 if (BIT_STATUS_AT(env->scan_env->backrefed_mem, en->regnum))
5231 remove_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR_MASK);
5236 case ENCLOSE_STOP_BACKTRACK:
5237 case ENCLOSE_CONDITION:
5238 r = optimize_node_left(en->target, opt, env);
5241 case ENCLOSE_ABSENT:
5242 set_mml(&opt->len, 0, ONIG_INFINITE_DISTANCE);
5250 fprintf(stderr,
"optimize_node_left: undefined node type %d\n",
5253 r = ONIGERR_TYPE_BUG;
5265 if (e->len == 0)
return 0;
5267 reg->exact = (UChar* )
xmalloc(e->len);
5268 CHECK_NULL_RETURN_MEMERR(reg->exact);
5269 xmemcpy(reg->exact, e->s, e->len);
5270 reg->exact_end = reg->exact + e->len;
5273 ONIGENC_IS_ALLOWED_REVERSE_MATCH(reg->enc, reg->exact, reg->exact_end);
5275 if (e->ignore_case > 0) {
5276 if (e->len >= 3 || (e->len >= 2 && allow_reverse)) {
5277 int orig_len = e->len;
5278 e->len = set_bm_skip(reg->exact, reg->exact_end, reg,
5281 reg->exact_end = reg->exact + e->len;
5282 reg->optimize = (allow_reverse != 0
5283 ? ONIG_OPTIMIZE_EXACT_BM_IC : ONIG_OPTIMIZE_EXACT_BM_NOT_REV_IC);
5293 reg->optimize = ONIG_OPTIMIZE_EXACT_IC;
5297 reg->optimize = ONIG_OPTIMIZE_EXACT_IC;
5301 if (e->len >= 3 || (e->len >= 2 && allow_reverse)) {
5302 set_bm_skip(reg->exact, reg->exact_end, reg,
5304 reg->optimize = (allow_reverse != 0
5305 ? ONIG_OPTIMIZE_EXACT_BM : ONIG_OPTIMIZE_EXACT_BM_NOT_REV);
5308 reg->optimize = ONIG_OPTIMIZE_EXACT;
5312 reg->dmin = e->mmd.min;
5313 reg->dmax = e->mmd.max;
5315 if (reg->dmin != ONIG_INFINITE_DISTANCE) {
5316 reg->threshold_len = (int )(reg->dmin + (reg->exact_end - reg->exact));
5327 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
5328 reg->map[i] = m->map[i];
5330 reg->optimize = ONIG_OPTIMIZE_MAP;
5331 reg->dmin = m->mmd.min;
5332 reg->dmax = m->mmd.max;
5334 if (reg->dmin != ONIG_INFINITE_DISTANCE) {
5335 reg->threshold_len = (int )(reg->dmin + 1);
5342 reg->sub_anchor |= anc->left_anchor & ANCHOR_BEGIN_LINE;
5343 reg->sub_anchor |= anc->right_anchor & ANCHOR_END_LINE;
5346#if defined(ONIG_DEBUG_COMPILE) || defined(ONIG_DEBUG_MATCH)
5347static void print_optimize_info(
FILE* f,
regex_t* reg);
5359 env.options = reg->options;
5360 env.case_fold_flag = reg->case_fold_flag;
5361 env.scan_env = scan_env;
5362 clear_mml(&env.mmd);
5364 r = optimize_node_left(node, &opt, &env);
5367 reg->anchor = opt.anc.left_anchor & (ANCHOR_BEGIN_BUF |
5368 ANCHOR_BEGIN_POSITION | ANCHOR_ANYCHAR_STAR | ANCHOR_ANYCHAR_STAR_ML |
5369 ANCHOR_LOOK_BEHIND);
5371 if ((opt.anc.left_anchor & (ANCHOR_LOOK_BEHIND | ANCHOR_PREC_READ_NOT)) != 0)
5372 reg->anchor &= ~ANCHOR_ANYCHAR_STAR_ML;
5374 reg->anchor |= opt.anc.right_anchor & (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF |
5375 ANCHOR_PREC_READ_NOT);
5377 if (reg->anchor & (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF)) {
5378 reg->anchor_dmin = opt.len.min;
5379 reg->anchor_dmax = opt.len.max;
5382 if (opt.exb.len > 0 || opt.exm.len > 0) {
5383 select_opt_exact_info(reg->enc, &opt.exb, &opt.exm);
5384 if (opt.map.value > 0 &&
5385 comp_opt_exact_or_map_info(&opt.exb, &opt.map) > 0) {
5389 r = set_optimize_exact_info(reg, &opt.exb);
5390 set_sub_anchor(reg, &opt.exb.anc);
5393 else if (opt.map.value > 0) {
5395 set_optimize_map_info(reg, &opt.map);
5396 set_sub_anchor(reg, &opt.map.anc);
5399 reg->sub_anchor |= opt.anc.left_anchor & ANCHOR_BEGIN_LINE;
5400 if (opt.len.max == 0)
5401 reg->sub_anchor |= opt.anc.right_anchor & ANCHOR_END_LINE;
5404#if defined(ONIG_DEBUG_COMPILE) || defined(ONIG_DEBUG_MATCH)
5405 print_optimize_info(stderr, reg);
5411clear_optimize_info(
regex_t* reg)
5413 reg->optimize = ONIG_OPTIMIZE_NONE;
5415 reg->anchor_dmin = 0;
5416 reg->anchor_dmax = 0;
5417 reg->sub_anchor = 0;
5418 reg->exact_end = (UChar* )NULL;
5419 reg->threshold_len = 0;
5421 reg->exact = (UChar* )NULL;
5427 const UChar *s,
const UChar *end)
5429 fprintf(fp,
"\nPATTERN: /");
5431 if (ONIGENC_MBC_MINLEN(enc) > 1) {
5437 code = ONIGENC_MBC_TO_CODE(enc, p, end);
5439 fprintf(fp,
" 0x%04x ", (
int )code);
5442 fputc((
int )code, fp);
5445 p += enclen(enc, p, end);
5450 fputc((
int )*s, fp);
5455 fprintf(fp,
"/ (%s)\n", enc->name);
5459#if defined(ONIG_DEBUG_COMPILE) || defined(ONIG_DEBUG_MATCH)
5461print_distance_range(
FILE* f, OnigDistance a, OnigDistance b)
5463 if (a == ONIG_INFINITE_DISTANCE)
5466 fprintf(f,
"(%"PRIuPTR
")", a);
5470 if (b == ONIG_INFINITE_DISTANCE)
5473 fprintf(f,
"(%"PRIuPTR
")", b);
5477print_anchor(
FILE* f,
int anchor)
5483 if (anchor & ANCHOR_BEGIN_BUF) {
5484 fprintf(f,
"begin-buf");
5487 if (anchor & ANCHOR_BEGIN_LINE) {
5488 if (q) fprintf(f,
", ");
5490 fprintf(f,
"begin-line");
5492 if (anchor & ANCHOR_BEGIN_POSITION) {
5493 if (q) fprintf(f,
", ");
5495 fprintf(f,
"begin-pos");
5497 if (anchor & ANCHOR_END_BUF) {
5498 if (q) fprintf(f,
", ");
5500 fprintf(f,
"end-buf");
5502 if (anchor & ANCHOR_SEMI_END_BUF) {
5503 if (q) fprintf(f,
", ");
5505 fprintf(f,
"semi-end-buf");
5507 if (anchor & ANCHOR_END_LINE) {
5508 if (q) fprintf(f,
", ");
5510 fprintf(f,
"end-line");
5512 if (anchor & ANCHOR_ANYCHAR_STAR) {
5513 if (q) fprintf(f,
", ");
5515 fprintf(f,
"anychar-star");
5517 if (anchor & ANCHOR_ANYCHAR_STAR_ML) {
5518 if (q) fprintf(f,
", ");
5519 fprintf(f,
"anychar-star-ml");
5528 static const char* on[] = {
"NONE",
"EXACT",
"EXACT_BM",
"EXACT_BM_NOT_REV",
5530 "EXACT_BM_IC",
"EXACT_BM_NOT_REV_IC" };
5532 fprintf(f,
"optimize: %s\n", on[reg->optimize]);
5533 fprintf(f,
" anchor: "); print_anchor(f, reg->anchor);
5534 if ((reg->anchor & ANCHOR_END_BUF_MASK) != 0)
5535 print_distance_range(f, reg->anchor_dmin, reg->anchor_dmax);
5538 if (reg->optimize) {
5539 fprintf(f,
" sub anchor: "); print_anchor(f, reg->sub_anchor);
5546 fprintf(f,
"exact: [");
5547 for (p = reg->exact; p < reg->exact_end; p++) {
5550 fprintf(f,
"]: length: %"PRIdPTR
"\n", (reg->exact_end - reg->exact));
5552 else if (reg->optimize & ONIG_OPTIMIZE_MAP) {
5555 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
5556 if (reg->map[i]) n++;
5558 fprintf(f,
"map: n=%d\n", n);
5562 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) {
5563 if (reg->map[i] != 0) {
5564 if (c > 0) fputs(
", ", f);
5566 if (ONIGENC_MBC_MAXLEN(reg->enc) == 1 &&
5567 ONIGENC_IS_CODE_PRINT(reg->enc, (OnigCodePoint )i))
5570 fprintf(f,
"%d", i);
5583 if (IS_NOT_NULL(reg)) {
5586 xfree(reg->repeat_range);
5587 onig_free(reg->chain);
5589#ifdef USE_NAMED_GROUP
5590 onig_names_free(reg);
5598 if (IS_NOT_NULL(reg)) {
5599 onig_free_body(reg);
5605dup_copy(
const void *ptr,
size_t size)
5608 if (IS_NOT_NULL(newptr)) {
5609 memcpy(newptr, ptr, size);
5617 if (IS_NOT_NULL(oreg)) {
5620# define COPY_FAILED(mem, size) IS_NULL(nreg->mem = dup_copy(oreg->mem, size))
5622 if (IS_NOT_NULL(oreg->exact)) {
5623 size_t exact_size = oreg->exact_end - oreg->exact;
5624 if (COPY_FAILED(exact, exact_size))
5626 (nreg)->exact_end = (nreg)->exact + exact_size;
5629 if (IS_NOT_NULL(oreg->p)) {
5630 if (COPY_FAILED(p, oreg->alloc))
5633 if (IS_NOT_NULL(oreg->repeat_range)) {
5634 if (COPY_FAILED(repeat_range, oreg->repeat_range_alloc *
sizeof(
OnigRepeatRange)))
5635 goto err_repeat_range;
5637 if (IS_NOT_NULL(oreg->name_table)) {
5638 if (onig_names_copy(nreg, oreg))
5639 goto err_name_table;
5641 if (IS_NOT_NULL(oreg->chain)) {
5642 if (onig_reg_copy(&nreg->chain, oreg->chain))
5649 onig_names_free(nreg);
5651 xfree(nreg->repeat_range);
5658 return ONIGERR_MEMORY;
5666 if (IS_NOT_NULL(oreg)) {
5668 if (IS_NULL(reg))
return ONIGERR_MEMORY;
5670 return onig_reg_copy_body(reg, oreg);
5677onig_memsize(
const regex_t *reg)
5679 size_t size =
sizeof(
regex_t);
5680 if (IS_NULL(reg))
return 0;
5681 if (IS_NOT_NULL(reg->p)) size += reg->alloc;
5682 if (IS_NOT_NULL(reg->exact)) size += reg->exact_end - reg->exact;
5683 if (IS_NOT_NULL(reg->repeat_range)) size += reg->repeat_range_alloc *
sizeof(
OnigRepeatRange);
5684 if (IS_NOT_NULL(reg->chain)) size += onig_memsize(reg->chain);
5692 size_t size =
sizeof(*regs);
5693 if (IS_NULL(regs))
return 0;
5694 size += regs->allocated * (
sizeof(*regs->beg) +
sizeof(*regs->end));
5699#define REGEX_TRANSFER(to,from) do {\
5700 onig_free_body(to);\
5701 xmemcpy(to, from, sizeof(regex_t));\
5709 REGEX_TRANSFER(to, from);
5713#ifdef ONIG_DEBUG_COMPILE
5714static void print_compiled_byte_code_list(
FILE* f,
regex_t* reg);
5716#ifdef ONIG_DEBUG_PARSE_TREE
5717static void print_tree(
FILE* f,
Node* node);
5722onig_compile(
regex_t* reg,
const UChar* pattern,
const UChar* pattern_end,
5725 return onig_compile_ruby(reg, pattern, pattern_end, einfo, NULL, 0);
5731onig_compile_ruby(
regex_t* reg,
const UChar* pattern,
const UChar* pattern_end,
5732 OnigErrorInfo* einfo,
const char *sourcefile,
int sourceline)
5735onig_compile(
regex_t* reg,
const UChar* pattern,
const UChar* pattern_end,
5739#define COMPILE_INIT_SIZE 20
5742 OnigDistance init_size;
5745#ifdef USE_SUBEXP_CALL
5749 if (IS_NOT_NULL(einfo)) einfo->par = (UChar* )NULL;
5752 scan_env.sourcefile = sourcefile;
5753 scan_env.sourceline = sourceline;
5757 print_enc_string(stderr, reg->enc, pattern, pattern_end);
5760 if (reg->alloc == 0) {
5761 init_size = (pattern_end - pattern) * 2;
5762 if (init_size <= 0) init_size = COMPILE_INIT_SIZE;
5763 r = BBUF_INIT(reg, init_size);
5764 if (r != 0)
goto end;
5770 reg->num_repeat = 0;
5771 reg->num_null_check = 0;
5772 reg->repeat_range_alloc = 0;
5774#ifdef USE_COMBINATION_EXPLOSION_CHECK
5775 reg->num_comb_exp_check = 0;
5778 r = onig_parse_make_tree(&root, pattern, pattern_end, reg, &scan_env);
5779 if (r != 0)
goto err;
5781#ifdef ONIG_DEBUG_PARSE_TREE
5783 fprintf(stderr,
"ORIGINAL PARSE TREE:\n");
5784 print_tree(stderr, root);
5788#ifdef USE_NAMED_GROUP
5790 if (scan_env.num_named > 0 &&
5791 IS_SYNTAX_BV(scan_env.syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
5792 !ONIG_IS_OPTION_ON(reg->options, ONIG_OPTION_CAPTURE_GROUP)) {
5793 if (scan_env.num_named != scan_env.num_mem)
5794 r = disable_noname_group_capture(&root, reg, &scan_env);
5796 r = numbered_ref_check(root);
5798 if (r != 0)
goto err;
5802#ifdef USE_SUBEXP_CALL
5803 if (scan_env.num_call > 0) {
5804 r = unset_addr_list_init(&uslist, scan_env.num_call);
5805 if (r != 0)
goto err;
5806 scan_env.unset_addr_list = &uslist;
5807 r = setup_subexp_call(root, &scan_env);
5808 if (r != 0)
goto err_unset;
5809 r = subexp_recursive_check_trav(root, &scan_env);
5810 if (r < 0)
goto err_unset;
5811 r = subexp_inf_recursive_check_trav(root, &scan_env);
5812 if (r != 0)
goto err_unset;
5814 reg->num_call = scan_env.num_call;
5820 r = setup_tree(root, reg, 0, &scan_env);
5821 if (r != 0)
goto err_unset;
5823#ifdef ONIG_DEBUG_PARSE_TREE
5824 print_tree(stderr, root);
5827 reg->capture_history = scan_env.capture_history;
5828 reg->bt_mem_start = scan_env.bt_mem_start;
5829 reg->bt_mem_start |= reg->capture_history;
5830 if (IS_FIND_CONDITION(reg->options))
5831 BIT_STATUS_ON_ALL(reg->bt_mem_end);
5833 reg->bt_mem_end = scan_env.bt_mem_end;
5834 reg->bt_mem_end |= reg->capture_history;
5837#ifdef USE_COMBINATION_EXPLOSION_CHECK
5838 if (scan_env.backrefed_mem == 0
5839# ifdef USE_SUBEXP_CALL
5840 || scan_env.num_call == 0
5843 setup_comb_exp_check(root, 0, &scan_env);
5844# ifdef USE_SUBEXP_CALL
5845 if (scan_env.has_recursion != 0) {
5846 scan_env.num_comb_exp_check = 0;
5850 if (scan_env.comb_exp_max_regnum > 0) {
5852 for (i = 1; i <= scan_env.comb_exp_max_regnum; i++) {
5853 if (BIT_STATUS_AT(scan_env.backrefed_mem, i) != 0) {
5854 scan_env.num_comb_exp_check = 0;
5861 reg->num_comb_exp_check = scan_env.num_comb_exp_check;
5864 clear_optimize_info(reg);
5865#ifndef ONIG_DONT_OPTIMIZE
5866 r = set_optimize_info_from_tree(root, reg, &scan_env);
5867 if (r != 0)
goto err_unset;
5870 if (IS_NOT_NULL(scan_env.mem_nodes_dynamic)) {
5871 xfree(scan_env.mem_nodes_dynamic);
5872 scan_env.mem_nodes_dynamic = (
Node** )NULL;
5875 r = compile_tree(root, reg);
5877 r = add_opcode(reg, OP_END);
5878#ifdef USE_SUBEXP_CALL
5879 if (scan_env.num_call > 0) {
5880 r = unset_addr_list_fix(&uslist, reg);
5881 unset_addr_list_end(&uslist);
5886 if ((reg->num_repeat != 0) || (reg->bt_mem_end != 0))
5887 reg->stack_pop_level = STACK_POP_LEVEL_ALL;
5889 if (reg->bt_mem_start != 0)
5890 reg->stack_pop_level = STACK_POP_LEVEL_MEM_START;
5892 reg->stack_pop_level = STACK_POP_LEVEL_FREE;
5895#ifdef USE_SUBEXP_CALL
5896 else if (scan_env.num_call > 0) {
5897 unset_addr_list_end(&uslist);
5900 onig_node_free(root);
5902#ifdef ONIG_DEBUG_COMPILE
5903# ifdef USE_NAMED_GROUP
5904 onig_print_names(stderr, reg);
5906 print_compiled_byte_code_list(stderr, reg);
5910 onig_reg_resize(reg);
5914#ifdef USE_SUBEXP_CALL
5915 if (scan_env.num_call > 0) {
5916 unset_addr_list_end(&uslist);
5920 if (IS_NOT_NULL(scan_env.error)) {
5921 if (IS_NOT_NULL(einfo)) {
5922 einfo->enc = scan_env.enc;
5923 einfo->par = scan_env.error;
5924 einfo->par_end = scan_env.error_end;
5928 onig_node_free(root);
5929 xfree(scan_env.mem_nodes_dynamic);
5934static int onig_inited = 0;
5937onig_reg_init(
regex_t* reg, OnigOptionType option,
5938 OnigCaseFoldType case_fold_flag,
5945 return ONIGERR_INVALID_ARGUMENT;
5947 (reg)->exact = (UChar* )NULL;
5948 (reg)->chain = (
regex_t* )NULL;
5949 (reg)->p = (UChar* )NULL;
5950 (reg)->name_table = (
void* )NULL;
5953 if (ONIGENC_IS_UNDEF(enc))
5954 return ONIGERR_DEFAULT_ENCODING_IS_NOT_SET;
5956 if ((option & (ONIG_OPTION_DONT_CAPTURE_GROUP|ONIG_OPTION_CAPTURE_GROUP))
5957 == (ONIG_OPTION_DONT_CAPTURE_GROUP|ONIG_OPTION_CAPTURE_GROUP)) {
5958 return ONIGERR_INVALID_COMBINATION_OF_OPTIONS;
5961 if ((option & ONIG_OPTION_NEGATE_SINGLELINE) != 0) {
5962 option |= syntax->options;
5963 option &= ~ONIG_OPTION_SINGLELINE;
5966 option |= syntax->options;
5969 (reg)->options = option;
5970 (reg)->syntax = syntax;
5971 (reg)->optimize = 0;
5976 (reg)->case_fold_flag = case_fold_flag;
5978 (reg)->timelimit = 0;
5984onig_new_without_alloc(
regex_t* reg,
const UChar* pattern,
5985 const UChar* pattern_end, OnigOptionType option,
OnigEncoding enc,
5990 r = onig_reg_init(reg, option, ONIGENC_CASE_FOLD_DEFAULT, enc, syntax);
5993 r = onig_compile(reg, pattern, pattern_end, einfo);
5998onig_new(
regex_t** reg,
const UChar* pattern,
const UChar* pattern_end,
6003 if (IS_NULL(*reg))
return ONIGERR_MEMORY;
6005 int r = onig_new_without_alloc(*reg, pattern, pattern_end, option, enc, syntax, einfo);
6015onig_initialize(
OnigEncoding encodings[] ARG_UNUSED,
int n ARG_UNUSED)
6023 if (onig_inited != 0)
6028#if defined(ONIG_DEBUG_MEMLEAK) && defined(_MSC_VER)
6029 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
6035#ifdef ONIG_DEBUG_STATISTICS
6036 onig_statistics_init();
6045extern void onig_add_end_call(
void (*func)(
void))
6050 if (item == 0) return ;
6052 item->next = EndCallTop;
6059exec_end_call_list(
void)
6064 while (EndCallTop != 0) {
6065 func = EndCallTop->func;
6069 EndCallTop = EndCallTop->next;
6077 exec_end_call_list();
6079#ifdef ONIG_DEBUG_STATISTICS
6080 onig_print_statistics(stderr);
6083#if defined(ONIG_DEBUG_MEMLEAK) && defined(_MSC_VER)
6084 _CrtDumpMemoryLeaks();
6093onig_is_in_code_range(
const UChar* p, OnigCodePoint code)
6095 OnigCodePoint n, *data;
6096 OnigCodePoint low, high, x;
6098 GET_CODE_POINT(n, p);
6099 data = (OnigCodePoint* )p;
6102 for (low = 0, high = n; low < high; ) {
6103 x = (low + high) >> 1;
6104 if (code > data[x * 2 + 1])
6110 return ((low < n && code >= data[low * 2]) ? 1 : 0);
6114onig_is_code_in_cc_len(
int elen, OnigCodePoint code,
CClassNode* cc)
6118 if (elen > 1 || (code >= SINGLE_BYTE_SIZE)) {
6119 if (IS_NULL(cc->mbuf)) {
6123 found = (onig_is_in_code_range(cc->mbuf->p, code) != 0 ? 1 : 0);
6127 found = (BITSET_AT(cc->bs, code) == 0 ? 0 : 1);
6130 if (IS_NCCLASS_NOT(cc))
6141 if (ONIGENC_MBC_MINLEN(enc) > 1) {
6145 len = ONIGENC_CODE_TO_MBCLEN(enc, code);
6147 return onig_is_code_in_cc_len(
len, code, cc);
6154# define ARG_SPECIAL -1
6156# define ARG_RELADDR 1
6157# define ARG_ABSADDR 2
6158# define ARG_LENGTH 3
6159# define ARG_MEMNUM 4
6160# define ARG_OPTION 5
6161# define ARG_STATE_CHECK 6
6163OnigOpInfoType OnigOpInfo[] = {
6164 { OP_FINISH,
"finish", ARG_NON },
6165 { OP_END,
"end", ARG_NON },
6166 { OP_EXACT1,
"exact1", ARG_SPECIAL },
6167 { OP_EXACT2,
"exact2", ARG_SPECIAL },
6168 { OP_EXACT3,
"exact3", ARG_SPECIAL },
6169 { OP_EXACT4,
"exact4", ARG_SPECIAL },
6170 { OP_EXACT5,
"exact5", ARG_SPECIAL },
6171 { OP_EXACTN,
"exactn", ARG_SPECIAL },
6172 { OP_EXACTMB2N1,
"exactmb2-n1", ARG_SPECIAL },
6173 { OP_EXACTMB2N2,
"exactmb2-n2", ARG_SPECIAL },
6174 { OP_EXACTMB2N3,
"exactmb2-n3", ARG_SPECIAL },
6175 { OP_EXACTMB2N,
"exactmb2-n", ARG_SPECIAL },
6176 { OP_EXACTMB3N,
"exactmb3n" , ARG_SPECIAL },
6177 { OP_EXACTMBN,
"exactmbn", ARG_SPECIAL },
6178 { OP_EXACT1_IC,
"exact1-ic", ARG_SPECIAL },
6179 { OP_EXACTN_IC,
"exactn-ic", ARG_SPECIAL },
6180 { OP_CCLASS,
"cclass", ARG_SPECIAL },
6181 { OP_CCLASS_MB,
"cclass-mb", ARG_SPECIAL },
6182 { OP_CCLASS_MIX,
"cclass-mix", ARG_SPECIAL },
6183 { OP_CCLASS_NOT,
"cclass-not", ARG_SPECIAL },
6184 { OP_CCLASS_MB_NOT,
"cclass-mb-not", ARG_SPECIAL },
6185 { OP_CCLASS_MIX_NOT,
"cclass-mix-not", ARG_SPECIAL },
6186 { OP_ANYCHAR,
"anychar", ARG_NON },
6187 { OP_ANYCHAR_ML,
"anychar-ml", ARG_NON },
6188 { OP_ANYCHAR_STAR,
"anychar*", ARG_NON },
6189 { OP_ANYCHAR_ML_STAR,
"anychar-ml*", ARG_NON },
6190 { OP_ANYCHAR_STAR_PEEK_NEXT,
"anychar*-peek-next", ARG_SPECIAL },
6191 { OP_ANYCHAR_ML_STAR_PEEK_NEXT,
"anychar-ml*-peek-next", ARG_SPECIAL },
6192 { OP_WORD,
"word", ARG_NON },
6193 { OP_NOT_WORD,
"not-word", ARG_NON },
6194 { OP_WORD_BOUND,
"word-bound", ARG_NON },
6195 { OP_NOT_WORD_BOUND,
"not-word-bound", ARG_NON },
6196 { OP_WORD_BEGIN,
"word-begin", ARG_NON },
6197 { OP_WORD_END,
"word-end", ARG_NON },
6198 { OP_ASCII_WORD,
"ascii-word", ARG_NON },
6199 { OP_NOT_ASCII_WORD,
"not-ascii-word", ARG_NON },
6200 { OP_ASCII_WORD_BOUND,
"ascii-word-bound", ARG_NON },
6201 { OP_NOT_ASCII_WORD_BOUND,
"not-ascii-word-bound", ARG_NON },
6202 { OP_ASCII_WORD_BEGIN,
"ascii-word-begin", ARG_NON },
6203 { OP_ASCII_WORD_END,
"ascii-word-end", ARG_NON },
6204 { OP_BEGIN_BUF,
"begin-buf", ARG_NON },
6205 { OP_END_BUF,
"end-buf", ARG_NON },
6206 { OP_BEGIN_LINE,
"begin-line", ARG_NON },
6207 { OP_END_LINE,
"end-line", ARG_NON },
6208 { OP_SEMI_END_BUF,
"semi-end-buf", ARG_NON },
6209 { OP_BEGIN_POSITION,
"begin-position", ARG_NON },
6210 { OP_BACKREF1,
"backref1", ARG_NON },
6211 { OP_BACKREF2,
"backref2", ARG_NON },
6212 { OP_BACKREFN,
"backrefn", ARG_MEMNUM },
6213 { OP_BACKREFN_IC,
"backrefn-ic", ARG_SPECIAL },
6214 { OP_BACKREF_MULTI,
"backref_multi", ARG_SPECIAL },
6215 { OP_BACKREF_MULTI_IC,
"backref_multi-ic", ARG_SPECIAL },
6216 { OP_BACKREF_WITH_LEVEL,
"backref_at_level", ARG_SPECIAL },
6217 { OP_MEMORY_START_PUSH,
"mem-start-push", ARG_MEMNUM },
6218 { OP_MEMORY_START,
"mem-start", ARG_MEMNUM },
6219 { OP_MEMORY_END_PUSH,
"mem-end-push", ARG_MEMNUM },
6220 { OP_MEMORY_END_PUSH_REC,
"mem-end-push-rec", ARG_MEMNUM },
6221 { OP_MEMORY_END,
"mem-end", ARG_MEMNUM },
6222 { OP_MEMORY_END_REC,
"mem-end-rec", ARG_MEMNUM },
6223 { OP_SET_OPTION_PUSH,
"set-option-push", ARG_OPTION },
6224 { OP_SET_OPTION,
"set-option", ARG_OPTION },
6225 { OP_KEEP,
"keep", ARG_NON },
6226 { OP_FAIL,
"fail", ARG_NON },
6227 { OP_JUMP,
"jump", ARG_RELADDR },
6228 { OP_PUSH,
"push", ARG_RELADDR },
6229 { OP_POP,
"pop", ARG_NON },
6230 { OP_PUSH_OR_JUMP_EXACT1,
"push-or-jump-e1", ARG_SPECIAL },
6231 { OP_PUSH_IF_PEEK_NEXT,
"push-if-peek-next", ARG_SPECIAL },
6232 { OP_REPEAT,
"repeat", ARG_SPECIAL },
6233 { OP_REPEAT_NG,
"repeat-ng", ARG_SPECIAL },
6234 { OP_REPEAT_INC,
"repeat-inc", ARG_MEMNUM },
6235 { OP_REPEAT_INC_NG,
"repeat-inc-ng", ARG_MEMNUM },
6236 { OP_REPEAT_INC_SG,
"repeat-inc-sg", ARG_MEMNUM },
6237 { OP_REPEAT_INC_NG_SG,
"repeat-inc-ng-sg", ARG_MEMNUM },
6238 { OP_NULL_CHECK_START,
"null-check-start", ARG_MEMNUM },
6239 { OP_NULL_CHECK_END,
"null-check-end", ARG_MEMNUM },
6240 { OP_NULL_CHECK_END_MEMST,
"null-check-end-memst", ARG_MEMNUM },
6241 { OP_NULL_CHECK_END_MEMST_PUSH,
"null-check-end-memst-push", ARG_MEMNUM },
6242 { OP_PUSH_POS,
"push-pos", ARG_NON },
6243 { OP_POP_POS,
"pop-pos", ARG_NON },
6244 { OP_PUSH_POS_NOT,
"push-pos-not", ARG_RELADDR },
6245 { OP_FAIL_POS,
"fail-pos", ARG_NON },
6246 { OP_PUSH_STOP_BT,
"push-stop-bt", ARG_NON },
6247 { OP_POP_STOP_BT,
"pop-stop-bt", ARG_NON },
6248 { OP_LOOK_BEHIND,
"look-behind", ARG_SPECIAL },
6249 { OP_PUSH_LOOK_BEHIND_NOT,
"push-look-behind-not", ARG_SPECIAL },
6250 { OP_FAIL_LOOK_BEHIND_NOT,
"fail-look-behind-not", ARG_NON },
6251 { OP_PUSH_ABSENT_POS,
"push-absent-pos", ARG_NON },
6252 { OP_ABSENT,
"absent", ARG_RELADDR },
6253 { OP_ABSENT_END,
"absent-end", ARG_NON },
6254 { OP_CALL,
"call", ARG_ABSADDR },
6255 { OP_RETURN,
"return", ARG_NON },
6256 { OP_CONDITION,
"condition", ARG_SPECIAL },
6257 { OP_STATE_CHECK_PUSH,
"state-check-push", ARG_SPECIAL },
6258 { OP_STATE_CHECK_PUSH_OR_JUMP,
"state-check-push-or-jump", ARG_SPECIAL },
6259 { OP_STATE_CHECK,
"state-check", ARG_STATE_CHECK },
6260 { OP_STATE_CHECK_ANYCHAR_STAR,
"state-check-anychar*", ARG_STATE_CHECK },
6261 { OP_STATE_CHECK_ANYCHAR_ML_STAR,
6262 "state-check-anychar-ml*", ARG_STATE_CHECK },
6271 for (i = 0; OnigOpInfo[i].opcode >= 0; i++) {
6272 if (opcode == OnigOpInfo[i].opcode)
6273 return OnigOpInfo[i].name;
6279op2arg_type(
int opcode)
6283 for (i = 0; OnigOpInfo[i].opcode >= 0; i++) {
6284 if (opcode == OnigOpInfo[i].opcode)
6285 return OnigOpInfo[i].arg_type;
6290# ifdef ONIG_DEBUG_PARSE_TREE
6292Indent(
FILE* f,
int indent)
6295 for (i = 0; i < indent; i++) putc(
' ', f);
6300p_string(
FILE* f, ptrdiff_t
len, UChar* s)
6303 while (
len-- > 0) { fputc(*s++, f); }
6307p_len_string(
FILE* f, LengthType
len,
int mb_len, UChar* s)
6309 int x =
len * mb_len;
6311 fprintf(f,
":%d:",
len);
6312 while (x-- > 0) { fputc(*s++, f); }
6316onig_print_compiled_byte_code(
FILE* f, UChar* bp, UChar* bpend, UChar** nextp,
6323 StateCheckNumType scn;
6327 fprintf(f,
"[%s", op2name(*bp));
6328 arg_type = op2arg_type(*bp);
6329 if (arg_type != ARG_SPECIAL) {
6335 GET_RELADDR_INC(addr, bp);
6336 fprintf(f,
":(%s%d)", (addr >= 0) ?
"+" :
"", addr);
6339 GET_ABSADDR_INC(addr, bp);
6340 fprintf(f,
":(%d)", addr);
6343 GET_LENGTH_INC(
len, bp);
6344 fprintf(f,
":%d",
len);
6347 mem = *((MemNumType* )bp);
6349 fprintf(f,
":%d", mem);
6353 OnigOptionType option = *((OnigOptionType* )bp);
6355 fprintf(f,
":%d", option);
6359 case ARG_STATE_CHECK:
6360 scn = *((StateCheckNumType* )bp);
6361 bp += SIZE_STATE_CHECK_NUM;
6362 fprintf(f,
":%d", scn);
6369 case OP_ANYCHAR_STAR_PEEK_NEXT:
6370 case OP_ANYCHAR_ML_STAR_PEEK_NEXT:
6371 p_string(f, 1, bp++);
break;
6373 p_string(f, 2, bp); bp += 2;
break;
6375 p_string(f, 3, bp); bp += 3;
break;
6377 p_string(f, 4, bp); bp += 4;
break;
6379 p_string(f, 5, bp); bp += 5;
break;
6381 GET_LENGTH_INC(
len, bp);
6382 p_len_string(f,
len, 1, bp);
6387 p_string(f, 2, bp); bp += 2;
break;
6389 p_string(f, 4, bp); bp += 4;
break;
6391 p_string(f, 6, bp); bp += 6;
break;
6393 GET_LENGTH_INC(
len, bp);
6394 p_len_string(f,
len, 2, bp);
6398 GET_LENGTH_INC(
len, bp);
6399 p_len_string(f,
len, 3, bp);
6406 GET_LENGTH_INC(mb_len, bp);
6407 GET_LENGTH_INC(
len, bp);
6408 fprintf(f,
":%d:%d:", mb_len,
len);
6410 while (n-- > 0) { fputc(*bp++, f); }
6415 len = enclen(enc, bp, bpend);
6416 p_string(f,
len, bp);
6420 GET_LENGTH_INC(
len, bp);
6421 p_len_string(f,
len, 1, bp);
6426 n = bitset_on_num((BitSetRef )bp);
6428 fprintf(f,
":%d", n);
6432 n = bitset_on_num((BitSetRef )bp);
6434 fprintf(f,
":%d", n);
6438 case OP_CCLASS_MB_NOT:
6439 GET_LENGTH_INC(
len, bp);
6441# ifndef PLATFORM_UNALIGNED_WORD_ACCESS
6444 GET_CODE_POINT(code, q);
6446 fprintf(f,
":%d:%d", (
int )code,
len);
6450 case OP_CCLASS_MIX_NOT:
6451 n = bitset_on_num((BitSetRef )bp);
6453 GET_LENGTH_INC(
len, bp);
6455# ifndef PLATFORM_UNALIGNED_WORD_ACCESS
6458 GET_CODE_POINT(code, q);
6460 fprintf(f,
":%d:%d:%d", n, (
int )code,
len);
6463 case OP_BACKREFN_IC:
6464 mem = *((MemNumType* )bp);
6466 fprintf(f,
":%d", mem);
6469 case OP_BACKREF_MULTI_IC:
6470 case OP_BACKREF_MULTI:
6472 GET_LENGTH_INC(
len, bp);
6473 for (i = 0; i <
len; i++) {
6474 GET_MEMNUM_INC(mem, bp);
6475 if (i > 0) fputs(
", ", f);
6476 fprintf(f,
"%d", mem);
6480 case OP_BACKREF_WITH_LEVEL:
6482 OnigOptionType option;
6485 GET_OPTION_INC(option, bp);
6486 fprintf(f,
":%d", option);
6487 GET_LENGTH_INC(level, bp);
6488 fprintf(f,
":%d", level);
6491 GET_LENGTH_INC(
len, bp);
6492 for (i = 0; i <
len; i++) {
6493 GET_MEMNUM_INC(mem, bp);
6494 if (i > 0) fputs(
", ", f);
6495 fprintf(f,
"%d", mem);
6503 mem = *((MemNumType* )bp);
6505 addr = *((RelAddrType* )bp);
6507 fprintf(f,
":%d:%d", mem, addr);
6511 case OP_PUSH_OR_JUMP_EXACT1:
6512 case OP_PUSH_IF_PEEK_NEXT:
6513 addr = *((RelAddrType* )bp);
6515 fprintf(f,
":(%s%d)", (addr >= 0) ?
"+" :
"", addr);
6520 case OP_LOOK_BEHIND:
6521 GET_LENGTH_INC(
len, bp);
6522 fprintf(f,
":%d",
len);
6525 case OP_PUSH_LOOK_BEHIND_NOT:
6526 GET_RELADDR_INC(addr, bp);
6527 GET_LENGTH_INC(
len, bp);
6528 fprintf(f,
":%d:(%s%d)",
len, (addr >= 0) ?
"+" :
"", addr);
6531 case OP_STATE_CHECK_PUSH:
6532 case OP_STATE_CHECK_PUSH_OR_JUMP:
6533 scn = *((StateCheckNumType* )bp);
6534 bp += SIZE_STATE_CHECK_NUM;
6535 addr = *((RelAddrType* )bp);
6537 fprintf(f,
":%d:(%s%d)", scn, (addr >= 0) ?
"+" :
"", addr);
6541 GET_MEMNUM_INC(mem, bp);
6542 GET_RELADDR_INC(addr, bp);
6543 fprintf(f,
":%d:(%s%d)", mem, (addr >= 0) ?
"+" :
"", addr);
6547 fprintf(stderr,
"onig_print_compiled_byte_code: undefined code %d\n",
6552 if (nextp) *nextp = bp;
6555# ifdef ONIG_DEBUG_COMPILE
6557print_compiled_byte_code_list(
FILE* f,
regex_t* reg)
6561 UChar* end = reg->p + reg->used;
6563 fprintf(f,
"code length: %d", reg->used);
6569 fprintf(f,
"\n%ld:", bp - reg->p);
6571 fprintf(f,
" %ld:", bp - reg->p);
6572 onig_print_compiled_byte_code(f, bp, end, &bp, reg->enc);
6579# ifdef ONIG_DEBUG_PARSE_TREE
6581print_indent_tree(
FILE* f,
Node* node,
int indent)
6583 int i,
type, container_p = 0;
6588 if (IS_NULL(node)) {
6589 fprintf(f,
"ERROR: null node!!!\n");
6597 if (NTYPE(node) == NT_LIST)
6598 fprintf(f,
"<list:%"PRIxPTR
">\n", (intptr_t )node);
6600 fprintf(f,
"<alt:%"PRIxPTR
">\n", (intptr_t )node);
6602 print_indent_tree(f, NCAR(node), indent + add);
6603 while (IS_NOT_NULL(node = NCDR(node))) {
6604 if (NTYPE(node) != type) {
6605 fprintf(f,
"ERROR: list/alt right is not a cons. %d\n", NTYPE(node));
6608 print_indent_tree(f, NCAR(node), indent + add);
6613 fprintf(f,
"<string%s:%"PRIxPTR
">",
6614 (NSTRING_IS_RAW(node) ?
"-raw" :
""), (intptr_t )node);
6615 for (p = NSTR(node)->s; p < NSTR(node)->end; p++) {
6616 if (*p >= 0x20 && *p < 0x7f)
6619 fprintf(f,
" 0x%02x", *p);
6625 fprintf(f,
"<cclass:%"PRIxPTR
">", (intptr_t )node);
6626 if (IS_NCCLASS_NOT(NCCLASS(node))) fputs(
"not ", f);
6627 if (NCCLASS(node)->mbuf) {
6628 BBuf* bbuf = NCCLASS(node)->mbuf;
6629 OnigCodePoint* data = (OnigCodePoint* )bbuf->p;
6630 OnigCodePoint* end = (OnigCodePoint* )(bbuf->p + bbuf->used);
6631 fprintf(f,
"%d", *data++);
6632 for (; data < end; data+=2) {
6634 fprintf(f,
"%04x-%04x", data[0], data[1]);
6640 fprintf(f,
"<ctype:%"PRIxPTR
"> ", (intptr_t )node);
6641 switch (NCTYPE(node)->ctype) {
6642 case ONIGENC_CTYPE_WORD:
6643 if (NCTYPE(node)->not != 0)
6644 fputs(
"not word", f);
6650 fprintf(f,
"ERROR: undefined ctype.\n");
6656 fprintf(f,
"<anychar:%"PRIxPTR
">", (intptr_t )node);
6660 fprintf(f,
"<anchor:%"PRIxPTR
"> ", (intptr_t )node);
6661 switch (NANCHOR(node)->type) {
6662 case ANCHOR_BEGIN_BUF: fputs(
"begin buf", f);
break;
6663 case ANCHOR_END_BUF: fputs(
"end buf", f);
break;
6664 case ANCHOR_BEGIN_LINE: fputs(
"begin line", f);
break;
6665 case ANCHOR_END_LINE: fputs(
"end line", f);
break;
6666 case ANCHOR_SEMI_END_BUF: fputs(
"semi end buf", f);
break;
6667 case ANCHOR_BEGIN_POSITION: fputs(
"begin position", f);
break;
6669 case ANCHOR_WORD_BOUND: fputs(
"word bound", f);
break;
6670 case ANCHOR_NOT_WORD_BOUND: fputs(
"not word bound", f);
break;
6671# ifdef USE_WORD_BEGIN_END
6672 case ANCHOR_WORD_BEGIN: fputs(
"word begin", f);
break;
6673 case ANCHOR_WORD_END: fputs(
"word end", f);
break;
6675 case ANCHOR_PREC_READ: fputs(
"prec read", f); container_p = TRUE;
break;
6676 case ANCHOR_PREC_READ_NOT: fputs(
"prec read not", f); container_p = TRUE;
break;
6677 case ANCHOR_LOOK_BEHIND: fputs(
"look_behind", f); container_p = TRUE;
break;
6678 case ANCHOR_LOOK_BEHIND_NOT: fputs(
"look_behind_not",f); container_p = TRUE;
break;
6679 case ANCHOR_KEEP: fputs(
"keep",f);
break;
6682 fprintf(f,
"ERROR: undefined anchor type.\n");
6692 fprintf(f,
"<backref:%"PRIxPTR
">", (intptr_t )node);
6693 for (i = 0; i < br->back_num; i++) {
6694 if (i > 0) fputs(
", ", f);
6695 fprintf(f,
"%d", p[i]);
6700# ifdef USE_SUBEXP_CALL
6704 fprintf(f,
"<call:%"PRIxPTR
">", (intptr_t )node);
6705 p_string(f, cn->name_end - cn->name, cn->name);
6711 fprintf(f,
"<quantifier:%"PRIxPTR
">{%d,%d}%s\n", (intptr_t )node,
6712 NQTFR(node)->lower, NQTFR(node)->upper,
6713 (NQTFR(node)->greedy ?
"" :
"?"));
6714 print_indent_tree(f, NQTFR(node)->target, indent + add);
6718 fprintf(f,
"<enclose:%"PRIxPTR
"> ", (intptr_t )node);
6719 switch (NENCLOSE(node)->type) {
6720 case ENCLOSE_OPTION:
6721 fprintf(f,
"option:%d", NENCLOSE(node)->option);
6723 case ENCLOSE_MEMORY:
6724 fprintf(f,
"memory:%d", NENCLOSE(node)->regnum);
6726 case ENCLOSE_STOP_BACKTRACK:
6727 fprintf(f,
"stop-bt");
6729 case ENCLOSE_CONDITION:
6730 fprintf(f,
"condition:%d", NENCLOSE(node)->regnum);
6732 case ENCLOSE_ABSENT:
6733 fprintf(f,
"absent");
6740 print_indent_tree(f, NENCLOSE(node)->target, indent + add);
6744 fprintf(f,
"print_indent_tree: undefined node type %d\n", NTYPE(node));
6748 if (type != NT_LIST && type != NT_ALT && type != NT_QTFR &&
6752 if (container_p) print_indent_tree(f, NANCHOR(node)->target, indent + add);
6760 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.