| 775 |
md->start_match_ptr = ecode + 2; |
md->start_match_ptr = ecode + 2; |
| 776 |
RRETURN(MATCH_SKIP_ARG); |
RRETURN(MATCH_SKIP_ARG); |
| 777 |
|
|
| 778 |
/* For THEN (and THEN_ARG) we pass back the address of the bracket or |
/* For THEN (and THEN_ARG) we pass back the address of the opcode, so that |
| 779 |
the alt that is at the start of the current branch. This makes it possible |
the branch in which it occurs can be determined. Overload the start of |
| 780 |
to skip back past alternatives that precede the THEN within the current |
match pointer to do this. */ |
|
branch. */ |
|
| 781 |
|
|
| 782 |
case OP_THEN: |
case OP_THEN: |
| 783 |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, |
| 784 |
eptrb, RM54); |
eptrb, RM54); |
| 785 |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
| 786 |
md->start_match_ptr = ecode - GET(ecode, 1); |
md->start_match_ptr = ecode; |
| 787 |
MRRETURN(MATCH_THEN); |
MRRETURN(MATCH_THEN); |
| 788 |
|
|
| 789 |
case OP_THEN_ARG: |
case OP_THEN_ARG: |
| 790 |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1+LINK_SIZE], |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, |
| 791 |
offset_top, md, eptrb, RM58); |
md, eptrb, RM58); |
| 792 |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
| 793 |
md->start_match_ptr = ecode - GET(ecode, 1); |
md->start_match_ptr = ecode; |
| 794 |
md->mark = ecode + LINK_SIZE + 2; |
md->mark = ecode + 2; |
| 795 |
RRETURN(MATCH_THEN); |
RRETURN(MATCH_THEN); |
| 796 |
|
|
| 797 |
/* Handle a capturing bracket, other than those that are possessive with an |
/* Handle a capturing bracket, other than those that are possessive with an |
| 837 |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, |
| 838 |
eptrb, RM1); |
eptrb, RM1); |
| 839 |
if (rrc == MATCH_ONCE) break; /* Backing up through an atomic group */ |
if (rrc == MATCH_ONCE) break; /* Backing up through an atomic group */ |
| 840 |
if (rrc != MATCH_NOMATCH && |
|
| 841 |
(rrc != MATCH_THEN || md->start_match_ptr != ecode)) |
/* If we backed up to a THEN, check whether it is within the current |
| 842 |
RRETURN(rrc); |
branch by comparing the address of the THEN that is passed back with |
| 843 |
|
the end of the branch. If it is within the current branch, and the |
| 844 |
|
branch is one of two or more alternatives (it either starts or ends |
| 845 |
|
with OP_ALT), we have reached the limit of THEN's action, so convert |
| 846 |
|
the return code to NOMATCH, which will cause normal backtracking to |
| 847 |
|
happen from now on. Otherwise, THEN is passed back to an outer |
| 848 |
|
alternative. This implements Perl's treatment of parenthesized groups, |
| 849 |
|
where a group not containing | does not affect the current alternative, |
| 850 |
|
that is, (X) is NOT the same as (X|(*F)). */ |
| 851 |
|
|
| 852 |
|
if (rrc == MATCH_THEN) |
| 853 |
|
{ |
| 854 |
|
next = ecode + GET(ecode,1); |
| 855 |
|
if (md->start_match_ptr < next && |
| 856 |
|
(*ecode == OP_ALT || *next == OP_ALT)) |
| 857 |
|
rrc = MATCH_NOMATCH; |
| 858 |
|
} |
| 859 |
|
|
| 860 |
|
/* Anything other than NOMATCH is passed back. */ |
| 861 |
|
|
| 862 |
|
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
| 863 |
md->capture_last = save_capture_last; |
md->capture_last = save_capture_last; |
| 864 |
ecode += GET(ecode, 1); |
ecode += GET(ecode, 1); |
| 865 |
if (*ecode != OP_ALT) break; |
if (*ecode != OP_ALT) break; |
| 870 |
md->offset_vector[offset+1] = save_offset2; |
md->offset_vector[offset+1] = save_offset2; |
| 871 |
md->offset_vector[md->offset_end - number] = save_offset3; |
md->offset_vector[md->offset_end - number] = save_offset3; |
| 872 |
|
|
| 873 |
/* At this point, rrc will be one of MATCH_ONCE, MATCH_NOMATCH, or |
/* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */ |
|
MATCH_THEN. */ |
|
| 874 |
|
|
| 875 |
if (rrc != MATCH_THEN && md->mark == NULL) md->mark = markptr; |
if (md->mark == NULL) md->mark = markptr; |
| 876 |
RRETURN(((rrc == MATCH_ONCE)? MATCH_ONCE:MATCH_NOMATCH)); |
RRETURN(rrc); |
| 877 |
} |
} |
| 878 |
|
|
| 879 |
/* FALL THROUGH ... Insufficient room for saving captured contents. Treat |
/* FALL THROUGH ... Insufficient room for saving captured contents. Treat |
| 930 |
|
|
| 931 |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, eptrb, |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, eptrb, |
| 932 |
RM2); |
RM2); |
| 933 |
if (rrc != MATCH_NOMATCH && |
|
| 934 |
(rrc != MATCH_THEN || md->start_match_ptr != ecode)) |
/* See comment in the code for capturing groups above about handling |
| 935 |
|
THEN. */ |
| 936 |
|
|
| 937 |
|
if (rrc == MATCH_THEN) |
| 938 |
|
{ |
| 939 |
|
next = ecode + GET(ecode,1); |
| 940 |
|
if (md->start_match_ptr < next && |
| 941 |
|
(*ecode == OP_ALT || *next == OP_ALT)) |
| 942 |
|
rrc = MATCH_NOMATCH; |
| 943 |
|
} |
| 944 |
|
|
| 945 |
|
if (rrc != MATCH_NOMATCH) |
| 946 |
{ |
{ |
| 947 |
if (rrc == MATCH_ONCE) |
if (rrc == MATCH_ONCE) |
| 948 |
{ |
{ |
| 959 |
ecode += GET(ecode, 1); |
ecode += GET(ecode, 1); |
| 960 |
if (*ecode != OP_ALT) break; |
if (*ecode != OP_ALT) break; |
| 961 |
} |
} |
| 962 |
if (rrc != MATCH_THEN && md->mark == NULL) md->mark = markptr; |
|
| 963 |
|
if (md->mark == NULL) md->mark = markptr; |
| 964 |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
| 965 |
|
|
| 966 |
/* Handle possessive capturing brackets with an unlimited repeat. We come |
/* Handle possessive capturing brackets with an unlimited repeat. We come |
| 1023 |
matched_once = TRUE; |
matched_once = TRUE; |
| 1024 |
continue; |
continue; |
| 1025 |
} |
} |
| 1026 |
if (rrc != MATCH_NOMATCH && |
|
| 1027 |
(rrc != MATCH_THEN || md->start_match_ptr != ecode)) |
/* See comment in the code for capturing groups above about handling |
| 1028 |
RRETURN(rrc); |
THEN. */ |
| 1029 |
|
|
| 1030 |
|
if (rrc == MATCH_THEN) |
| 1031 |
|
{ |
| 1032 |
|
next = ecode + GET(ecode,1); |
| 1033 |
|
if (md->start_match_ptr < next && |
| 1034 |
|
(*ecode == OP_ALT || *next == OP_ALT)) |
| 1035 |
|
rrc = MATCH_NOMATCH; |
| 1036 |
|
} |
| 1037 |
|
|
| 1038 |
|
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
| 1039 |
md->capture_last = save_capture_last; |
md->capture_last = save_capture_last; |
| 1040 |
ecode += GET(ecode, 1); |
ecode += GET(ecode, 1); |
| 1041 |
if (*ecode != OP_ALT) break; |
if (*ecode != OP_ALT) break; |
| 1048 |
md->offset_vector[md->offset_end - number] = save_offset3; |
md->offset_vector[md->offset_end - number] = save_offset3; |
| 1049 |
} |
} |
| 1050 |
|
|
| 1051 |
if (rrc != MATCH_THEN && md->mark == NULL) md->mark = markptr; |
if (md->mark == NULL) md->mark = markptr; |
| 1052 |
if (allow_zero || matched_once) |
if (allow_zero || matched_once) |
| 1053 |
{ |
{ |
| 1054 |
ecode += 1 + LINK_SIZE; |
ecode += 1 + LINK_SIZE; |
| 1095 |
matched_once = TRUE; |
matched_once = TRUE; |
| 1096 |
continue; |
continue; |
| 1097 |
} |
} |
| 1098 |
if (rrc != MATCH_NOMATCH && |
|
| 1099 |
(rrc != MATCH_THEN || md->start_match_ptr != ecode)) |
/* See comment in the code for capturing groups above about handling |
| 1100 |
RRETURN(rrc); |
THEN. */ |
| 1101 |
|
|
| 1102 |
|
if (rrc == MATCH_THEN) |
| 1103 |
|
{ |
| 1104 |
|
next = ecode + GET(ecode,1); |
| 1105 |
|
if (md->start_match_ptr < next && |
| 1106 |
|
(*ecode == OP_ALT || *next == OP_ALT)) |
| 1107 |
|
rrc = MATCH_NOMATCH; |
| 1108 |
|
} |
| 1109 |
|
|
| 1110 |
|
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
| 1111 |
ecode += GET(ecode, 1); |
ecode += GET(ecode, 1); |
| 1112 |
if (*ecode != OP_ALT) break; |
if (*ecode != OP_ALT) break; |
| 1113 |
} |
} |
| 1319 |
ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2); |
ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2); |
| 1320 |
while (*ecode == OP_ALT) ecode += GET(ecode, 1); |
while (*ecode == OP_ALT) ecode += GET(ecode, 1); |
| 1321 |
} |
} |
| 1322 |
else if (rrc != MATCH_NOMATCH && |
|
| 1323 |
(rrc != MATCH_THEN || md->start_match_ptr != ecode)) |
/* PCRE doesn't allow the effect of (*THEN) to escape beyond an |
| 1324 |
|
assertion; it is therefore treated as NOMATCH. */ |
| 1325 |
|
|
| 1326 |
|
else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) |
| 1327 |
{ |
{ |
| 1328 |
RRETURN(rrc); /* Need braces because of following else */ |
RRETURN(rrc); /* Need braces because of following else */ |
| 1329 |
} |
} |
| 1334 |
} |
} |
| 1335 |
} |
} |
| 1336 |
|
|
| 1337 |
/* 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, can |
| 1338 |
we used always to use tail recursion to avoid using another stack frame, |
use tail recursion to avoid using another stack frame, except when there is |
| 1339 |
except when there was unlimited repeat of a possibly empty group. However, |
unlimited repeat of a possibly empty group. In the latter case, a recursive |
| 1340 |
that strategy no longer works because of the possibilty of (*THEN) being |
call to match() is always required, unless the second alternative doesn't |
| 1341 |
encountered in the branch. However, we can still use tail recursion if |
exist, in which case we can just plough on. Note that, for compatibility |
| 1342 |
there are no (*THEN)s in the pattern. Otherwise, a recursive call to |
with Perl, the | in a conditional group is NOT treated as creating two |
| 1343 |
match() is always required, unless the second alternative doesn't exist, in |
alternatives. If a THEN is encountered in the branch, it propagates out to |
| 1344 |
which case we can just plough on. */ |
the enclosing alternative (unless nested in a deeper set of alternatives, |
| 1345 |
|
of course). */ |
| 1346 |
|
|
| 1347 |
if (condition || *ecode == OP_ALT) |
if (condition || *ecode == OP_ALT) |
| 1348 |
{ |
{ |
| 1349 |
if (op == OP_SCOND) md->match_function_type = MATCH_CBEGROUP; |
if (op != OP_SCOND) |
|
else if (!md->hasthen) |
|
| 1350 |
{ |
{ |
| 1351 |
ecode += 1 + LINK_SIZE; |
ecode += 1 + LINK_SIZE; |
| 1352 |
goto TAIL_RECURSE; |
goto TAIL_RECURSE; |
| 1353 |
} |
} |
| 1354 |
|
|
| 1355 |
/* A call to match() is required. */ |
md->match_function_type = MATCH_CBEGROUP; |
|
|
|
| 1356 |
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49); |
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49); |
|
|
|
|
/* If the result is THEN from within the "true" branch of the condition, |
|
|
md->start_match_ptr will point to the original OP_COND, not to the start |
|
|
of the branch, so we have do work to see if it matches. If THEN comes |
|
|
from the "false" branch, md->start_match_ptr does point to OP_ALT. */ |
|
|
|
|
|
if (rrc == MATCH_THEN) |
|
|
{ |
|
|
if (*ecode != OP_ALT) |
|
|
{ |
|
|
do ecode += GET(ecode, 1); while (*ecode == OP_ALT); |
|
|
ecode -= GET(ecode, 1); |
|
|
} |
|
|
if (md->start_match_ptr == ecode) rrc = MATCH_NOMATCH; |
|
|
} |
|
| 1357 |
RRETURN(rrc); |
RRETURN(rrc); |
| 1358 |
} |
} |
| 1359 |
|
|
| 1449 |
markptr = md->mark; |
markptr = md->mark; |
| 1450 |
break; |
break; |
| 1451 |
} |
} |
| 1452 |
if (rrc != MATCH_NOMATCH && |
|
| 1453 |
(rrc != MATCH_THEN || md->start_match_ptr != ecode)) |
/* PCRE does not allow THEN to escape beyond an assertion; it is treated |
| 1454 |
RRETURN(rrc); |
as NOMATCH. */ |
| 1455 |
|
|
| 1456 |
|
if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); |
| 1457 |
ecode += GET(ecode, 1); |
ecode += GET(ecode, 1); |
| 1458 |
} |
} |
| 1459 |
while (*ecode == OP_ALT); |
while (*ecode == OP_ALT); |
| 1494 |
do ecode += GET(ecode,1); while (*ecode == OP_ALT); |
do ecode += GET(ecode,1); while (*ecode == OP_ALT); |
| 1495 |
break; |
break; |
| 1496 |
} |
} |
| 1497 |
if (rrc != MATCH_NOMATCH && |
|
| 1498 |
(rrc != MATCH_THEN || md->start_match_ptr != ecode)) |
/* PCRE does not allow THEN to escape beyond an assertion; it is treated |
| 1499 |
RRETURN(rrc); |
as NOMATCH. */ |
| 1500 |
|
|
| 1501 |
|
if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); |
| 1502 |
ecode += GET(ecode,1); |
ecode += GET(ecode,1); |
| 1503 |
} |
} |
| 1504 |
while (*ecode == OP_ALT); |
while (*ecode == OP_ALT); |
| 1655 |
mstart = md->start_match_ptr; |
mstart = md->start_match_ptr; |
| 1656 |
goto RECURSION_MATCHED; /* Exit loop; end processing */ |
goto RECURSION_MATCHED; /* Exit loop; end processing */ |
| 1657 |
} |
} |
| 1658 |
else if (rrc != MATCH_NOMATCH && |
|
| 1659 |
(rrc != MATCH_THEN || md->start_match_ptr != callpat)) |
/* PCRE does not allow THEN to escape beyond a recursion; it is treated |
| 1660 |
|
as NOMATCH. */ |
| 1661 |
|
|
| 1662 |
|
else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) |
| 1663 |
{ |
{ |
| 1664 |
DPRINTF(("Recursion gave error %d\n", rrc)); |
DPRINTF(("Recursion gave error %d\n", rrc)); |
| 1665 |
if (new_recursive.offset_save != stacksave) |
if (new_recursive.offset_save != stacksave) |