/[pcre]/code/trunk/pcre_exec.c
ViewVC logotype

Diff of /code/trunk/pcre_exec.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 713 by ph10, Tue Sep 27 11:03:15 2011 UTC revision 716 by ph10, Tue Oct 4 16:38:05 2011 UTC
# Line 775  for (;;) Line 775  for (;;)
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
# Line 838  for (;;) Line 837  for (;;)
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;
# Line 851  for (;;) Line 870  for (;;)
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
# Line 912  for (;;) Line 930  for (;;)
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            {            {
# Line 930  for (;;) Line 959  for (;;)
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
# Line 993  for (;;) Line 1023  for (;;)
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;
# Line 1008  for (;;) Line 1048  for (;;)
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;
# Line 1055  for (;;) Line 1095  for (;;)
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        }        }
# Line 1269  for (;;) Line 1319  for (;;)
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          }          }
# Line 1281  for (;;) Line 1334  for (;;)
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    
# Line 1412  for (;;) Line 1449  for (;;)
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);
# Line 1455  for (;;) Line 1494  for (;;)
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);
# Line 1614  for (;;) Line 1655  for (;;)
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)

Legend:
Removed from v.713  
changed lines
  Added in v.716

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12