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;
71swap_node(Node* a, Node* b)
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++;
143onig_reg_resize(regex_t *reg)
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);
264add_length(regex_t* reg, OnigDistance
len)
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);
336static int compile_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
423compile_call(
CallNode* node, regex_t* reg)
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,
468 regex_t* reg,
int ignore_case)
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;
492 OnigEncoding enc = reg->enc;
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);
528compile_length_string_raw_node(
StrNode* sn, regex_t* reg)
530 if (sn->end <= sn->s)
533 return add_compile_string_length(sn->s, 1 , sn->end - sn->s, reg, 0);
537compile_string_node(Node* node, regex_t* reg)
539 int r,
len, prev_len, blen, ambig;
540 OnigEncoding enc = reg->enc;
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);
576compile_string_raw_node(
StrNode* sn, regex_t* reg)
578 if (sn->end <= sn->s)
581 return add_compile_string(sn->s, 1 , sn->end - sn->s, reg, 0);
585add_multi_byte_cclass(BBuf* mbuf, regex_t* reg)
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);
608compile_length_cclass_node(
CClassNode* cc, regex_t* reg)
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);
633compile_cclass_node(
CClassNode* cc, regex_t* reg)
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
757compile_length_quantifier_node(
QtfrNode* qn, regex_t* reg)
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;
837compile_quantifier_node(
QtfrNode* qn, regex_t* reg)
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);
991compile_length_quantifier_node(
QtfrNode* qn, regex_t* reg)
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;
1059compile_quantifier_node(
QtfrNode* qn, regex_t* reg)
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);
1193compile_length_option_node(
EncloseNode* node, regex_t* 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;
1213compile_option_node(
EncloseNode* node, regex_t* reg)
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);
1239compile_length_enclose_node(
EncloseNode* node, regex_t* reg)
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);
1341compile_enclose_node(
EncloseNode* node, regex_t* reg)
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;
1503compile_length_anchor_node(
AnchorNode* node, regex_t* reg)
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;
1536compile_anchor_node(
AnchorNode* node, regex_t* reg)
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;
1633compile_length_tree(Node* node, regex_t* reg)
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;
1728compile_tree(Node* node, regex_t* reg)
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
1903noname_disable_map(Node** plink,
GroupNumRemap* map,
int* counter)
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);
1961renumber_node_backref(Node* node,
GroupNumRemap* map,
const int num_mem)
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;
1990renumber_by_map(Node* node,
GroupNumRemap* map,
const int num_mem)
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);
2068disable_noname_group_capture(Node** root, regex_t* reg,
ScanEnv* env)
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;
2587get_char_length_tree(Node* node, regex_t* reg,
int*
len)
2589 return get_char_length_tree1(node, reg,
len, 0);
2594is_not_included(Node* x, Node* y, regex_t* reg)
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;
3197setup_subexp_call(Node* node,
ScanEnv* env)
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);
3354setup_look_behind(Node* node, regex_t* reg,
ScanEnv* env)
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;
3375next_setup(Node* node, Node* next_node, regex_t* reg)
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,
3506 regex_t* reg, Node **rnode)
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);
3921setup_tree(Node* node, regex_t* reg,
int state,
ScanEnv* 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** int_skip,
int ignore_case)
4231 OnigDistance i,
len;
4232 int clen, flen, n, j, k;
4233 UChar *p, buf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
4235 OnigEncoding enc = reg->enc;
4238 if (
len < ONIG_CHAR_TABLE_SIZE) {
4240 for (i = 0; i <
len; i += clen) {
4242 n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
4244 clen = enclen(enc, p, end);
4246 clen = (int )(end - p);
4248 for (j = 0; j < n; j++) {
4249 if ((items[j].code_len != 1) || (items[j].byte_len != clen)) {
4254 flen = ONIGENC_CODE_TO_MBC(enc, items[j].code[0], buf);
4267 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
4268 skip[i] = (UChar )(
len + 1);
4270 for (i = 0; i <
len; i += clen) {
4273 n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
4275 clen = enclen(enc, p, end);
4277 clen = (int )(end - p);
4279 for (j = 0; j < clen; j++) {
4280 skip[s[i + j]] = (UChar )(
len - i - j);
4281 for (k = 0; k < n; k++) {
4282 ONIGENC_CODE_TO_MBC(enc, items[k].code[0], buf);
4283 skip[buf[j]] = (UChar )(
len - i - j);
4289# if OPT_EXACT_MAXLEN < ONIG_CHAR_TABLE_SIZE
4291 return ONIGERR_TYPE_BUG;
4293 if (IS_NULL(*int_skip)) {
4294 *int_skip = (
int* )
xmalloc(
sizeof(
int) * ONIG_CHAR_TABLE_SIZE);
4295 if (IS_NULL(*int_skip))
return ONIGERR_MEMORY;
4297 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) (*int_skip)[i] = (int )(
len + 1);
4300 for (i = 0; i <
len; i += clen) {
4303 n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
4305 clen = enclen(enc, p, end);
4307 clen = (int )(end - p);
4309 for (j = 0; j < n; j++) {
4310 if ((items[j].code_len != 1) || (items[j].byte_len != clen))
4312 flen = ONIGENC_CODE_TO_MBC(enc, items[j].code[0], buf[j]);
4316 for (j = 0; j < clen; j++) {
4317 (*int_skip)[s[i + j]] = (int )(
len - i - j);
4318 for (k = 0; k < n; k++) {
4319 (*int_skip)[buf[k][j]] = (int )(
len - i - j);
4336 OnigOptionType options;
4337 OnigCaseFoldType case_fold_flag;
4353 UChar s[OPT_EXACT_MAXLEN];
4361 UChar map[ONIG_CHAR_TABLE_SIZE];
4377map_position_value(OnigEncoding enc,
int i)
4379 static const short int ByteValTable[] = {
4380 5, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10, 1, 1, 10, 1, 1,
4381 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4382 12, 4, 7, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5,
4383 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5,
4384 5, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
4385 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 5, 5, 5,
4386 5, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
4387 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 1
4390 if (i < numberof(ByteValTable)) {
4391 if (i == 0 && ONIGENC_MBC_MINLEN(enc) > 1)
4394 return (
int )ByteValTable[i];
4404 static const short int dist_vals[] = {
4405 1000, 500, 333, 250, 200, 167, 143, 125, 111, 100,
4406 91, 83, 77, 71, 67, 63, 59, 56, 53, 50,
4407 48, 45, 43, 42, 40, 38, 37, 36, 34, 33,
4408 32, 31, 30, 29, 29, 28, 27, 26, 26, 25,
4409 24, 24, 23, 23, 22, 22, 21, 21, 20, 20,
4410 20, 19, 19, 19, 18, 18, 18, 17, 17, 17,
4411 16, 16, 16, 16, 15, 15, 15, 15, 14, 14,
4412 14, 14, 14, 14, 13, 13, 13, 13, 13, 13,
4413 12, 12, 12, 12, 12, 12, 11, 11, 11, 11,
4414 11, 11, 11, 11, 11, 10, 10, 10, 10, 10
4419 if (mm->max == ONIG_INFINITE_DISTANCE)
return 0;
4421 d = mm->max - mm->min;
4422 if (d < numberof(dist_vals))
4424 return (
int )dist_vals[d];
4432 if (v2 <= 0)
return -1;
4433 if (v1 <= 0)
return 1;
4435 v1 *= distance_value(d1);
4436 v2 *= distance_value(d2);
4438 if (v2 > v1)
return 1;
4439 if (v2 < v1)
return -1;
4441 if (d2->min < d1->min)
return 1;
4442 if (d2->min > d1->min)
return -1;
4449 return (a->min == b->min && a->max == b->max) ? 1 : 0;
4454set_mml(
MinMaxLen* mml, OnigDistance min, OnigDistance max)
4463 mml->min = mml->max = 0;
4469 to->min = from->min;
4470 to->max = from->max;
4476 to->min = distance_add(to->min, from->min);
4477 to->max = distance_add(to->max, from->max);
4484 to->min = distance_add(to->min,
len);
4485 to->max = distance_add(to->max,
len);
4492 if (to->min > from->min) to->min = from->min;
4493 if (to->max < from->max) to->max = from->max;
4505 anc->left_anchor = 0;
4506 anc->right_anchor = 0;
4517 OnigDistance left_len, OnigDistance right_len)
4519 clear_opt_anc_info(to);
4521 to->left_anchor = left->left_anchor;
4522 if (left_len == 0) {
4523 to->left_anchor |= right->left_anchor;
4526 to->right_anchor = right->right_anchor;
4527 if (right_len == 0) {
4528 to->right_anchor |= left->right_anchor;
4531 to->right_anchor |= (left->right_anchor & ANCHOR_PREC_READ_NOT);
4536is_left_anchor(
int anc)
4538 if (anc == ANCHOR_END_BUF || anc == ANCHOR_SEMI_END_BUF ||
4539 anc == ANCHOR_END_LINE || anc == ANCHOR_PREC_READ ||
4540 anc == ANCHOR_PREC_READ_NOT)
4549 if ((to->left_anchor & anc) != 0)
return 1;
4551 return ((to->right_anchor & anc) != 0 ? 1 : 0);
4557 if (is_left_anchor(anc))
4558 to->left_anchor |= anc;
4560 to->right_anchor |= anc;
4566 if (is_left_anchor(anc))
4567 to->left_anchor &= ~anc;
4569 to->right_anchor &= ~anc;
4575 to->left_anchor &= add->left_anchor;
4576 to->right_anchor &= add->right_anchor;
4582 return (ex->len >= OPT_EXACT_MAXLEN ? 1 : 0);
4588 clear_mml(&ex->mmd);
4589 clear_opt_anc_info(&ex->anc);
4591 ex->ignore_case = -1;
4609 if (to->ignore_case < 0)
4610 to->ignore_case = add->ignore_case;
4611 else if (to->ignore_case != add->ignore_case)
4616 for (i = to->len; p < end; ) {
4617 len = enclen(enc, p, end);
4618 if (i +
len > OPT_EXACT_MAXLEN)
break;
4619 for (j = 0; j <
len && p < end; j++)
4624 to->reach_end = (p == end ? add->reach_end : 0);
4626 concat_opt_anc_info(&tanc, &to->anc, &add->anc, 1, 1);
4627 if (! to->reach_end) tanc.right_anchor = 0;
4628 copy_opt_anc_info(&to->anc, &tanc);
4632concat_opt_exact_info_str(
OptExactInfo* to, UChar* s, UChar* end,
4633 int raw ARG_UNUSED, OnigEncoding enc)
4638 for (i = to->len, p = s; p < end && i < OPT_EXACT_MAXLEN; ) {
4639 len = enclen(enc, p, end);
4640 if (i +
len > OPT_EXACT_MAXLEN)
break;
4641 for (j = 0; j <
len && p < end; j++)
4653 if (add->len == 0 || to->len == 0) {
4654 clear_opt_exact_info(to);
4658 if (! is_equal_mml(&to->mmd, &add->mmd)) {
4659 clear_opt_exact_info(to);
4663 for (i = 0; i < to->len && i < add->len; ) {
4664 if (to->s[i] != add->s[i])
break;
4665 len = enclen(env->enc, to->s + i, to->s + to->len);
4667 for (j = 1; j <
len; j++) {
4668 if (to->s[i+j] != add->s[i+j])
break;
4674 if (! add->reach_end || i < add->
len || i < to->
len) {
4678 if (to->ignore_case < 0)
4679 to->ignore_case = add->ignore_case;
4680 else if (add->ignore_case >= 0)
4681 to->ignore_case |= add->ignore_case;
4683 alt_merge_opt_anc_info(&to->anc, &add->anc);
4684 if (! to->reach_end) to->anc.right_anchor = 0;
4699 copy_opt_exact_info(now, alt);
4702 else if (v1 <= 2 && v2 <= 2) {
4704 v2 = map_position_value(enc, now->s[0]);
4705 v1 = map_position_value(enc, alt->s[0]);
4707 if (now->len > 1) v1 += 5;
4708 if (alt->len > 1) v2 += 5;
4711 if (now->ignore_case <= 0) v1 *= 2;
4712 if (alt->ignore_case <= 0) v2 *= 2;
4714 if (comp_distance_value(&now->mmd, &alt->mmd, v1, v2) > 0)
4715 copy_opt_exact_info(now, alt);
4724 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4725 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4726 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4727 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4728 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4729 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4730 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4731 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4732 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4733 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4734 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4735 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4736 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4737 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4738 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4739 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
4743 xmemcpy(map, &clean_info,
sizeof(
OptMapInfo));
4753add_char_opt_map_info(
OptMapInfo* map, UChar c, OnigEncoding enc)
4755 if (map->map[c] == 0) {
4757 map->value += map_position_value(enc, c);
4762add_char_amb_opt_map_info(
OptMapInfo* map, UChar* p, UChar* end,
4763 OnigEncoding enc, OnigCaseFoldType case_fold_flag)
4766 UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
4769 add_char_opt_map_info(map, p[0], enc);
4771 case_fold_flag = DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag);
4772 n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, case_fold_flag, p, end, items);
4773 if (n < 0)
return n;
4775 for (i = 0; i < n; i++) {
4776 ONIGENC_CODE_TO_MBC(enc, items[i].code[0], buf);
4777 add_char_opt_map_info(map, buf[0], enc);
4786 const int z = 1<<15;
4790 if (alt->value == 0) return ;
4791 if (now->value == 0) {
4792 copy_opt_map_info(now, alt);
4796 v1 = z / now->value;
4797 v2 = z / alt->value;
4798 if (comp_distance_value(&now->mmd, &alt->mmd, v1, v2) > 0)
4799 copy_opt_map_info(now, alt);
4805#define COMP_EM_BASE 20
4808 if (m->value <= 0)
return -1;
4810 ve = COMP_EM_BASE * e->len * (e->ignore_case > 0 ? 1 : 2);
4811 vm = COMP_EM_BASE * 5 * 2 / m->value;
4812 return comp_distance_value(&e->mmd, &m->mmd, ve, vm);
4821 if (to->value == 0) return ;
4822 if (add->value == 0 || to->mmd.max < add->mmd.min) {
4823 clear_opt_map_info(to);
4827 alt_merge_mml(&to->mmd, &add->mmd);
4830 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) {
4835 val += map_position_value(enc, i);
4839 alt_merge_opt_anc_info(&to->anc, &add->anc);
4845 copy_mml(&(opt->exb.mmd), mmd);
4846 copy_mml(&(opt->expr.mmd), mmd);
4847 copy_mml(&(opt->map.mmd), mmd);
4853 clear_mml(&opt->len);
4854 clear_opt_anc_info(&opt->anc);
4855 clear_opt_exact_info(&opt->exb);
4856 clear_opt_exact_info(&opt->exm);
4857 clear_opt_exact_info(&opt->expr);
4858 clear_opt_map_info(&opt->map);
4870 int exb_reach, exm_reach;
4873 concat_opt_anc_info(&tanc, &to->anc, &add->anc, to->len.max, add->len.max);
4874 copy_opt_anc_info(&to->anc, &tanc);
4876 if (add->exb.len > 0 && to->len.max == 0) {
4877 concat_opt_anc_info(&tanc, &to->anc, &add->exb.anc,
4878 to->len.max, add->len.max);
4879 copy_opt_anc_info(&add->exb.anc, &tanc);
4882 if (add->map.value > 0 && to->len.max == 0) {
4883 if (add->map.mmd.max == 0)
4884 add->map.anc.left_anchor |= to->anc.left_anchor;
4887 exb_reach = to->exb.reach_end;
4888 exm_reach = to->exm.reach_end;
4890 if (add->len.max != 0)
4891 to->exb.reach_end = to->exm.reach_end = 0;
4893 if (add->exb.len > 0) {
4895 concat_opt_exact_info(&to->exb, &add->exb, enc);
4896 clear_opt_exact_info(&add->exb);
4898 else if (exm_reach) {
4899 concat_opt_exact_info(&to->exm, &add->exb, enc);
4900 clear_opt_exact_info(&add->exb);
4903 select_opt_exact_info(enc, &to->exm, &add->exb);
4904 select_opt_exact_info(enc, &to->exm, &add->exm);
4906 if (to->expr.len > 0) {
4907 if (add->len.max > 0) {
4908 if (to->expr.len > (
int )add->len.max)
4909 to->expr.len = (int )add->len.max;
4911 if (to->expr.mmd.max == 0)
4912 select_opt_exact_info(enc, &to->exb, &to->expr);
4914 select_opt_exact_info(enc, &to->exm, &to->expr);
4917 else if (add->expr.len > 0) {
4918 copy_opt_exact_info(&to->expr, &add->expr);
4921 select_opt_map_info(&to->map, &add->map);
4923 add_mml(&to->len, &add->len);
4929 alt_merge_opt_anc_info (&to->anc, &add->anc);
4930 alt_merge_opt_exact_info(&to->exb, &add->exb, env);
4931 alt_merge_opt_exact_info(&to->exm, &add->exm, env);
4932 alt_merge_opt_exact_info(&to->expr, &add->expr, env);
4933 alt_merge_opt_map_info(env->enc, &to->map, &add->map);
4935 alt_merge_mml(&to->len, &add->len);
4939#define MAX_NODE_OPT_INFO_REF_COUNT 5
4947 clear_node_opt_info(opt);
4948 set_bound_node_opt_info(opt, &env->mmd);
4958 copy_opt_env(&nenv, env);
4960 r = optimize_node_left(NCAR(nd), &nopt, &nenv);
4962 add_mml(&nenv.mmd, &nopt.len);
4963 concat_left_node_opt_info(env->enc, opt, &nopt);
4965 }
while (r == 0 && IS_NOT_NULL(nd = NCDR(nd)));
4975 r = optimize_node_left(NCAR(nd), &nopt, env);
4977 if (nd == node) copy_node_opt_info(opt, &nopt);
4978 else alt_merge_node_opt_info(opt, &nopt, env);
4980 }
while ((r == 0) && IS_NOT_NULL(nd = NCDR(nd)));
4987 OnigDistance slen = sn->end - sn->s;
4988 int is_raw = NSTRING_IS_RAW(node);
4990 if (! NSTRING_IS_AMBIG(node)) {
4991 concat_opt_exact_info_str(&opt->exb, sn->s, sn->end,
4993 opt->exb.ignore_case = 0;
4995 add_char_opt_map_info(&opt->map, *(sn->s), env->enc);
4997 set_mml(&opt->len, slen, slen);
5002 if (NSTRING_IS_DONT_GET_OPT_INFO(node)) {
5003 int n = onigenc_strlen(env->enc, sn->s, sn->end);
5004 max = (OnigDistance )ONIGENC_MBC_MAXLEN_DIST(env->enc) * (OnigDistance)n;
5007 concat_opt_exact_info_str(&opt->exb, sn->s, sn->end,
5009 opt->exb.ignore_case = 1;
5012 r = add_char_amb_opt_map_info(&opt->map, sn->s, sn->end,
5013 env->enc, env->case_fold_flag);
5020 set_mml(&opt->len, slen, max);
5023 if ((OnigDistance )opt->exb.len == slen)
5024 opt->exb.reach_end = 1;
5035 if (IS_NOT_NULL(cc->mbuf) || IS_NCCLASS_NOT(cc)) {
5036 OnigDistance min = ONIGENC_MBC_MINLEN(env->enc);
5037 OnigDistance max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
5039 set_mml(&opt->len, min, max);
5042 for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
5043 z = BITSET_AT(cc->bs, i);
5044 if ((z && !IS_NCCLASS_NOT(cc)) || (!z && IS_NCCLASS_NOT(cc))) {
5045 add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
5048 set_mml(&opt->len, 1, 1);
5058 max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
5063 maxcode = NCTYPE(node)->ascii_range ? 0x80 : SINGLE_BYTE_SIZE;
5064 switch (NCTYPE(node)->ctype) {
5065 case ONIGENC_CTYPE_WORD:
5066 if (NCTYPE(node)->not != 0) {
5067 for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
5068 if (! ONIGENC_IS_CODE_WORD(env->enc, i) || i >= maxcode) {
5069 add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
5074 for (i = 0; i < maxcode; i++) {
5075 if (ONIGENC_IS_CODE_WORD(env->enc, i)) {
5076 add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
5084 min = ONIGENC_MBC_MINLEN(env->enc);
5086 set_mml(&opt->len, min, max);
5092 OnigDistance min = ONIGENC_MBC_MINLEN(env->enc);
5093 OnigDistance max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
5094 set_mml(&opt->len, min, max);
5099 switch (NANCHOR(node)->type) {
5100 case ANCHOR_BEGIN_BUF:
5101 case ANCHOR_BEGIN_POSITION:
5102 case ANCHOR_BEGIN_LINE:
5103 case ANCHOR_END_BUF:
5104 case ANCHOR_SEMI_END_BUF:
5105 case ANCHOR_END_LINE:
5106 case ANCHOR_LOOK_BEHIND:
5107 case ANCHOR_PREC_READ_NOT:
5108 add_opt_anc_info(&opt->anc, NANCHOR(node)->type);
5111 case ANCHOR_PREC_READ:
5115 r = optimize_node_left(NANCHOR(node)->target, &nopt, env);
5117 if (nopt.exb.len > 0)
5118 copy_opt_exact_info(&opt->expr, &nopt.exb);
5119 else if (nopt.exm.len > 0)
5120 copy_opt_exact_info(&opt->expr, &nopt.exm);
5122 opt->expr.reach_end = 0;
5124 if (nopt.map.value > 0)
5125 copy_opt_map_info(&opt->map, &nopt.map);
5130 case ANCHOR_LOOK_BEHIND_NOT:
5139 OnigDistance min, max, tmin, tmax;
5140 Node** nodes = SCANENV_MEM_NODES(env->scan_env);
5143 if (br->state & NST_RECURSION) {
5144 set_mml(&opt->len, 0, ONIG_INFINITE_DISTANCE);
5147 backs = BACKREFS_P(br);
5148 r = get_min_match_length(nodes[backs[0]], &min, env->scan_env);
5150 r = get_max_match_length(nodes[backs[0]], &max, env->scan_env);
5152 for (i = 1; i < br->back_num; i++) {
5153 r = get_min_match_length(nodes[backs[i]], &tmin, env->scan_env);
5155 r = get_max_match_length(nodes[backs[i]], &tmax, env->scan_env);
5157 if (min > tmin) min = tmin;
5158 if (max < tmax) max = tmax;
5160 if (r == 0) set_mml(&opt->len, min, max);
5164#ifdef USE_SUBEXP_CALL
5166 if (IS_CALL_RECURSION(NCALL(node)))
5167 set_mml(&opt->len, 0, ONIG_INFINITE_DISTANCE);
5169 OnigOptionType save = env->options;
5170 env->options = NENCLOSE(NCALL(node)->target)->option;
5171 r = optimize_node_left(NCALL(node)->target, opt, env);
5172 env->options = save;
5180 OnigDistance min, max;
5184 r = optimize_node_left(qn->target, &nopt, env);
5187 if (qn->lower == 0 && IS_REPEAT_INFINITE(qn->upper)) {
5188 if (env->mmd.max == 0 &&
5189 NTYPE(qn->target) == NT_CANY && qn->greedy) {
5190 if (IS_MULTILINE(env->options))
5192 add_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR_ML);
5194 add_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR);
5198 if (qn->lower > 0) {
5199 copy_node_opt_info(opt, &nopt);
5200 if (nopt.exb.len > 0) {
5201 if (nopt.exb.reach_end) {
5202 for (i = 2; i <= qn->lower &&
5203 ! is_full_opt_exact_info(&opt->exb); i++) {
5204 concat_opt_exact_info(&opt->exb, &nopt.exb, env->enc);
5206 if (i < qn->lower) {
5207 opt->exb.reach_end = 0;
5212 if (qn->lower != qn->upper) {
5213 opt->exb.reach_end = 0;
5214 opt->exm.reach_end = 0;
5217 opt->exm.reach_end = 0;
5221 min = distance_multiply(nopt.len.min, qn->lower);
5222 if (IS_REPEAT_INFINITE(qn->upper))
5223 max = (nopt.len.max > 0 ? ONIG_INFINITE_DISTANCE : 0);
5225 max = distance_multiply(nopt.len.max, qn->upper);
5227 set_mml(&opt->len, min, max);
5236 case ENCLOSE_OPTION:
5238 OnigOptionType save = env->options;
5240 env->options = en->option;
5241 r = optimize_node_left(en->target, opt, env);
5242 env->options = save;
5246 case ENCLOSE_MEMORY:
5247#ifdef USE_SUBEXP_CALL
5249 if (en->opt_count > MAX_NODE_OPT_INFO_REF_COUNT) {
5250 OnigDistance min, max;
5253 max = ONIG_INFINITE_DISTANCE;
5254 if (IS_ENCLOSE_MIN_FIXED(en)) min = en->min_len;
5255 if (IS_ENCLOSE_MAX_FIXED(en)) max = en->max_len;
5256 set_mml(&opt->len, min, max);
5261 r = optimize_node_left(en->target, opt, env);
5263 if (is_set_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR_MASK)) {
5264 if (BIT_STATUS_AT(env->scan_env->backrefed_mem, en->regnum))
5265 remove_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR_MASK);
5270 case ENCLOSE_STOP_BACKTRACK:
5271 case ENCLOSE_CONDITION:
5272 r = optimize_node_left(en->target, opt, env);
5275 case ENCLOSE_ABSENT:
5276 set_mml(&opt->len, 0, ONIG_INFINITE_DISTANCE);
5284 fprintf(stderr,
"optimize_node_left: undefined node type %d\n",
5287 r = ONIGERR_TYPE_BUG;
5299 if (e->len == 0)
return 0;
5301 reg->exact = (UChar* )
xmalloc(e->len);
5302 CHECK_NULL_RETURN_MEMERR(reg->exact);
5303 xmemcpy(reg->exact, e->s, e->len);
5304 reg->exact_end = reg->exact + e->len;
5307 ONIGENC_IS_ALLOWED_REVERSE_MATCH(reg->enc, reg->exact, reg->exact_end);
5309 if (e->ignore_case > 0) {
5310 if (e->len >= 3 || (e->len >= 2 && allow_reverse)) {
5311 int orig_len = e->len;
5312 e->len = set_bm_skip(reg->exact, reg->exact_end, reg,
5313 reg->map, &(reg->int_map), 1);
5315 reg->exact_end = reg->exact + e->len;
5316 reg->optimize = (allow_reverse != 0
5317 ? ONIG_OPTIMIZE_EXACT_BM_IC : ONIG_OPTIMIZE_EXACT_BM_NOT_REV_IC);
5327 reg->optimize = ONIG_OPTIMIZE_EXACT_IC;
5331 reg->optimize = ONIG_OPTIMIZE_EXACT_IC;
5335 if (e->len >= 3 || (e->len >= 2 && allow_reverse)) {
5336 set_bm_skip(reg->exact, reg->exact_end, reg,
5337 reg->map, &(reg->int_map), 0);
5338 reg->optimize = (allow_reverse != 0
5339 ? ONIG_OPTIMIZE_EXACT_BM : ONIG_OPTIMIZE_EXACT_BM_NOT_REV);
5342 reg->optimize = ONIG_OPTIMIZE_EXACT;
5346 reg->dmin = e->mmd.min;
5347 reg->dmax = e->mmd.max;
5349 if (reg->dmin != ONIG_INFINITE_DISTANCE) {
5350 reg->threshold_len = (int )(reg->dmin + (reg->exact_end - reg->exact));
5357set_optimize_map_info(regex_t* reg,
OptMapInfo* m)
5361 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
5362 reg->map[i] = m->map[i];
5364 reg->optimize = ONIG_OPTIMIZE_MAP;
5365 reg->dmin = m->mmd.min;
5366 reg->dmax = m->mmd.max;
5368 if (reg->dmin != ONIG_INFINITE_DISTANCE) {
5369 reg->threshold_len = (int )(reg->dmin + 1);
5376 reg->sub_anchor |= anc->left_anchor & ANCHOR_BEGIN_LINE;
5377 reg->sub_anchor |= anc->right_anchor & ANCHOR_END_LINE;
5380#if defined(ONIG_DEBUG_COMPILE) || defined(ONIG_DEBUG_MATCH)
5381static void print_optimize_info(FILE* f, regex_t* reg);
5385set_optimize_info_from_tree(Node* node, regex_t* reg,
ScanEnv* scan_env)
5393 env.options = reg->options;
5394 env.case_fold_flag = reg->case_fold_flag;
5395 env.scan_env = scan_env;
5396 clear_mml(&env.mmd);
5398 r = optimize_node_left(node, &opt, &env);
5401 reg->anchor = opt.anc.left_anchor & (ANCHOR_BEGIN_BUF |
5402 ANCHOR_BEGIN_POSITION | ANCHOR_ANYCHAR_STAR | ANCHOR_ANYCHAR_STAR_ML |
5403 ANCHOR_LOOK_BEHIND);
5405 if ((opt.anc.left_anchor & (ANCHOR_LOOK_BEHIND | ANCHOR_PREC_READ_NOT)) != 0)
5406 reg->anchor &= ~ANCHOR_ANYCHAR_STAR_ML;
5408 reg->anchor |= opt.anc.right_anchor & (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF |
5409 ANCHOR_PREC_READ_NOT);
5411 if (reg->anchor & (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF)) {
5412 reg->anchor_dmin = opt.len.min;
5413 reg->anchor_dmax = opt.len.max;
5416 if (opt.exb.len > 0 || opt.exm.len > 0) {
5417 select_opt_exact_info(reg->enc, &opt.exb, &opt.exm);
5418 if (opt.map.value > 0 &&
5419 comp_opt_exact_or_map_info(&opt.exb, &opt.map) > 0) {
5423 r = set_optimize_exact_info(reg, &opt.exb);
5424 set_sub_anchor(reg, &opt.exb.anc);
5427 else if (opt.map.value > 0) {
5429 set_optimize_map_info(reg, &opt.map);
5430 set_sub_anchor(reg, &opt.map.anc);
5433 reg->sub_anchor |= opt.anc.left_anchor & ANCHOR_BEGIN_LINE;
5434 if (opt.len.max == 0)
5435 reg->sub_anchor |= opt.anc.right_anchor & ANCHOR_END_LINE;
5438#if defined(ONIG_DEBUG_COMPILE) || defined(ONIG_DEBUG_MATCH)
5439 print_optimize_info(stderr, reg);
5445clear_optimize_info(regex_t* reg)
5447 reg->optimize = ONIG_OPTIMIZE_NONE;
5449 reg->anchor_dmin = 0;
5450 reg->anchor_dmax = 0;
5451 reg->sub_anchor = 0;
5452 reg->exact_end = (UChar* )NULL;
5453 reg->threshold_len = 0;
5455 reg->exact = (UChar* )NULL;
5460static void print_enc_string(FILE* fp, OnigEncoding enc,
5461 const UChar *s,
const UChar *end)
5463 fprintf(fp,
"\nPATTERN: /");
5465 if (ONIGENC_MBC_MINLEN(enc) > 1) {
5471 code = ONIGENC_MBC_TO_CODE(enc, p, end);
5473 fprintf(fp,
" 0x%04x ", (
int )code);
5476 fputc((
int )code, fp);
5479 p += enclen(enc, p, end);
5484 fputc((
int )*s, fp);
5489 fprintf(fp,
"/ (%s)\n", enc->name);
5493#if defined(ONIG_DEBUG_COMPILE) || defined(ONIG_DEBUG_MATCH)
5495print_distance_range(FILE* f, OnigDistance a, OnigDistance b)
5497 if (a == ONIG_INFINITE_DISTANCE)
5500 fprintf(f,
"(%"PRIuPTR
")", a);
5504 if (b == ONIG_INFINITE_DISTANCE)
5507 fprintf(f,
"(%"PRIuPTR
")", b);
5511print_anchor(FILE* f,
int anchor)
5517 if (anchor & ANCHOR_BEGIN_BUF) {
5518 fprintf(f,
"begin-buf");
5521 if (anchor & ANCHOR_BEGIN_LINE) {
5522 if (q) fprintf(f,
", ");
5524 fprintf(f,
"begin-line");
5526 if (anchor & ANCHOR_BEGIN_POSITION) {
5527 if (q) fprintf(f,
", ");
5529 fprintf(f,
"begin-pos");
5531 if (anchor & ANCHOR_END_BUF) {
5532 if (q) fprintf(f,
", ");
5534 fprintf(f,
"end-buf");
5536 if (anchor & ANCHOR_SEMI_END_BUF) {
5537 if (q) fprintf(f,
", ");
5539 fprintf(f,
"semi-end-buf");
5541 if (anchor & ANCHOR_END_LINE) {
5542 if (q) fprintf(f,
", ");
5544 fprintf(f,
"end-line");
5546 if (anchor & ANCHOR_ANYCHAR_STAR) {
5547 if (q) fprintf(f,
", ");
5549 fprintf(f,
"anychar-star");
5551 if (anchor & ANCHOR_ANYCHAR_STAR_ML) {
5552 if (q) fprintf(f,
", ");
5553 fprintf(f,
"anychar-star-ml");
5560print_optimize_info(FILE* f, regex_t* reg)
5562 static const char* on[] = {
"NONE",
"EXACT",
"EXACT_BM",
"EXACT_BM_NOT_REV",
5564 "EXACT_BM_IC",
"EXACT_BM_NOT_REV_IC" };
5566 fprintf(f,
"optimize: %s\n", on[reg->optimize]);
5567 fprintf(f,
" anchor: "); print_anchor(f, reg->anchor);
5568 if ((reg->anchor & ANCHOR_END_BUF_MASK) != 0)
5569 print_distance_range(f, reg->anchor_dmin, reg->anchor_dmax);
5572 if (reg->optimize) {
5573 fprintf(f,
" sub anchor: "); print_anchor(f, reg->sub_anchor);
5580 fprintf(f,
"exact: [");
5581 for (p = reg->exact; p < reg->exact_end; p++) {
5584 fprintf(f,
"]: length: %"PRIdPTR
"\n", (reg->exact_end - reg->exact));
5586 else if (reg->optimize & ONIG_OPTIMIZE_MAP) {
5589 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
5590 if (reg->map[i]) n++;
5592 fprintf(f,
"map: n=%d\n", n);
5596 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) {
5597 if (reg->map[i] != 0) {
5598 if (c > 0) fputs(
", ", f);
5600 if (ONIGENC_MBC_MAXLEN(reg->enc) == 1 &&
5601 ONIGENC_IS_CODE_PRINT(reg->enc, (OnigCodePoint )i))
5604 fprintf(f,
"%d", i);
5615onig_free_body(regex_t* reg)
5617 if (IS_NOT_NULL(reg)) {
5620 xfree(reg->int_map);
5621 xfree(reg->int_map_backward);
5622 xfree(reg->repeat_range);
5623 onig_free(reg->chain);
5625#ifdef USE_NAMED_GROUP
5626 onig_names_free(reg);
5632onig_free(regex_t* reg)
5634 if (IS_NOT_NULL(reg)) {
5635 onig_free_body(reg);
5641dup_copy(
const void *
ptr,
size_t size)
5644 if (IS_NOT_NULL(newptr)) {
5645 memcpy(newptr,
ptr, size);
5651onig_reg_copy(regex_t** nreg, regex_t* oreg)
5653 if (IS_NOT_NULL(oreg)) {
5654 regex_t *reg = *nreg = (regex_t* )
xmalloc(
sizeof(regex_t));
5655 if (IS_NULL(reg))
return ONIGERR_MEMORY;
5659# define COPY_FAILED(mem, size) IS_NULL(reg->mem = dup_copy(reg->mem, size))
5661 if (IS_NOT_NULL(reg->exact)) {
5662 size_t exact_size = reg->exact_end - reg->exact;
5663 if (COPY_FAILED(exact, exact_size))
5665 (reg)->exact_end = (reg)->exact + exact_size;
5668 if (IS_NOT_NULL(reg->int_map)) {
5669 if (COPY_FAILED(int_map,
sizeof(
int) * ONIG_CHAR_TABLE_SIZE))
5672 if (IS_NOT_NULL(reg->int_map_backward)) {
5673 if (COPY_FAILED(int_map_backward,
sizeof(
int) * ONIG_CHAR_TABLE_SIZE))
5674 goto err_int_map_backward;
5676 if (IS_NOT_NULL(reg->p)) {
5677 if (COPY_FAILED(p, reg->alloc))
5680 if (IS_NOT_NULL(reg->repeat_range)) {
5681 if (COPY_FAILED(repeat_range, reg->repeat_range_alloc *
sizeof(
OnigRepeatRange)))
5682 goto err_repeat_range;
5684 if (IS_NOT_NULL(reg->name_table)) {
5685 if (onig_names_copy(reg, oreg))
5686 goto err_name_table;
5688 if (IS_NOT_NULL(reg->chain)) {
5689 if (onig_reg_copy(®->chain, reg->chain))
5696 onig_names_free(reg);
5698 xfree(reg->repeat_range);
5702 xfree(reg->int_map_backward);
5703 err_int_map_backward:
5704 xfree(reg->int_map);
5709 return ONIGERR_MEMORY;
5716onig_memsize(
const regex_t *reg)
5718 size_t size =
sizeof(regex_t);
5719 if (IS_NULL(reg))
return 0;
5720 if (IS_NOT_NULL(reg->p)) size += reg->alloc;
5721 if (IS_NOT_NULL(reg->exact)) size += reg->exact_end - reg->exact;
5722 if (IS_NOT_NULL(reg->int_map)) size +=
sizeof(int) * ONIG_CHAR_TABLE_SIZE;
5723 if (IS_NOT_NULL(reg->int_map_backward)) size +=
sizeof(int) * ONIG_CHAR_TABLE_SIZE;
5724 if (IS_NOT_NULL(reg->repeat_range)) size += reg->repeat_range_alloc *
sizeof(
OnigRepeatRange);
5725 if (IS_NOT_NULL(reg->chain)) size += onig_memsize(reg->chain);
5731onig_region_memsize(
const OnigRegion *regs)
5733 size_t size =
sizeof(*regs);
5734 if (IS_NULL(regs))
return 0;
5735 size += regs->allocated * (
sizeof(*regs->beg) +
sizeof(*regs->end));
5740#define REGEX_TRANSFER(to,from) do {\
5741 onig_free_body(to);\
5742 xmemcpy(to, from, sizeof(regex_t));\
5748onig_transfer(regex_t* to, regex_t* from)
5750 REGEX_TRANSFER(to, from);
5754#ifdef ONIG_DEBUG_COMPILE
5755static void print_compiled_byte_code_list(FILE* f, regex_t* reg);
5757#ifdef ONIG_DEBUG_PARSE_TREE
5758static void print_tree(FILE* f, Node* node);
5763onig_compile(regex_t* reg,
const UChar* pattern,
const UChar* pattern_end,
5766 return onig_compile_ruby(reg, pattern, pattern_end, einfo, NULL, 0);
5772onig_compile_ruby(regex_t* reg,
const UChar* pattern,
const UChar* pattern_end,
5773 OnigErrorInfo* einfo,
const char *sourcefile,
int sourceline)
5776onig_compile(regex_t* reg,
const UChar* pattern,
const UChar* pattern_end,
5780#define COMPILE_INIT_SIZE 20
5783 OnigDistance init_size;
5786#ifdef USE_SUBEXP_CALL
5790 if (IS_NOT_NULL(einfo)) einfo->par = (UChar* )NULL;
5793 scan_env.sourcefile = sourcefile;
5794 scan_env.sourceline = sourceline;
5798 print_enc_string(stderr, reg->enc, pattern, pattern_end);
5801 if (reg->alloc == 0) {
5802 init_size = (pattern_end - pattern) * 2;
5803 if (init_size <= 0) init_size = COMPILE_INIT_SIZE;
5804 r = BBUF_INIT(reg, init_size);
5805 if (r != 0)
goto end;
5811 reg->num_repeat = 0;
5812 reg->num_null_check = 0;
5813 reg->repeat_range_alloc = 0;
5815#ifdef USE_COMBINATION_EXPLOSION_CHECK
5816 reg->num_comb_exp_check = 0;
5819 r = onig_parse_make_tree(&root, pattern, pattern_end, reg, &scan_env);
5820 if (r != 0)
goto err;
5822#ifdef ONIG_DEBUG_PARSE_TREE
5824 fprintf(stderr,
"ORIGINAL PARSE TREE:\n");
5825 print_tree(stderr, root);
5829#ifdef USE_NAMED_GROUP
5831 if (scan_env.num_named > 0 &&
5832 IS_SYNTAX_BV(scan_env.syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
5833 !ONIG_IS_OPTION_ON(reg->options, ONIG_OPTION_CAPTURE_GROUP)) {
5834 if (scan_env.num_named != scan_env.num_mem)
5835 r = disable_noname_group_capture(&root, reg, &scan_env);
5837 r = numbered_ref_check(root);
5839 if (r != 0)
goto err;
5843#ifdef USE_SUBEXP_CALL
5844 if (scan_env.num_call > 0) {
5845 r = unset_addr_list_init(&uslist, scan_env.num_call);
5846 if (r != 0)
goto err;
5847 scan_env.unset_addr_list = &uslist;
5848 r = setup_subexp_call(root, &scan_env);
5849 if (r != 0)
goto err_unset;
5850 r = subexp_recursive_check_trav(root, &scan_env);
5851 if (r < 0)
goto err_unset;
5852 r = subexp_inf_recursive_check_trav(root, &scan_env);
5853 if (r != 0)
goto err_unset;
5855 reg->num_call = scan_env.num_call;
5861 r = setup_tree(root, reg, 0, &scan_env);
5862 if (r != 0)
goto err_unset;
5864#ifdef ONIG_DEBUG_PARSE_TREE
5865 print_tree(stderr, root);
5868 reg->capture_history = scan_env.capture_history;
5869 reg->bt_mem_start = scan_env.bt_mem_start;
5870 reg->bt_mem_start |= reg->capture_history;
5871 if (IS_FIND_CONDITION(reg->options))
5872 BIT_STATUS_ON_ALL(reg->bt_mem_end);
5874 reg->bt_mem_end = scan_env.bt_mem_end;
5875 reg->bt_mem_end |= reg->capture_history;
5878#ifdef USE_COMBINATION_EXPLOSION_CHECK
5879 if (scan_env.backrefed_mem == 0
5880# ifdef USE_SUBEXP_CALL
5881 || scan_env.num_call == 0
5884 setup_comb_exp_check(root, 0, &scan_env);
5885# ifdef USE_SUBEXP_CALL
5886 if (scan_env.has_recursion != 0) {
5887 scan_env.num_comb_exp_check = 0;
5891 if (scan_env.comb_exp_max_regnum > 0) {
5893 for (i = 1; i <= scan_env.comb_exp_max_regnum; i++) {
5894 if (BIT_STATUS_AT(scan_env.backrefed_mem, i) != 0) {
5895 scan_env.num_comb_exp_check = 0;
5902 reg->num_comb_exp_check = scan_env.num_comb_exp_check;
5905 clear_optimize_info(reg);
5906#ifndef ONIG_DONT_OPTIMIZE
5907 r = set_optimize_info_from_tree(root, reg, &scan_env);
5908 if (r != 0)
goto err_unset;
5911 if (IS_NOT_NULL(scan_env.mem_nodes_dynamic)) {
5912 xfree(scan_env.mem_nodes_dynamic);
5913 scan_env.mem_nodes_dynamic = (Node** )NULL;
5916 r = compile_tree(root, reg);
5918 r = add_opcode(reg, OP_END);
5919 if (r != 0)
goto err_unset;
5920#ifdef USE_SUBEXP_CALL
5921 if (scan_env.num_call > 0) {
5922 r = unset_addr_list_fix(&uslist, reg);
5923 unset_addr_list_end(&uslist);
5928 if ((reg->num_repeat != 0) || (reg->bt_mem_end != 0))
5929 reg->stack_pop_level = STACK_POP_LEVEL_ALL;
5931 if (reg->bt_mem_start != 0)
5932 reg->stack_pop_level = STACK_POP_LEVEL_MEM_START;
5934 reg->stack_pop_level = STACK_POP_LEVEL_FREE;
5937#ifdef USE_SUBEXP_CALL
5938 else if (scan_env.num_call > 0) {
5939 unset_addr_list_end(&uslist);
5942 onig_node_free(root);
5944#ifdef ONIG_DEBUG_COMPILE
5945# ifdef USE_NAMED_GROUP
5946 onig_print_names(stderr, reg);
5948 print_compiled_byte_code_list(stderr, reg);
5952 onig_reg_resize(reg);
5956#ifdef USE_SUBEXP_CALL
5957 if (scan_env.num_call > 0) {
5958 unset_addr_list_end(&uslist);
5962 if (IS_NOT_NULL(scan_env.error)) {
5963 if (IS_NOT_NULL(einfo)) {
5964 einfo->enc = scan_env.enc;
5965 einfo->par = scan_env.error;
5966 einfo->par_end = scan_env.error_end;
5970 onig_node_free(root);
5971 xfree(scan_env.mem_nodes_dynamic);
5976static int onig_inited = 0;
5979onig_reg_init(regex_t* reg, OnigOptionType option,
5980 OnigCaseFoldType case_fold_flag,
5987 return ONIGERR_INVALID_ARGUMENT;
5989 if (ONIGENC_IS_UNDEF(enc))
5990 return ONIGERR_DEFAULT_ENCODING_IS_NOT_SET;
5992 if ((option & (ONIG_OPTION_DONT_CAPTURE_GROUP|ONIG_OPTION_CAPTURE_GROUP))
5993 == (ONIG_OPTION_DONT_CAPTURE_GROUP|ONIG_OPTION_CAPTURE_GROUP)) {
5994 return ONIGERR_INVALID_COMBINATION_OF_OPTIONS;
5997 if ((option & ONIG_OPTION_NEGATE_SINGLELINE) != 0) {
5998 option |= syntax->options;
5999 option &= ~ONIG_OPTION_SINGLELINE;
6002 option |= syntax->options;
6005 (reg)->options = option;
6006 (reg)->syntax = syntax;
6007 (reg)->optimize = 0;
6008 (reg)->exact = (UChar* )NULL;
6009 (reg)->int_map = (
int* )NULL;
6010 (reg)->int_map_backward = (
int* )NULL;
6011 (reg)->chain = (regex_t* )NULL;
6013 (reg)->p = (UChar* )NULL;
6016 (reg)->name_table = (
void* )NULL;
6018 (reg)->case_fold_flag = case_fold_flag;
6020 (reg)->timelimit = 0;
6026onig_new_without_alloc(regex_t* reg,
const UChar* pattern,
6027 const UChar* pattern_end, OnigOptionType option, OnigEncoding enc,
6032 r = onig_reg_init(reg, option, ONIGENC_CASE_FOLD_DEFAULT, enc, syntax);
6035 r = onig_compile(reg, pattern, pattern_end, einfo);
6040onig_new(regex_t** reg,
const UChar* pattern,
const UChar* pattern_end,
6041 OnigOptionType option, OnigEncoding enc,
const OnigSyntaxType* syntax,
6044 *reg = (regex_t* )
xmalloc(
sizeof(regex_t));
6045 if (IS_NULL(*reg))
return ONIGERR_MEMORY;
6047 int r = onig_new_without_alloc(*reg, pattern, pattern_end, option, enc, syntax, einfo);
6057onig_initialize(OnigEncoding encodings[] ARG_UNUSED,
int n ARG_UNUSED)
6065 if (onig_inited != 0)
6070#if defined(ONIG_DEBUG_MEMLEAK) && defined(_MSC_VER)
6071 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
6077#ifdef ONIG_DEBUG_STATISTICS
6078 onig_statistics_init();
6085static OnigEndCallListItemType* EndCallTop;
6087extern void onig_add_end_call(
void (*func)(
void))
6089 OnigEndCallListItemType* item;
6091 item = (OnigEndCallListItemType* )
xmalloc(
sizeof(*item));
6092 if (item == 0) return ;
6094 item->next = EndCallTop;
6101exec_end_call_list(
void)
6103 OnigEndCallListItemType* prev;
6106 while (EndCallTop != 0) {
6107 func = EndCallTop->func;
6111 EndCallTop = EndCallTop->next;
6119 exec_end_call_list();
6121#ifdef ONIG_DEBUG_STATISTICS
6122 onig_print_statistics(stderr);
6125#if defined(ONIG_DEBUG_MEMLEAK) && defined(_MSC_VER)
6126 _CrtDumpMemoryLeaks();
6135onig_is_in_code_range(
const UChar* p, OnigCodePoint code)
6137 OnigCodePoint n, *data;
6138 OnigCodePoint low, high, x;
6140 GET_CODE_POINT(n, p);
6141 data = (OnigCodePoint* )p;
6144 for (low = 0, high = n; low < high; ) {
6145 x = (low + high) >> 1;
6146 if (code > data[x * 2 + 1])
6152 return ((low < n && code >= data[low * 2]) ? 1 : 0);
6156onig_is_code_in_cc_len(
int elen, OnigCodePoint code,
CClassNode* cc)
6160 if (elen > 1 || (code >= SINGLE_BYTE_SIZE)) {
6161 if (IS_NULL(cc->mbuf)) {
6165 found = (onig_is_in_code_range(cc->mbuf->p, code) != 0 ? 1 : 0);
6169 found = (BITSET_AT(cc->bs, code) == 0 ? 0 : 1);
6172 if (IS_NCCLASS_NOT(cc))
6179onig_is_code_in_cc(OnigEncoding enc, OnigCodePoint code,
CClassNode* cc)
6183 if (ONIGENC_MBC_MINLEN(enc) > 1) {
6187 len = ONIGENC_CODE_TO_MBCLEN(enc, code);
6189 return onig_is_code_in_cc_len(
len, code, cc);
6196# define ARG_SPECIAL -1
6198# define ARG_RELADDR 1
6199# define ARG_ABSADDR 2
6200# define ARG_LENGTH 3
6201# define ARG_MEMNUM 4
6202# define ARG_OPTION 5
6203# define ARG_STATE_CHECK 6
6205OnigOpInfoType OnigOpInfo[] = {
6206 { OP_FINISH,
"finish", ARG_NON },
6207 { OP_END,
"end", ARG_NON },
6208 { OP_EXACT1,
"exact1", ARG_SPECIAL },
6209 { OP_EXACT2,
"exact2", ARG_SPECIAL },
6210 { OP_EXACT3,
"exact3", ARG_SPECIAL },
6211 { OP_EXACT4,
"exact4", ARG_SPECIAL },
6212 { OP_EXACT5,
"exact5", ARG_SPECIAL },
6213 { OP_EXACTN,
"exactn", ARG_SPECIAL },
6214 { OP_EXACTMB2N1,
"exactmb2-n1", ARG_SPECIAL },
6215 { OP_EXACTMB2N2,
"exactmb2-n2", ARG_SPECIAL },
6216 { OP_EXACTMB2N3,
"exactmb2-n3", ARG_SPECIAL },
6217 { OP_EXACTMB2N,
"exactmb2-n", ARG_SPECIAL },
6218 { OP_EXACTMB3N,
"exactmb3n" , ARG_SPECIAL },
6219 { OP_EXACTMBN,
"exactmbn", ARG_SPECIAL },
6220 { OP_EXACT1_IC,
"exact1-ic", ARG_SPECIAL },
6221 { OP_EXACTN_IC,
"exactn-ic", ARG_SPECIAL },
6222 { OP_CCLASS,
"cclass", ARG_SPECIAL },
6223 { OP_CCLASS_MB,
"cclass-mb", ARG_SPECIAL },
6224 { OP_CCLASS_MIX,
"cclass-mix", ARG_SPECIAL },
6225 { OP_CCLASS_NOT,
"cclass-not", ARG_SPECIAL },
6226 { OP_CCLASS_MB_NOT,
"cclass-mb-not", ARG_SPECIAL },
6227 { OP_CCLASS_MIX_NOT,
"cclass-mix-not", ARG_SPECIAL },
6228 { OP_ANYCHAR,
"anychar", ARG_NON },
6229 { OP_ANYCHAR_ML,
"anychar-ml", ARG_NON },
6230 { OP_ANYCHAR_STAR,
"anychar*", ARG_NON },
6231 { OP_ANYCHAR_ML_STAR,
"anychar-ml*", ARG_NON },
6232 { OP_ANYCHAR_STAR_PEEK_NEXT,
"anychar*-peek-next", ARG_SPECIAL },
6233 { OP_ANYCHAR_ML_STAR_PEEK_NEXT,
"anychar-ml*-peek-next", ARG_SPECIAL },
6234 { OP_WORD,
"word", ARG_NON },
6235 { OP_NOT_WORD,
"not-word", ARG_NON },
6236 { OP_WORD_BOUND,
"word-bound", ARG_NON },
6237 { OP_NOT_WORD_BOUND,
"not-word-bound", ARG_NON },
6238 { OP_WORD_BEGIN,
"word-begin", ARG_NON },
6239 { OP_WORD_END,
"word-end", ARG_NON },
6240 { OP_ASCII_WORD,
"ascii-word", ARG_NON },
6241 { OP_NOT_ASCII_WORD,
"not-ascii-word", ARG_NON },
6242 { OP_ASCII_WORD_BOUND,
"ascii-word-bound", ARG_NON },
6243 { OP_NOT_ASCII_WORD_BOUND,
"not-ascii-word-bound", ARG_NON },
6244 { OP_ASCII_WORD_BEGIN,
"ascii-word-begin", ARG_NON },
6245 { OP_ASCII_WORD_END,
"ascii-word-end", ARG_NON },
6246 { OP_BEGIN_BUF,
"begin-buf", ARG_NON },
6247 { OP_END_BUF,
"end-buf", ARG_NON },
6248 { OP_BEGIN_LINE,
"begin-line", ARG_NON },
6249 { OP_END_LINE,
"end-line", ARG_NON },
6250 { OP_SEMI_END_BUF,
"semi-end-buf", ARG_NON },
6251 { OP_BEGIN_POSITION,
"begin-position", ARG_NON },
6252 { OP_BACKREF1,
"backref1", ARG_NON },
6253 { OP_BACKREF2,
"backref2", ARG_NON },
6254 { OP_BACKREFN,
"backrefn", ARG_MEMNUM },
6255 { OP_BACKREFN_IC,
"backrefn-ic", ARG_SPECIAL },
6256 { OP_BACKREF_MULTI,
"backref_multi", ARG_SPECIAL },
6257 { OP_BACKREF_MULTI_IC,
"backref_multi-ic", ARG_SPECIAL },
6258 { OP_BACKREF_WITH_LEVEL,
"backref_at_level", ARG_SPECIAL },
6259 { OP_MEMORY_START_PUSH,
"mem-start-push", ARG_MEMNUM },
6260 { OP_MEMORY_START,
"mem-start", ARG_MEMNUM },
6261 { OP_MEMORY_END_PUSH,
"mem-end-push", ARG_MEMNUM },
6262 { OP_MEMORY_END_PUSH_REC,
"mem-end-push-rec", ARG_MEMNUM },
6263 { OP_MEMORY_END,
"mem-end", ARG_MEMNUM },
6264 { OP_MEMORY_END_REC,
"mem-end-rec", ARG_MEMNUM },
6265 { OP_SET_OPTION_PUSH,
"set-option-push", ARG_OPTION },
6266 { OP_SET_OPTION,
"set-option", ARG_OPTION },
6267 { OP_KEEP,
"keep", ARG_NON },
6268 { OP_FAIL,
"fail", ARG_NON },
6269 { OP_JUMP,
"jump", ARG_RELADDR },
6270 { OP_PUSH,
"push", ARG_RELADDR },
6271 { OP_POP,
"pop", ARG_NON },
6272 { OP_PUSH_OR_JUMP_EXACT1,
"push-or-jump-e1", ARG_SPECIAL },
6273 { OP_PUSH_IF_PEEK_NEXT,
"push-if-peek-next", ARG_SPECIAL },
6274 { OP_REPEAT,
"repeat", ARG_SPECIAL },
6275 { OP_REPEAT_NG,
"repeat-ng", ARG_SPECIAL },
6276 { OP_REPEAT_INC,
"repeat-inc", ARG_MEMNUM },
6277 { OP_REPEAT_INC_NG,
"repeat-inc-ng", ARG_MEMNUM },
6278 { OP_REPEAT_INC_SG,
"repeat-inc-sg", ARG_MEMNUM },
6279 { OP_REPEAT_INC_NG_SG,
"repeat-inc-ng-sg", ARG_MEMNUM },
6280 { OP_NULL_CHECK_START,
"null-check-start", ARG_MEMNUM },
6281 { OP_NULL_CHECK_END,
"null-check-end", ARG_MEMNUM },
6282 { OP_NULL_CHECK_END_MEMST,
"null-check-end-memst", ARG_MEMNUM },
6283 { OP_NULL_CHECK_END_MEMST_PUSH,
"null-check-end-memst-push", ARG_MEMNUM },
6284 { OP_PUSH_POS,
"push-pos", ARG_NON },
6285 { OP_POP_POS,
"pop-pos", ARG_NON },
6286 { OP_PUSH_POS_NOT,
"push-pos-not", ARG_RELADDR },
6287 { OP_FAIL_POS,
"fail-pos", ARG_NON },
6288 { OP_PUSH_STOP_BT,
"push-stop-bt", ARG_NON },
6289 { OP_POP_STOP_BT,
"pop-stop-bt", ARG_NON },
6290 { OP_LOOK_BEHIND,
"look-behind", ARG_SPECIAL },
6291 { OP_PUSH_LOOK_BEHIND_NOT,
"push-look-behind-not", ARG_SPECIAL },
6292 { OP_FAIL_LOOK_BEHIND_NOT,
"fail-look-behind-not", ARG_NON },
6293 { OP_PUSH_ABSENT_POS,
"push-absent-pos", ARG_NON },
6294 { OP_ABSENT,
"absent", ARG_RELADDR },
6295 { OP_ABSENT_END,
"absent-end", ARG_NON },
6296 { OP_CALL,
"call", ARG_ABSADDR },
6297 { OP_RETURN,
"return", ARG_NON },
6298 { OP_CONDITION,
"condition", ARG_SPECIAL },
6299 { OP_STATE_CHECK_PUSH,
"state-check-push", ARG_SPECIAL },
6300 { OP_STATE_CHECK_PUSH_OR_JUMP,
"state-check-push-or-jump", ARG_SPECIAL },
6301 { OP_STATE_CHECK,
"state-check", ARG_STATE_CHECK },
6302 { OP_STATE_CHECK_ANYCHAR_STAR,
"state-check-anychar*", ARG_STATE_CHECK },
6303 { OP_STATE_CHECK_ANYCHAR_ML_STAR,
6304 "state-check-anychar-ml*", ARG_STATE_CHECK },
6313 for (i = 0; OnigOpInfo[i].opcode >= 0; i++) {
6314 if (opcode == OnigOpInfo[i].opcode)
6315 return OnigOpInfo[i].name;
6321op2arg_type(
int opcode)
6325 for (i = 0; OnigOpInfo[i].opcode >= 0; i++) {
6326 if (opcode == OnigOpInfo[i].opcode)
6327 return OnigOpInfo[i].arg_type;
6332# ifdef ONIG_DEBUG_PARSE_TREE
6334Indent(FILE* f,
int indent)
6337 for (i = 0; i < indent; i++) putc(
' ', f);
6342p_string(FILE* f, ptrdiff_t
len, UChar* s)
6345 while (
len-- > 0) { fputc(*s++, f); }
6349p_len_string(FILE* f, LengthType
len,
int mb_len, UChar* s)
6351 int x =
len * mb_len;
6353 fprintf(f,
":%d:",
len);
6354 while (x-- > 0) { fputc(*s++, f); }
6358onig_print_compiled_byte_code(FILE* f, UChar* bp, UChar* bpend, UChar** nextp,
6365 StateCheckNumType scn;
6369 fprintf(f,
"[%s", op2name(*bp));
6370 arg_type = op2arg_type(*bp);
6371 if (arg_type != ARG_SPECIAL) {
6377 GET_RELADDR_INC(addr, bp);
6378 fprintf(f,
":(%s%d)", (addr >= 0) ?
"+" :
"", addr);
6381 GET_ABSADDR_INC(addr, bp);
6382 fprintf(f,
":(%d)", addr);
6385 GET_LENGTH_INC(
len, bp);
6386 fprintf(f,
":%d",
len);
6389 mem = *((MemNumType* )bp);
6391 fprintf(f,
":%d", mem);
6395 OnigOptionType option = *((OnigOptionType* )bp);
6397 fprintf(f,
":%d", option);
6401 case ARG_STATE_CHECK:
6402 scn = *((StateCheckNumType* )bp);
6403 bp += SIZE_STATE_CHECK_NUM;
6404 fprintf(f,
":%d", scn);
6411 case OP_ANYCHAR_STAR_PEEK_NEXT:
6412 case OP_ANYCHAR_ML_STAR_PEEK_NEXT:
6413 p_string(f, 1, bp++);
break;
6415 p_string(f, 2, bp); bp += 2;
break;
6417 p_string(f, 3, bp); bp += 3;
break;
6419 p_string(f, 4, bp); bp += 4;
break;
6421 p_string(f, 5, bp); bp += 5;
break;
6423 GET_LENGTH_INC(
len, bp);
6424 p_len_string(f,
len, 1, bp);
6429 p_string(f, 2, bp); bp += 2;
break;
6431 p_string(f, 4, bp); bp += 4;
break;
6433 p_string(f, 6, bp); bp += 6;
break;
6435 GET_LENGTH_INC(
len, bp);
6436 p_len_string(f,
len, 2, bp);
6440 GET_LENGTH_INC(
len, bp);
6441 p_len_string(f,
len, 3, bp);
6448 GET_LENGTH_INC(mb_len, bp);
6449 GET_LENGTH_INC(
len, bp);
6450 fprintf(f,
":%d:%d:", mb_len,
len);
6452 while (n-- > 0) { fputc(*bp++, f); }
6457 len = enclen(enc, bp, bpend);
6458 p_string(f,
len, bp);
6462 GET_LENGTH_INC(
len, bp);
6463 p_len_string(f,
len, 1, bp);
6468 n = bitset_on_num((BitSetRef )bp);
6470 fprintf(f,
":%d", n);
6474 n = bitset_on_num((BitSetRef )bp);
6476 fprintf(f,
":%d", n);
6480 case OP_CCLASS_MB_NOT:
6481 GET_LENGTH_INC(
len, bp);
6483# ifndef PLATFORM_UNALIGNED_WORD_ACCESS
6486 GET_CODE_POINT(code, q);
6488 fprintf(f,
":%d:%d", (
int )code,
len);
6492 case OP_CCLASS_MIX_NOT:
6493 n = bitset_on_num((BitSetRef )bp);
6495 GET_LENGTH_INC(
len, bp);
6497# ifndef PLATFORM_UNALIGNED_WORD_ACCESS
6500 GET_CODE_POINT(code, q);
6502 fprintf(f,
":%d:%d:%d", n, (
int )code,
len);
6505 case OP_BACKREFN_IC:
6506 mem = *((MemNumType* )bp);
6508 fprintf(f,
":%d", mem);
6511 case OP_BACKREF_MULTI_IC:
6512 case OP_BACKREF_MULTI:
6514 GET_LENGTH_INC(
len, bp);
6515 for (i = 0; i <
len; i++) {
6516 GET_MEMNUM_INC(mem, bp);
6517 if (i > 0) fputs(
", ", f);
6518 fprintf(f,
"%d", mem);
6522 case OP_BACKREF_WITH_LEVEL:
6524 OnigOptionType option;
6527 GET_OPTION_INC(option, bp);
6528 fprintf(f,
":%d", option);
6529 GET_LENGTH_INC(level, bp);
6530 fprintf(f,
":%d", level);
6533 GET_LENGTH_INC(
len, bp);
6534 for (i = 0; i <
len; i++) {
6535 GET_MEMNUM_INC(mem, bp);
6536 if (i > 0) fputs(
", ", f);
6537 fprintf(f,
"%d", mem);
6545 mem = *((MemNumType* )bp);
6547 addr = *((RelAddrType* )bp);
6549 fprintf(f,
":%d:%d", mem, addr);
6553 case OP_PUSH_OR_JUMP_EXACT1:
6554 case OP_PUSH_IF_PEEK_NEXT:
6555 addr = *((RelAddrType* )bp);
6557 fprintf(f,
":(%s%d)", (addr >= 0) ?
"+" :
"", addr);
6562 case OP_LOOK_BEHIND:
6563 GET_LENGTH_INC(
len, bp);
6564 fprintf(f,
":%d",
len);
6567 case OP_PUSH_LOOK_BEHIND_NOT:
6568 GET_RELADDR_INC(addr, bp);
6569 GET_LENGTH_INC(
len, bp);
6570 fprintf(f,
":%d:(%s%d)",
len, (addr >= 0) ?
"+" :
"", addr);
6573 case OP_STATE_CHECK_PUSH:
6574 case OP_STATE_CHECK_PUSH_OR_JUMP:
6575 scn = *((StateCheckNumType* )bp);
6576 bp += SIZE_STATE_CHECK_NUM;
6577 addr = *((RelAddrType* )bp);
6579 fprintf(f,
":%d:(%s%d)", scn, (addr >= 0) ?
"+" :
"", addr);
6583 GET_MEMNUM_INC(mem, bp);
6584 GET_RELADDR_INC(addr, bp);
6585 fprintf(f,
":%d:(%s%d)", mem, (addr >= 0) ?
"+" :
"", addr);
6589 fprintf(stderr,
"onig_print_compiled_byte_code: undefined code %d\n",
6594 if (nextp) *nextp = bp;
6597# ifdef ONIG_DEBUG_COMPILE
6599print_compiled_byte_code_list(FILE* f, regex_t* reg)
6603 UChar* end = reg->p + reg->used;
6605 fprintf(f,
"code length: %d", reg->used);
6611 fprintf(f,
"\n%ld:", bp - reg->p);
6613 fprintf(f,
" %ld:", bp - reg->p);
6614 onig_print_compiled_byte_code(f, bp, end, &bp, reg->enc);
6621# ifdef ONIG_DEBUG_PARSE_TREE
6623print_indent_tree(FILE* f, Node* node,
int indent)
6625 int i,
type, container_p = 0;
6630 if (IS_NULL(node)) {
6631 fprintf(f,
"ERROR: null node!!!\n");
6639 if (NTYPE(node) == NT_LIST)
6640 fprintf(f,
"<list:%"PRIxPTR
">\n", (intptr_t )node);
6642 fprintf(f,
"<alt:%"PRIxPTR
">\n", (intptr_t )node);
6644 print_indent_tree(f, NCAR(node), indent + add);
6645 while (IS_NOT_NULL(node = NCDR(node))) {
6646 if (NTYPE(node) != type) {
6647 fprintf(f,
"ERROR: list/alt right is not a cons. %d\n", NTYPE(node));
6650 print_indent_tree(f, NCAR(node), indent + add);
6655 fprintf(f,
"<string%s:%"PRIxPTR
">",
6656 (NSTRING_IS_RAW(node) ?
"-raw" :
""), (intptr_t )node);
6657 for (p = NSTR(node)->s; p < NSTR(node)->end; p++) {
6658 if (*p >= 0x20 && *p < 0x7f)
6661 fprintf(f,
" 0x%02x", *p);
6667 fprintf(f,
"<cclass:%"PRIxPTR
">", (intptr_t )node);
6668 if (IS_NCCLASS_NOT(NCCLASS(node))) fputs(
"not ", f);
6669 if (NCCLASS(node)->mbuf) {
6670 BBuf* bbuf = NCCLASS(node)->mbuf;
6671 OnigCodePoint* data = (OnigCodePoint* )bbuf->p;
6672 OnigCodePoint* end = (OnigCodePoint* )(bbuf->p + bbuf->used);
6673 fprintf(f,
"%d", *data++);
6674 for (; data < end; data+=2) {
6676 fprintf(f,
"%04x-%04x", data[0], data[1]);
6682 fprintf(f,
"<ctype:%"PRIxPTR
"> ", (intptr_t )node);
6683 switch (NCTYPE(node)->ctype) {
6684 case ONIGENC_CTYPE_WORD:
6685 if (NCTYPE(node)->not != 0)
6686 fputs(
"not word", f);
6692 fprintf(f,
"ERROR: undefined ctype.\n");
6698 fprintf(f,
"<anychar:%"PRIxPTR
">", (intptr_t )node);
6702 fprintf(f,
"<anchor:%"PRIxPTR
"> ", (intptr_t )node);
6703 switch (NANCHOR(node)->type) {
6704 case ANCHOR_BEGIN_BUF: fputs(
"begin buf", f);
break;
6705 case ANCHOR_END_BUF: fputs(
"end buf", f);
break;
6706 case ANCHOR_BEGIN_LINE: fputs(
"begin line", f);
break;
6707 case ANCHOR_END_LINE: fputs(
"end line", f);
break;
6708 case ANCHOR_SEMI_END_BUF: fputs(
"semi end buf", f);
break;
6709 case ANCHOR_BEGIN_POSITION: fputs(
"begin position", f);
break;
6711 case ANCHOR_WORD_BOUND: fputs(
"word bound", f);
break;
6712 case ANCHOR_NOT_WORD_BOUND: fputs(
"not word bound", f);
break;
6713# ifdef USE_WORD_BEGIN_END
6714 case ANCHOR_WORD_BEGIN: fputs(
"word begin", f);
break;
6715 case ANCHOR_WORD_END: fputs(
"word end", f);
break;
6717 case ANCHOR_PREC_READ: fputs(
"prec read", f); container_p = TRUE;
break;
6718 case ANCHOR_PREC_READ_NOT: fputs(
"prec read not", f); container_p = TRUE;
break;
6719 case ANCHOR_LOOK_BEHIND: fputs(
"look_behind", f); container_p = TRUE;
break;
6720 case ANCHOR_LOOK_BEHIND_NOT: fputs(
"look_behind_not",f); container_p = TRUE;
break;
6721 case ANCHOR_KEEP: fputs(
"keep",f);
break;
6724 fprintf(f,
"ERROR: undefined anchor type.\n");
6734 fprintf(f,
"<backref:%"PRIxPTR
">", (intptr_t )node);
6735 for (i = 0; i < br->back_num; i++) {
6736 if (i > 0) fputs(
", ", f);
6737 fprintf(f,
"%d", p[i]);
6742# ifdef USE_SUBEXP_CALL
6746 fprintf(f,
"<call:%"PRIxPTR
">", (intptr_t )node);
6747 p_string(f, cn->name_end - cn->name, cn->name);
6753 fprintf(f,
"<quantifier:%"PRIxPTR
">{%d,%d}%s\n", (intptr_t )node,
6754 NQTFR(node)->lower, NQTFR(node)->upper,
6755 (NQTFR(node)->greedy ?
"" :
"?"));
6756 print_indent_tree(f, NQTFR(node)->target, indent + add);
6760 fprintf(f,
"<enclose:%"PRIxPTR
"> ", (intptr_t )node);
6761 switch (NENCLOSE(node)->type) {
6762 case ENCLOSE_OPTION:
6763 fprintf(f,
"option:%d", NENCLOSE(node)->option);
6765 case ENCLOSE_MEMORY:
6766 fprintf(f,
"memory:%d", NENCLOSE(node)->regnum);
6768 case ENCLOSE_STOP_BACKTRACK:
6769 fprintf(f,
"stop-bt");
6771 case ENCLOSE_CONDITION:
6772 fprintf(f,
"condition:%d", NENCLOSE(node)->regnum);
6774 case ENCLOSE_ABSENT:
6775 fprintf(f,
"absent");
6782 print_indent_tree(f, NENCLOSE(node)->target, indent + add);
6786 fprintf(f,
"print_indent_tree: undefined node type %d\n", NTYPE(node));
6790 if (type != NT_LIST && type != NT_ALT && type != NT_QTFR &&
6794 if (container_p) print_indent_tree(f, NANCHOR(node)->target, indent + add);
6800print_tree(FILE* f, Node* node)
6802 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.
char * ptr
Pointer to the underlying memory region, of at least capa bytes.
int len
Length of the buffer.
VALUE type(ANYARGS)
ANYARGS-ed function type.