53 |
#undef min |
#undef min |
54 |
#undef max |
#undef max |
55 |
|
|
|
/* The chain of eptrblocks for tail recursions uses memory in stack workspace, |
|
|
obtained at top level, the size of which is defined by EPTR_WORK_SIZE. */ |
|
|
|
|
|
#define EPTR_WORK_SIZE (1000) |
|
|
|
|
56 |
/* Flag bits for the match() function */ |
/* Flag bits for the match() function */ |
57 |
|
|
58 |
#define match_condassert 0x01 /* Called to check a condition assertion */ |
#define match_condassert 0x01 /* Called to check a condition assertion */ |
59 |
#define match_cbegroup 0x02 /* Could-be-empty unlimited repeat group */ |
#define match_cbegroup 0x02 /* Could-be-empty unlimited repeat group */ |
|
#define match_tail_recursed 0x04 /* Tail recursive call */ |
|
60 |
|
|
61 |
/* Non-error returns from the match() function. Error returns are externally |
/* Non-error returns from the match() function. Error returns are externally |
62 |
defined PCRE_ERROR_xxx codes, which are all negative. */ |
defined PCRE_ERROR_xxx codes, which are all negative. */ |
206 |
RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20, |
RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20, |
207 |
RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30, |
RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30, |
208 |
RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40, |
RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40, |
209 |
RM41, RM42, RM43, RM44, RM45, RM46, RM47 }; |
RM41, RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50 }; |
210 |
|
|
211 |
|
|
212 |
/* These versions of the macros use the stack, as normal. There are debugging |
/* These versions of the macros use the stack, as normal. There are debugging |
378 |
match_condassert - this is an assertion condition |
match_condassert - this is an assertion condition |
379 |
match_cbegroup - this is the start of an unlimited repeat |
match_cbegroup - this is the start of an unlimited repeat |
380 |
group that can match an empty string |
group that can match an empty string |
|
match_tail_recursed - this is a tail_recursed group |
|
381 |
rdepth the recursion depth |
rdepth the recursion depth |
382 |
|
|
383 |
Returns: MATCH_MATCH if matched ) these values are >= 0 |
Returns: MATCH_MATCH if matched ) these values are >= 0 |
579 |
string, the match_cbegroup flag is set. When this is the case, add the current |
string, the match_cbegroup flag is set. When this is the case, add the current |
580 |
subject pointer to the chain of such remembered pointers, to be checked when we |
subject pointer to the chain of such remembered pointers, to be checked when we |
581 |
hit the closing ket, in order to break infinite loops that match no characters. |
hit the closing ket, in order to break infinite loops that match no characters. |
582 |
When match() is called in other circumstances, don't add to the chain. If this |
When match() is called in other circumstances, don't add to the chain. The |
583 |
is a tail recursion, use a block from the workspace, as the one on the stack is |
match_cbegroup flag must NOT be used with tail recursion, because the memory |
584 |
already used. */ |
block that is used is on the stack, so a new one may be required for each |
585 |
|
match(). */ |
586 |
|
|
587 |
if ((flags & match_cbegroup) != 0) |
if ((flags & match_cbegroup) != 0) |
588 |
{ |
{ |
589 |
eptrblock *p; |
newptrb.epb_saved_eptr = eptr; |
590 |
if ((flags & match_tail_recursed) != 0) |
newptrb.epb_prev = eptrb; |
591 |
{ |
eptrb = &newptrb; |
|
if (md->eptrn >= EPTR_WORK_SIZE) RRETURN(PCRE_ERROR_NULLWSLIMIT); |
|
|
p = md->eptrchain + md->eptrn++; |
|
|
} |
|
|
else p = &newptrb; |
|
|
p->epb_saved_eptr = eptr; |
|
|
p->epb_prev = eptrb; |
|
|
eptrb = p; |
|
592 |
} |
} |
593 |
|
|
594 |
/* Now start processing the opcodes. */ |
/* Now start processing the opcodes. */ |
664 |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
665 |
} |
} |
666 |
|
|
667 |
/* Insufficient room for saving captured contents. Treat as a non-capturing |
/* FALL THROUGH ... Insufficient room for saving captured contents. Treat |
668 |
bracket. */ |
as a non-capturing bracket. */ |
669 |
|
|
670 |
|
/* VVVVVVVVVVVVVVVVVVVVVVVVV */ |
671 |
|
/* VVVVVVVVVVVVVVVVVVVVVVVVV */ |
672 |
|
|
673 |
DPRINTF(("insufficient capture room: treat as non-capturing\n")); |
DPRINTF(("insufficient capture room: treat as non-capturing\n")); |
674 |
|
|
675 |
|
/* VVVVVVVVVVVVVVVVVVVVVVVVV */ |
676 |
|
/* VVVVVVVVVVVVVVVVVVVVVVVVV */ |
677 |
|
|
678 |
/* Non-capturing bracket. Loop for all the alternatives. When we get to the |
/* Non-capturing bracket. Loop for all the alternatives. When we get to the |
679 |
final alternative within the brackets, we would return the result of a |
final alternative within the brackets, we would return the result of a |
680 |
recursive call to match() whatever happened. We can reduce stack usage by |
recursive call to match() whatever happened. We can reduce stack usage by |
681 |
turning this into a tail recursion. */ |
turning this into a tail recursion, except in the case when match_cbegroup |
682 |
|
is set.*/ |
683 |
|
|
684 |
case OP_BRA: |
case OP_BRA: |
685 |
case OP_SBRA: |
case OP_SBRA: |
687 |
flags = (op >= OP_SBRA)? match_cbegroup : 0; |
flags = (op >= OP_SBRA)? match_cbegroup : 0; |
688 |
for (;;) |
for (;;) |
689 |
{ |
{ |
690 |
if (ecode[GET(ecode, 1)] != OP_ALT) |
if (ecode[GET(ecode, 1)] != OP_ALT) /* Final alternative */ |
691 |
{ |
{ |
692 |
ecode += _pcre_OP_lengths[*ecode]; |
if (flags == 0) /* Not a possibly empty group */ |
693 |
flags |= match_tail_recursed; |
{ |
694 |
DPRINTF(("bracket 0 tail recursion\n")); |
ecode += _pcre_OP_lengths[*ecode]; |
695 |
goto TAIL_RECURSE; |
DPRINTF(("bracket 0 tail recursion\n")); |
696 |
|
goto TAIL_RECURSE; |
697 |
|
} |
698 |
|
|
699 |
|
/* Possibly empty group; can't use tail recursion. */ |
700 |
|
|
701 |
|
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims, |
702 |
|
eptrb, flags, RM48); |
703 |
|
RRETURN(rrc); |
704 |
} |
} |
705 |
|
|
706 |
/* For non-final alternatives, continue the loop for a NOMATCH result; |
/* For non-final alternatives, continue the loop for a NOMATCH result; |
768 |
} |
} |
769 |
|
|
770 |
/* We are now at the branch that is to be obeyed. As there is only one, |
/* We are now at the branch that is to be obeyed. As there is only one, |
771 |
we can use tail recursion to avoid using another stack frame. If the second |
we can use tail recursion to avoid using another stack frame, except when |
772 |
alternative doesn't exist, we can just plough on. */ |
match_cbegroup is required for an unlimited repeat of a possibly empty |
773 |
|
group. If the second alternative doesn't exist, we can just plough on. */ |
774 |
|
|
775 |
if (condition || *ecode == OP_ALT) |
if (condition || *ecode == OP_ALT) |
776 |
{ |
{ |
777 |
ecode += 1 + LINK_SIZE; |
ecode += 1 + LINK_SIZE; |
778 |
flags = match_tail_recursed | ((op == OP_SCOND)? match_cbegroup : 0); |
if (op == OP_SCOND) /* Possibly empty group */ |
779 |
goto TAIL_RECURSE; |
{ |
780 |
|
RMATCH(eptr, ecode, offset_top, md, ims, eptrb, match_cbegroup, RM49); |
781 |
|
RRETURN(rrc); |
782 |
|
} |
783 |
|
else /* Group must match something */ |
784 |
|
{ |
785 |
|
flags = 0; |
786 |
|
goto TAIL_RECURSE; |
787 |
|
} |
788 |
} |
} |
789 |
else |
else /* Condition false & no 2nd alternative */ |
790 |
{ |
{ |
791 |
ecode += 1 + LINK_SIZE; |
ecode += 1 + LINK_SIZE; |
792 |
} |
} |
1038 |
|
|
1039 |
do |
do |
1040 |
{ |
{ |
1041 |
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, |
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7); |
|
eptrb, 0, RM7); |
|
1042 |
if (rrc == MATCH_MATCH) break; |
if (rrc == MATCH_MATCH) break; |
1043 |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
1044 |
ecode += GET(ecode,1); |
ecode += GET(ecode,1); |
1083 |
|
|
1084 |
if (*ecode == OP_KETRMIN) |
if (*ecode == OP_KETRMIN) |
1085 |
{ |
{ |
1086 |
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, |
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM8); |
|
RM8); |
|
1087 |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
1088 |
ecode = prev; |
ecode = prev; |
1089 |
flags = match_tail_recursed; |
flags = 0; |
1090 |
goto TAIL_RECURSE; |
goto TAIL_RECURSE; |
1091 |
} |
} |
1092 |
else /* OP_KETRMAX */ |
else /* OP_KETRMAX */ |
1094 |
RMATCH(eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9); |
RMATCH(eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9); |
1095 |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
1096 |
ecode += 1 + LINK_SIZE; |
ecode += 1 + LINK_SIZE; |
1097 |
flags = match_tail_recursed; |
flags = 0; |
1098 |
goto TAIL_RECURSE; |
goto TAIL_RECURSE; |
1099 |
} |
} |
1100 |
/* Control never gets here */ |
/* Control never gets here */ |
1225 |
|
|
1226 |
/* The repeating kets try the rest of the pattern or restart from the |
/* The repeating kets try the rest of the pattern or restart from the |
1227 |
preceding bracket, in the appropriate order. In the second case, we can use |
preceding bracket, in the appropriate order. In the second case, we can use |
1228 |
tail recursion to avoid using another stack frame. */ |
tail recursion to avoid using another stack frame, unless we have an |
1229 |
|
unlimited repeat of a group that can match an empty string. */ |
1230 |
|
|
1231 |
flags = (*prev >= OP_SBRA)? match_cbegroup : 0; |
flags = (*prev >= OP_SBRA)? match_cbegroup : 0; |
1232 |
|
|
1233 |
if (*ecode == OP_KETRMIN) |
if (*ecode == OP_KETRMIN) |
1234 |
{ |
{ |
1235 |
RMATCH(eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0, |
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM12); |
|
RM12); |
|
1236 |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
1237 |
|
if (flags != 0) /* Could match an empty string */ |
1238 |
|
{ |
1239 |
|
RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM50); |
1240 |
|
RRETURN(rrc); |
1241 |
|
} |
1242 |
ecode = prev; |
ecode = prev; |
|
flags |= match_tail_recursed; |
|
1243 |
goto TAIL_RECURSE; |
goto TAIL_RECURSE; |
1244 |
} |
} |
1245 |
else /* OP_KETRMAX */ |
else /* OP_KETRMAX */ |
1247 |
RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13); |
RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13); |
1248 |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
1249 |
ecode += 1 + LINK_SIZE; |
ecode += 1 + LINK_SIZE; |
1250 |
flags = match_tail_recursed; |
flags = 0; |
1251 |
goto TAIL_RECURSE; |
goto TAIL_RECURSE; |
1252 |
} |
} |
1253 |
/* Control never gets here */ |
/* Control never gets here */ |
4303 |
USPTR start_match = (USPTR)subject + start_offset; |
USPTR start_match = (USPTR)subject + start_offset; |
4304 |
USPTR end_subject; |
USPTR end_subject; |
4305 |
USPTR req_byte_ptr = start_match - 1; |
USPTR req_byte_ptr = start_match - 1; |
|
eptrblock eptrchain[EPTR_WORK_SIZE]; |
|
4306 |
|
|
4307 |
pcre_study_data internal_study; |
pcre_study_data internal_study; |
4308 |
const pcre_study_data *study; |
const pcre_study_data *study; |
4388 |
md->hitend = FALSE; |
md->hitend = FALSE; |
4389 |
|
|
4390 |
md->recursive = NULL; /* No recursion at top level */ |
md->recursive = NULL; /* No recursion at top level */ |
|
md->eptrchain = eptrchain; /* Make workspace generally available */ |
|
4391 |
|
|
4392 |
md->lcc = tables + lcc_offset; |
md->lcc = tables + lcc_offset; |
4393 |
md->ctypes = tables + ctypes_offset; |
md->ctypes = tables + ctypes_offset; |
4685 |
|
|
4686 |
md->start_match_ptr = start_match; /* Insurance */ |
md->start_match_ptr = start_match; /* Insurance */ |
4687 |
md->match_call_count = 0; |
md->match_call_count = 0; |
4688 |
md->eptrn = 0; /* Next free eptrchain slot */ |
rc = match(start_match, md->start_code, start_match, 2, md, ims, NULL, 0, 0); |
|
rc = match(start_match, md->start_code, start_match, 2, md, |
|
|
ims, NULL, 0, 0); |
|
4689 |
|
|
4690 |
/* Any return other than MATCH_NOMATCH breaks the loop. */ |
/* Any return other than MATCH_NOMATCH breaks the loop. */ |
4691 |
|
|