/[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 893 by ph10, Thu Jan 19 17:15:11 2012 UTC revision 1015 by ph10, Sun Aug 26 16:07:14 2012 UTC
# Line 37  POSSIBILITY OF SUCH DAMAGE. Line 37  POSSIBILITY OF SUCH DAMAGE.
37  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
38  */  */
39    
   
40  /* This module contains pcre_exec(), the externally visible function that does  /* This module contains pcre_exec(), the externally visible function that does
41  pattern matching using an NFA algorithm, trying to mimic Perl as closely as  pattern matching using an NFA algorithm, trying to mimic Perl as closely as
42  possible. There are also some static supporting functions. */  possible. There are also some static supporting functions. */
# Line 140  Arguments: Line 139  Arguments:
139    md          points to match data block    md          points to match data block
140    caseless    TRUE if caseless    caseless    TRUE if caseless
141    
142  Returns:      < 0 if not matched, otherwise the number of subject bytes matched  Returns:      >= 0 the number of subject bytes matched
143                  -1 no match
144                  -2 partial match; always given if at end subject
145  */  */
146    
147  static int  static int
# Line 163  pchars(p, length, FALSE, md); Line 164  pchars(p, length, FALSE, md);
164  printf("\n");  printf("\n");
165  #endif  #endif
166    
167  /* Always fail if reference not set (and not JavaScript compatible). */  /* Always fail if reference not set (and not JavaScript compatible - in that
168    case the length is passed as zero). */
169    
170  if (length < 0) return -1;  if (length < 0) return -1;
171    
# Line 189  if (caseless) Line 191  if (caseless)
191      while (p < endptr)      while (p < endptr)
192        {        {
193        int c, d;        int c, d;
194        if (eptr >= md->end_subject) return -1;        if (eptr >= md->end_subject) return -2;   /* Partial match */
195        GETCHARINC(c, eptr);        GETCHARINC(c, eptr);
196        GETCHARINC(d, p);        GETCHARINC(d, p);
197        if (c != d && c != UCD_OTHERCASE(d)) return -1;        if (c != d && c != UCD_OTHERCASE(d)) return -1;
# Line 202  if (caseless) Line 204  if (caseless)
204    /* The same code works when not in UTF-8 mode and in UTF-8 mode when there    /* The same code works when not in UTF-8 mode and in UTF-8 mode when there
205    is no UCP support. */    is no UCP support. */
206      {      {
     if (eptr + length > md->end_subject) return -1;  
207      while (length-- > 0)      while (length-- > 0)
208        {        {
209          if (eptr >= md->end_subject) return -2;   /* Partial match */
210        if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1;        if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1;
211        p++;        p++;
212        eptr++;        eptr++;
# Line 217  are in UTF-8 mode. */ Line 219  are in UTF-8 mode. */
219    
220  else  else
221    {    {
222    if (eptr + length > md->end_subject) return -1;    while (length-- > 0)
223    while (length-- > 0) if (*p++ != *eptr++) return -1;      {
224        if (eptr >= md->end_subject) return -2;   /* Partial match */
225        if (*p++ != *eptr++) return -1;
226        }
227    }    }
228    
229  return (int)(eptr - eptr_start);  return (int)(eptr - eptr_start);
# Line 311  argument of match(), which never changes Line 316  argument of match(), which never changes
316    
317  #define RMATCH(ra,rb,rc,rd,re,rw)\  #define RMATCH(ra,rb,rc,rd,re,rw)\
318    {\    {\
319    heapframe *newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\    heapframe *newframe = frame->Xnextframe;\
320    if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\    if (newframe == NULL)\
321    frame->Xwhere = rw; \      {\
322        newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\
323        if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
324        newframe->Xnextframe = NULL;\
325        frame->Xnextframe = newframe;\
326        }\
327      frame->Xwhere = rw;\
328    newframe->Xeptr = ra;\    newframe->Xeptr = ra;\
329    newframe->Xecode = rb;\    newframe->Xecode = rb;\
330    newframe->Xmstart = mstart;\    newframe->Xmstart = mstart;\
# Line 332  argument of match(), which never changes Line 343  argument of match(), which never changes
343    {\    {\
344    heapframe *oldframe = frame;\    heapframe *oldframe = frame;\
345    frame = oldframe->Xprevframe;\    frame = oldframe->Xprevframe;\
   if (oldframe != &frame_zero) (PUBL(stack_free))(oldframe);\  
346    if (frame != NULL)\    if (frame != NULL)\
347      {\      {\
348      rrc = ra;\      rrc = ra;\
# Line 346  argument of match(), which never changes Line 356  argument of match(), which never changes
356    
357  typedef struct heapframe {  typedef struct heapframe {
358    struct heapframe *Xprevframe;    struct heapframe *Xprevframe;
359      struct heapframe *Xnextframe;
360    
361    /* Function arguments that may change */    /* Function arguments that may change */
362    
# Line 487  int condcode; Line 498  int condcode;
498  /* When recursion is not being used, all "local" variables that have to be  /* When recursion is not being used, all "local" variables that have to be
499  preserved over calls to RMATCH() are part of a "frame". We set up the top-level  preserved over calls to RMATCH() are part of a "frame". We set up the top-level
500  frame on the stack here; subsequent instantiations are obtained from the heap  frame on the stack here; subsequent instantiations are obtained from the heap
501  whenever RMATCH() does a "recursion". See the macro definitions above. Putting  whenever RMATCH() does a "recursion". See the macro definitions above. Putting
502  the top-level on the stack rather than malloc-ing them all gives a performance  the top-level on the stack rather than malloc-ing them all gives a performance
503  boost in many cases where there is not much "recursion". */  boost in many cases where there is not much "recursion". */
504    
505  #ifdef NO_RECURSE  #ifdef NO_RECURSE
506  heapframe frame_zero;  heapframe *frame = (heapframe *)md->match_frames_base;
 heapframe *frame = &frame_zero;  
 frame->Xprevframe = NULL;            /* Marks the top level */  
507    
508  /* Copy in the original argument variables */  /* Copy in the original argument variables */
509    
# Line 616  int stacksave[REC_STACK_SAVE_MAX]; Line 625  int stacksave[REC_STACK_SAVE_MAX];
625    
626  eptrblock newptrb;  eptrblock newptrb;
627    
628  /* There is a special fudge for calling match() in a way that causes it to  /* There is a special fudge for calling match() in a way that causes it to
629  measure the size of its basic stack frame when the stack is being used for  measure the size of its basic stack frame when the stack is being used for
630  recursion. The first argument (eptr) points to a pointer that is used  recursion. The second argument (ecode) being NULL triggers this behaviour. It
631  "statically" for doing the calculation. The second argument (ecode) being NULL  cannot normally ever be NULL. The return is the negated value of the frame
632  triggers this behaviour. It cannot normally every be NULL. The return is the  size. */
 negated value of the frame size. */  
633    
634  if (ecode == NULL)  if (ecode == NULL)
635    {    {
   char **aptr = (char **)eptr;  
636    if (rdepth == 0)    if (rdepth == 0)
637      {      return match((PCRE_PUCHAR)&rdepth, NULL, NULL, 0, NULL, NULL, 1);
     *aptr = (char *)&rdepth;  
     return match(eptr, NULL, NULL, 0, NULL, NULL, 1);  
     }  
638    else    else
639      {      {
640      int len = (char *)&rdepth - *aptr;      int len = (char *)&rdepth - (char *)eptr;
641      return (len > 0)? -len : len;      return (len > 0)? -len : len;
642      }      }
643    }    }
644  #endif     /* NO_RECURSE */  #endif     /* NO_RECURSE */
645    
646  /* To save space on the stack and in the heap frame, I have doubled up on some  /* To save space on the stack and in the heap frame, I have doubled up on some
# Line 843  for (;;) Line 847  for (;;)
847      case OP_ONCE_NC:      case OP_ONCE_NC:
848      prev = ecode;      prev = ecode;
849      saved_eptr = eptr;      saved_eptr = eptr;
850      save_mark = md->mark;      save_mark = md->mark;
851      do      do
852        {        {
853        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64);
# Line 862  for (;;) Line 866  for (;;)
866    
867        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
868        ecode += GET(ecode,1);        ecode += GET(ecode,1);
869        md->mark = save_mark;        md->mark = save_mark;
870        }        }
871      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
872    
# Line 902  for (;;) Line 906  for (;;)
906        }        }
907      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
908        {        {
       md->match_function_type = MATCH_CBEGROUP;  
909        RMATCH(eptr, prev, offset_top, md, eptrb, RM66);        RMATCH(eptr, prev, offset_top, md, eptrb, RM66);
910        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
911        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
# Line 942  for (;;) Line 945  for (;;)
945        save_offset2 = md->offset_vector[offset+1];        save_offset2 = md->offset_vector[offset+1];
946        save_offset3 = md->offset_vector[md->offset_end - number];        save_offset3 = md->offset_vector[md->offset_end - number];
947        save_capture_last = md->capture_last;        save_capture_last = md->capture_last;
948        save_mark = md->mark;        save_mark = md->mark;
949    
950        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
951        md->offset_vector[md->offset_end - number] =        md->offset_vector[md->offset_end - number] =
# Line 1031  for (;;) Line 1034  for (;;)
1034    
1035      for (;;)      for (;;)
1036        {        {
1037        if (op >= OP_SBRA || op == OP_ONCE) md->match_function_type = MATCH_CBEGROUP;        if (op >= OP_SBRA || op == OP_ONCE)
1038            md->match_function_type = MATCH_CBEGROUP;
1039    
1040        /* If this is not a possibly empty group, and there are no (*THEN)s in        /* If this is not a possibly empty group, and there are no (*THEN)s in
1041        the pattern, and this is the final alternative, optimize as described        the pattern, and this is the final alternative, optimize as described
# Line 1048  for (;;) Line 1052  for (;;)
1052        save_mark = md->mark;        save_mark = md->mark;
1053        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
1054          RM2);          RM2);
1055    
1056        /* See comment in the code for capturing groups above about handling        /* See comment in the code for capturing groups above about handling
1057        THEN. */        THEN. */
1058    
# Line 1075  for (;;) Line 1079  for (;;)
1079          RRETURN(rrc);          RRETURN(rrc);
1080          }          }
1081        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1082        md->mark = save_mark;        md->mark = save_mark;
1083        if (*ecode != OP_ALT) break;        if (*ecode != OP_ALT) break;
1084        }        }
1085    
# Line 1554  for (;;) Line 1558  for (;;)
1558    
1559      case OP_ASSERT:      case OP_ASSERT:
1560      case OP_ASSERTBACK:      case OP_ASSERTBACK:
1561      save_mark = md->mark;      save_mark = md->mark;
1562      if (md->match_function_type == MATCH_CONDASSERT)      if (md->match_function_type == MATCH_CONDASSERT)
1563        {        {
1564        condassert = TRUE;        condassert = TRUE;
# Line 1570  for (;;) Line 1574  for (;;)
1574          mstart = md->start_match_ptr;   /* In case \K reset it */          mstart = md->start_match_ptr;   /* In case \K reset it */
1575          break;          break;
1576          }          }
1577          md->mark = save_mark;
1578    
1579        /* PCRE does not allow THEN to escape beyond an assertion; it is treated        /* A COMMIT failure must fail the entire assertion, without trying any
1580        as NOMATCH. */        subsequent branches. */
1581    
1582          if (rrc == MATCH_COMMIT) RRETURN(MATCH_NOMATCH);
1583    
1584          /* PCRE does not allow THEN to escape beyond an assertion; it
1585          is treated as NOMATCH. */
1586    
1587        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1588        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
       md->mark = save_mark;  
1589        }        }
1590      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
1591    
# Line 1600  for (;;) Line 1609  for (;;)
1609    
1610      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1611      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
1612      save_mark = md->mark;      save_mark = md->mark;
1613      if (md->match_function_type == MATCH_CONDASSERT)      if (md->match_function_type == MATCH_CONDASSERT)
1614        {        {
1615        condassert = TRUE;        condassert = TRUE;
# Line 1611  for (;;) Line 1620  for (;;)
1620      do      do
1621        {        {
1622        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);
1623        md->mark = save_mark;        md->mark = save_mark;
1624        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);
1625        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
1626          {          {
# Line 1784  for (;;) Line 1793  for (;;)
1793            goto RECURSION_MATCHED;        /* Exit loop; end processing */            goto RECURSION_MATCHED;        /* Exit loop; end processing */
1794            }            }
1795    
1796          /* PCRE does not allow THEN to escape beyond a recursion; it is treated          /* PCRE does not allow THEN or COMMIT to escape beyond a recursion; it
1797          as NOMATCH. */          is treated as NOMATCH. */
1798    
1799          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN &&
1800                     rrc != MATCH_COMMIT)
1801            {            {
1802            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1803            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
# Line 1998  for (;;) Line 2008  for (;;)
2008          }          }
2009        if (*prev >= OP_SBRA)    /* Could match an empty string */        if (*prev >= OP_SBRA)    /* Could match an empty string */
2010          {          {
         md->match_function_type = MATCH_CBEGROUP;  
2011          RMATCH(eptr, prev, offset_top, md, eptrb, RM50);          RMATCH(eptr, prev, offset_top, md, eptrb, RM50);
2012          RRETURN(rrc);          RRETURN(rrc);
2013          }          }
# Line 2007  for (;;) Line 2016  for (;;)
2016        }        }
2017      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
2018        {        {
       if (*prev >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;  
2019        RMATCH(eptr, prev, offset_top, md, eptrb, RM13);        RMATCH(eptr, prev, offset_top, md, eptrb, RM13);
2020        if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH;        if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH;
2021        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
# Line 2064  for (;;) Line 2072  for (;;)
2072    
2073      case OP_DOLLM:      case OP_DOLLM:
2074      if (eptr < md->end_subject)      if (eptr < md->end_subject)
2075        { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }        {
2076          if (!IS_NEWLINE(eptr))
2077            {
2078            if (md->partial != 0 &&
2079                eptr + 1 >= md->end_subject &&
2080                NLBLOCK->nltype == NLTYPE_FIXED &&
2081                NLBLOCK->nllen == 2 &&
2082                *eptr == NLBLOCK->nl[0])
2083              {
2084              md->hitend = TRUE;
2085              if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2086              }
2087            RRETURN(MATCH_NOMATCH);
2088            }
2089          }
2090      else      else
2091        {        {
2092        if (md->noteol) RRETURN(MATCH_NOMATCH);        if (md->noteol) RRETURN(MATCH_NOMATCH);
# Line 2096  for (;;) Line 2118  for (;;)
2118      ASSERT_NL_OR_EOS:      ASSERT_NL_OR_EOS:
2119      if (eptr < md->end_subject &&      if (eptr < md->end_subject &&
2120          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
2121          {
2122          if (md->partial != 0 &&
2123              eptr + 1 >= md->end_subject &&
2124              NLBLOCK->nltype == NLTYPE_FIXED &&
2125              NLBLOCK->nllen == 2 &&
2126              *eptr == NLBLOCK->nl[0])
2127            {
2128            md->hitend = TRUE;
2129            if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2130            }
2131        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2132          }
2133    
2134      /* Either at end of string or \n before end. */      /* Either at end of string or \n before end. */
2135    
# Line 2224  for (;;) Line 2257  for (;;)
2257        }        }
2258      break;      break;
2259    
2260      /* Match a single character type; inline for speed */      /* Match any single character type except newline; have to take care with
2261        CRLF newlines and partial matching. */
2262    
2263      case OP_ANY:      case OP_ANY:
2264      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
2265        if (md->partial != 0 &&
2266            eptr + 1 >= md->end_subject &&
2267            NLBLOCK->nltype == NLTYPE_FIXED &&
2268            NLBLOCK->nllen == 2 &&
2269            *eptr == NLBLOCK->nl[0])
2270          {
2271          md->hitend = TRUE;
2272          if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2273          }
2274    
2275      /* Fall through */      /* Fall through */
2276    
2277        /* Match any single character whatsoever. */
2278    
2279      case OP_ALLANY:      case OP_ALLANY:
2280      if (eptr >= md->end_subject)   /* DO NOT merge the eptr++ here; it must */      if (eptr >= md->end_subject)   /* DO NOT merge the eptr++ here; it must */
2281        {                            /* not be updated before SCHECK_PARTIAL. */        {                            /* not be updated before SCHECK_PARTIAL. */
# Line 2370  for (;;) Line 2416  for (;;)
2416        default: RRETURN(MATCH_NOMATCH);        default: RRETURN(MATCH_NOMATCH);
2417    
2418        case 0x000d:        case 0x000d:
2419        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;        if (eptr >= md->end_subject)
2420            {
2421            SCHECK_PARTIAL();
2422            }
2423          else if (*eptr == 0x0a) eptr++;
2424        break;        break;
2425    
2426        case 0x000a:        case 0x000a:
# Line 2591  for (;;) Line 2641  for (;;)
2641        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2642        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2643        }        }
2644      GETCHARINCTEST(c, eptr);      else
2645      if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);        {
2646      while (eptr < md->end_subject)        int lgb, rgb;
2647        {        GETCHARINCTEST(c, eptr);
2648        int len = 1;        lgb = UCD_GRAPHBREAK(c);
2649        if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }        while (eptr < md->end_subject)
2650        if (UCD_CATEGORY(c) != ucp_M) break;          {
2651        eptr += len;          int len = 1;
2652            if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
2653            rgb = UCD_GRAPHBREAK(c);
2654            if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
2655            lgb = rgb;
2656            eptr += len;
2657            }
2658        }        }
2659        CHECK_PARTIAL();
2660      ecode++;      ecode++;
2661      break;      break;
2662  #endif  #endif
# Line 2665  for (;;) Line 2722  for (;;)
2722        default:               /* No repeat follows */        default:               /* No repeat follows */
2723        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)
2724          {          {
2725            if (length == -2) eptr = md->end_subject;   /* Partial match */
2726          CHECK_PARTIAL();          CHECK_PARTIAL();
2727          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2728          }          }
# Line 2690  for (;;) Line 2748  for (;;)
2748        int slength;        int slength;
2749        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2750          {          {
2751            if (slength == -2) eptr = md->end_subject;   /* Partial match */
2752          CHECK_PARTIAL();          CHECK_PARTIAL();
2753          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2754          }          }
# Line 2713  for (;;) Line 2772  for (;;)
2772          if (fi >= max) RRETURN(MATCH_NOMATCH);          if (fi >= max) RRETURN(MATCH_NOMATCH);
2773          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2774            {            {
2775              if (slength == -2) eptr = md->end_subject;   /* Partial match */
2776            CHECK_PARTIAL();            CHECK_PARTIAL();
2777            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2778            }            }
# Line 2731  for (;;) Line 2791  for (;;)
2791          int slength;          int slength;
2792          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2793            {            {
2794            CHECK_PARTIAL();            /* Can't use CHECK_PARTIAL because we don't want to update eptr in
2795              the soft partial matching case. */
2796    
2797              if (slength == -2 && md->partial != 0 &&
2798                  md->end_subject > md->start_used_ptr)
2799                {
2800                md->hitend = TRUE;
2801                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2802                }
2803            break;            break;
2804            }            }
2805          eptr += slength;          eptr += slength;
2806          }          }
2807    
2808        while (eptr >= pp)        while (eptr >= pp)
2809          {          {
2810          RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);          RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);
# Line 3365  for (;;) Line 3434  for (;;)
3434      maximizing, find the maximum number of characters and work backwards. */      maximizing, find the maximum number of characters and work backwards. */
3435    
3436      DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,      DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,
3437        max, eptr));        max, (char *)eptr));
3438    
3439      if (op >= OP_STARI)  /* Caseless */      if (op >= OP_STARI)  /* Caseless */
3440        {        {
# Line 3509  for (;;) Line 3578  for (;;)
3578        SCHECK_PARTIAL();        SCHECK_PARTIAL();
3579        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
3580        }        }
     ecode++;  
     GETCHARINCTEST(c, eptr);  
     if (op == OP_NOTI)         /* The caseless case */  
       {  
       register int ch, och;  
       ch = *ecode++;  
 #ifdef COMPILE_PCRE8  
       /* ch must be < 128 if UTF is enabled. */  
       och = md->fcc[ch];  
 #else  
3581  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3582        if (utf)
3583          {
3584          register unsigned int ch, och;
3585    
3586          ecode++;
3587          GETCHARINC(ch, ecode);
3588          GETCHARINC(c, eptr);
3589    
3590          if (op == OP_NOT)
3591            {
3592            if (ch == c) RRETURN(MATCH_NOMATCH);
3593            }
3594          else
3595            {
3596  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3597        if (utf && ch > 127)          if (ch > 127)
3598          och = UCD_OTHERCASE(ch);            och = UCD_OTHERCASE(ch);
3599  #else  #else
3600        if (utf && ch > 127)          if (ch > 127)
3601          och = ch;            och = ch;
3602  #endif /* SUPPORT_UCP */  #endif /* SUPPORT_UCP */
3603        else          else
3604  #endif /* SUPPORT_UTF */            och = TABLE_GET(ch, md->fcc, ch);
3605          och = TABLE_GET(ch, md->fcc, ch);          if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
3606  #endif /* COMPILE_PCRE8 */          }
       if (ch == c || och == c) RRETURN(MATCH_NOMATCH);  
3607        }        }
3608      else    /* Caseful */      else
3609    #endif
3610        {        {
3611        if (*ecode++ == c) RRETURN(MATCH_NOMATCH);        register unsigned int ch = ecode[1];
3612          c = *eptr++;
3613          if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c))
3614            RRETURN(MATCH_NOMATCH);
3615          ecode += 2;
3616        }        }
3617      break;      break;
3618    
# Line 3615  for (;;) Line 3692  for (;;)
3692      /* Common code for all repeated single-byte matches. */      /* Common code for all repeated single-byte matches. */
3693    
3694      REPEATNOTCHAR:      REPEATNOTCHAR:
3695      fc = *ecode++;      GETCHARINCTEST(fc, ecode);
3696    
3697      /* The code is duplicated for the caseless and caseful cases, for speed,      /* The code is duplicated for the caseless and caseful cases, for speed,
3698      since matching characters is likely to be quite common. First, ensure the      since matching characters is likely to be quite common. First, ensure the
# Line 3626  for (;;) Line 3703  for (;;)
3703      characters and work backwards. */      characters and work backwards. */
3704    
3705      DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max,      DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max,
3706        max, eptr));        max, (char *)eptr));
3707    
3708      if (op >= OP_NOTSTARI)     /* Caseless */      if (op >= OP_NOTSTARI)     /* Caseless */
3709        {        {
 #ifdef COMPILE_PCRE8  
       /* fc must be < 128 if UTF is enabled. */  
       foc = md->fcc[fc];  
 #else  
3710  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3711  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3712        if (utf && fc > 127)        if (utf && fc > 127)
# Line 3645  for (;;) Line 3718  for (;;)
3718        else        else
3719  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
3720          foc = TABLE_GET(fc, md->fcc, fc);          foc = TABLE_GET(fc, md->fcc, fc);
 #endif /* COMPILE_PCRE8 */  
3721    
3722  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3723        if (utf)        if (utf)
# Line 3659  for (;;) Line 3731  for (;;)
3731              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3732              }              }
3733            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3734            if (fc == d || foc == d) RRETURN(MATCH_NOMATCH);            if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
3735            }            }
3736          }          }
3737        else        else
# Line 3697  for (;;) Line 3769  for (;;)
3769                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3770                }                }
3771              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3772              if (fc == d || foc == d) RRETURN(MATCH_NOMATCH);              if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
3773              }              }
3774            }            }
3775          else          else
# Line 3740  for (;;) Line 3812  for (;;)
3812                break;                break;
3813                }                }
3814              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3815              if (fc == d || foc == d) break;              if (fc == d || (unsigned int)foc == d) break;
3816              eptr += len;              eptr += len;
3817              }              }
3818            if (possessive) continue;            if (possessive) continue;
# Line 4160  for (;;) Line 4232  for (;;)
4232              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4233              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4234              }              }
4235            GETCHARINCTEST(c, eptr);            else
4236            if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);              {
4237            while (eptr < md->end_subject)              int lgb, rgb;
4238              {              GETCHARINCTEST(c, eptr);
4239              int len = 1;              lgb = UCD_GRAPHBREAK(c);
4240              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }             while (eptr < md->end_subject)
4241              if (UCD_CATEGORY(c) != ucp_M) break;                {
4242              eptr += len;                int len = 1;
4243                  if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
4244                  rgb = UCD_GRAPHBREAK(c);
4245                  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
4246                  lgb = rgb;
4247                  eptr += len;
4248                  }
4249              }              }
4250              CHECK_PARTIAL();
4251            }            }
4252          }          }
4253    
# Line 4189  for (;;) Line 4268  for (;;)
4268              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4269              }              }
4270            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4271              if (md->partial != 0 &&
4272                  eptr + 1 >= md->end_subject &&
4273                  NLBLOCK->nltype == NLTYPE_FIXED &&
4274                  NLBLOCK->nllen == 2 &&
4275                  *eptr == NLBLOCK->nl[0])
4276                {
4277                md->hitend = TRUE;
4278                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
4279                }
4280            eptr++;            eptr++;
4281            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4282            }            }
# Line 4473  for (;;) Line 4561  for (;;)
4561              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4562              }              }
4563            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4564              if (md->partial != 0 &&
4565                  eptr + 1 >= md->end_subject &&
4566                  NLBLOCK->nltype == NLTYPE_FIXED &&
4567                  NLBLOCK->nllen == 2 &&
4568                  *eptr == NLBLOCK->nl[0])
4569                {
4570                md->hitend = TRUE;
4571                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
4572                }
4573            eptr++;            eptr++;
4574            }            }
4575          break;          break;
# Line 4944  for (;;) Line 5041  for (;;)
5041              SCHECK_PARTIAL();              SCHECK_PARTIAL();
5042              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
5043              }              }
5044            GETCHARINCTEST(c, eptr);            else
5045            if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);              {
5046            while (eptr < md->end_subject)              int lgb, rgb;
5047              {              GETCHARINCTEST(c, eptr);
5048              int len = 1;              lgb = UCD_GRAPHBREAK(c);
5049              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }              while (eptr < md->end_subject)
5050              if (UCD_CATEGORY(c) != ucp_M) break;                {
5051              eptr += len;                int len = 1;
5052                  if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
5053                  rgb = UCD_GRAPHBREAK(c);
5054                  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
5055                  lgb = rgb;
5056                  eptr += len;
5057                  }
5058              }              }
5059              CHECK_PARTIAL();
5060            }            }
5061          }          }
5062        else        else
# Line 4976  for (;;) Line 5080  for (;;)
5080            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
5081            switch(ctype)            switch(ctype)
5082              {              {
5083              case OP_ANY:        /* This is the non-NL case */              case OP_ANY:               /* This is the non-NL case */
5084                if (md->partial != 0 &&    /* Take care with CRLF partial */
5085                    eptr >= md->end_subject &&
5086                    NLBLOCK->nltype == NLTYPE_FIXED &&
5087                    NLBLOCK->nllen == 2 &&
5088                    c == NLBLOCK->nl[0])
5089                  {
5090                  md->hitend = TRUE;
5091                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5092                  }
5093                break;
5094    
5095              case OP_ALLANY:              case OP_ALLANY:
5096              case OP_ANYBYTE:              case OP_ANYBYTE:
5097              break;              break;
# Line 5139  for (;;) Line 5254  for (;;)
5254            c = *eptr++;            c = *eptr++;
5255            switch(ctype)            switch(ctype)
5256              {              {
5257              case OP_ANY:     /* This is the non-NL case */              case OP_ANY:               /* This is the non-NL case */
5258                if (md->partial != 0 &&    /* Take care with CRLF partial */
5259                    eptr >= md->end_subject &&
5260                    NLBLOCK->nltype == NLTYPE_FIXED &&
5261                    NLBLOCK->nllen == 2 &&
5262                    c == NLBLOCK->nl[0])
5263                  {
5264                  md->hitend = TRUE;
5265                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5266                  }
5267                break;
5268    
5269              case OP_ALLANY:              case OP_ALLANY:
5270              case OP_ANYBYTE:              case OP_ANYBYTE:
5271              break;              break;
# Line 5480  for (;;) Line 5606  for (;;)
5606          {          {
5607          for (i = min; i < max; i++)          for (i = min; i < max; i++)
5608            {            {
           int len = 1;  
5609            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
5610              {              {
5611              SCHECK_PARTIAL();              SCHECK_PARTIAL();
5612              break;              break;
5613              }              }
5614            if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }            else
5615            if (UCD_CATEGORY(c) == ucp_M) break;              {
5616            eptr += len;              int lgb, rgb;
5617            while (eptr < md->end_subject)              GETCHARINCTEST(c, eptr);
5618              {              lgb = UCD_GRAPHBREAK(c);
5619              len = 1;              while (eptr < md->end_subject)
5620              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }                {
5621              if (UCD_CATEGORY(c) != ucp_M) break;                int len = 1;
5622              eptr += len;                if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
5623                  rgb = UCD_GRAPHBREAK(c);
5624                  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
5625                  lgb = rgb;
5626                  eptr += len;
5627                  }
5628              }              }
5629              CHECK_PARTIAL();
5630            }            }
5631    
5632          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
# Line 5539  for (;;) Line 5670  for (;;)
5670                  break;                  break;
5671                  }                  }
5672                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5673                  if (md->partial != 0 &&    /* Take care with CRLF partial */
5674                      eptr + 1 >= md->end_subject &&
5675                      NLBLOCK->nltype == NLTYPE_FIXED &&
5676                      NLBLOCK->nllen == 2 &&
5677                      *eptr == NLBLOCK->nl[0])
5678                    {
5679                    md->hitend = TRUE;
5680                    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5681                    }
5682                eptr++;                eptr++;
5683                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5684                }                }
# Line 5556  for (;;) Line 5696  for (;;)
5696                  break;                  break;
5697                  }                  }
5698                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5699                  if (md->partial != 0 &&    /* Take care with CRLF partial */
5700                      eptr + 1 >= md->end_subject &&
5701                      NLBLOCK->nltype == NLTYPE_FIXED &&
5702                      NLBLOCK->nllen == 2 &&
5703                      *eptr == NLBLOCK->nl[0])
5704                    {
5705                    md->hitend = TRUE;
5706                    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5707                    }
5708                eptr++;                eptr++;
5709                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5710                }                }
# Line 5820  for (;;) Line 5969  for (;;)
5969                break;                break;
5970                }                }
5971              if (IS_NEWLINE(eptr)) break;              if (IS_NEWLINE(eptr)) break;
5972                if (md->partial != 0 &&    /* Take care with CRLF partial */
5973                    eptr + 1 >= md->end_subject &&
5974                    NLBLOCK->nltype == NLTYPE_FIXED &&
5975                    NLBLOCK->nllen == 2 &&
5976                    *eptr == NLBLOCK->nl[0])
5977                  {
5978                  md->hitend = TRUE;
5979                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5980                  }
5981              eptr++;              eptr++;
5982              }              }
5983            break;            break;
# Line 6150  Undefine all the macros that were define Line 6308  Undefine all the macros that were define
6308  ***************************************************************************/  ***************************************************************************/
6309    
6310    
6311    #ifdef NO_RECURSE
6312    /*************************************************
6313    *          Release allocated heap frames         *
6314    *************************************************/
6315    
6316    /* This function releases all the allocated frames. The base frame is on the
6317    machine stack, and so must not be freed.
6318    
6319    Argument: the address of the base frame
6320    Returns:  nothing
6321    */
6322    
6323    static void
6324    release_match_heapframes (heapframe *frame_base)
6325    {
6326    heapframe *nextframe = frame_base->Xnextframe;
6327    while (nextframe != NULL)
6328      {
6329      heapframe *oldframe = nextframe;
6330      nextframe = nextframe->Xnextframe;
6331      (PUBL(stack_free))(oldframe);
6332      }
6333    }
6334    #endif
6335    
6336    
6337  /*************************************************  /*************************************************
6338  *         Execute a Regular Expression           *  *         Execute a Regular Expression           *
# Line 6212  PCRE_PUCHAR req_char_ptr = start_match - Line 6395  PCRE_PUCHAR req_char_ptr = start_match -
6395  const pcre_study_data *study;  const pcre_study_data *study;
6396  const REAL_PCRE *re = (const REAL_PCRE *)argument_re;  const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
6397    
6398  /* Check for the special magic call that measures the size of the stack used  #ifdef NO_RECURSE
6399  per recursive call of match(). */  heapframe frame_zero;
6400    frame_zero.Xprevframe = NULL;            /* Marks the top level */
6401    frame_zero.Xnextframe = NULL;            /* None are allocated yet */
6402    md->match_frames_base = &frame_zero;
6403    #endif
6404    
6405  if (re == NULL && extra_data == NULL && subject == NULL && length == -1)  /* Check for the special magic call that measures the size of the stack used
6406    per recursive call of match(). Without the funny casting for sizeof, a Windows
6407    compiler gave this error: "unary minus operator applied to unsigned type,
6408    result still unsigned". Hopefully the cast fixes that. */
6409    
6410    if (re == NULL && extra_data == NULL && subject == NULL && length == -999 &&
6411        start_offset == -999)
6412  #ifdef NO_RECURSE  #ifdef NO_RECURSE
6413    return -sizeof(heapframe);    return -((int)sizeof(heapframe));
6414  #else  #else
6415    return match((PCRE_PUCHAR)&start_partial, NULL, NULL, 0, NULL, NULL, 0);    return match(NULL, NULL, NULL, 0, NULL, NULL, 0);
6416  #endif  #endif
6417    
6418  /* Plausibility checks */  /* Plausibility checks */
6419    
6420  if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;  if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
6421  if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0))  if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0))
6422    return PCRE_ERROR_NULL;    return PCRE_ERROR_NULL;
6423  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
6424  if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;  if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
# Line 6284  if (utf && (options & PCRE_NO_UTF8_CHECK Line 6477  if (utf && (options & PCRE_NO_UTF8_CHECK
6477  /* If the pattern was successfully studied with JIT support, run the JIT  /* If the pattern was successfully studied with JIT support, run the JIT
6478  executable instead of the rest of this function. Most options must be set at  executable instead of the rest of this function. Most options must be set at
6479  compile time for the JIT code to be usable. Fallback to the normal code path if  compile time for the JIT code to be usable. Fallback to the normal code path if
6480  an unsupported flag is set. In particular, JIT does not support partial  an unsupported flag is set. */
 matching. */  
6481    
6482  #ifdef SUPPORT_JIT  #ifdef SUPPORT_JIT
6483  if (extra_data != NULL  if (extra_data != NULL
6484      && (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0      && (extra_data->flags & (PCRE_EXTRA_EXECUTABLE_JIT |
6485                                 PCRE_EXTRA_TABLES)) == PCRE_EXTRA_EXECUTABLE_JIT
6486      && extra_data->executable_jit != NULL      && extra_data->executable_jit != NULL
     && (extra_data->flags & PCRE_EXTRA_TABLES) == 0  
6487      && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |      && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |
6488                      PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART)) == 0)                      PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART |
6489    return PRIV(jit_exec)(re, extra_data->executable_jit,                      PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD)) == 0)
6490      (const pcre_uchar *)subject, length, start_offset, options,    {
6491      ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0)    rc = PRIV(jit_exec)(re, extra_data, (const pcre_uchar *)subject, length,
6492      ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount);         start_offset, options, offsets, offsetcount);
6493    
6494      /* PCRE_ERROR_NULL means that the selected normal or partial matching
6495      mode is not compiled. In this case we simply fallback to interpreter. */
6496    
6497      if (rc != PCRE_ERROR_NULL) return rc;
6498      }
6499  #endif  #endif
6500    
6501  /* Carry on with non-JIT matching. This information is for finding all the  /* Carry on with non-JIT matching. This information is for finding all the
# Line 6500  if (!anchored) Line 6698  if (!anchored)
6698    if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->flags & PCRE_FIRSTSET) != 0)
6699      {      {
6700      has_first_char = TRUE;      has_first_char = TRUE;
6701      first_char = first_char2 = re->first_char;      first_char = first_char2 = (pcre_uchar)(re->first_char);
6702      if ((re->flags & PCRE_FCH_CASELESS) != 0)      if ((re->flags & PCRE_FCH_CASELESS) != 0)
6703        {        {
6704        first_char2 = TABLE_GET(first_char, md->fcc, first_char);        first_char2 = TABLE_GET(first_char, md->fcc, first_char);
# Line 6522  character" set. */ Line 6720  character" set. */
6720  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
6721    {    {
6722    has_req_char = TRUE;    has_req_char = TRUE;
6723    req_char = req_char2 = re->req_char;    req_char = req_char2 = (pcre_uchar)(re->req_char);
6724    if ((re->flags & PCRE_RCH_CASELESS) != 0)    if ((re->flags & PCRE_RCH_CASELESS) != 0)
6725      {      {
6726      req_char2 = TABLE_GET(req_char, md->fcc, req_char);      req_char2 = TABLE_GET(req_char, md->fcc, req_char);
# Line 6891  if (rc == MATCH_MATCH || rc == MATCH_ACC Line 7089  if (rc == MATCH_MATCH || rc == MATCH_ACC
7089      {      {
7090      register int *iptr, *iend;      register int *iptr, *iend;
7091      int resetcount = 2 + re->top_bracket * 2;      int resetcount = 2 + re->top_bracket * 2;
7092      if (resetcount > offsetcount) resetcount = ocount;      if (resetcount > offsetcount) resetcount = offsetcount;
7093      iptr = offsets + md->end_offset_top;      iptr = offsets + md->end_offset_top;
7094      iend = offsets + resetcount;      iend = offsets + resetcount;
7095      while (iptr < iend) *iptr++ = -1;      while (iptr < iend) *iptr++ = -1;
# Line 6912  if (rc == MATCH_MATCH || rc == MATCH_ACC Line 7110  if (rc == MATCH_MATCH || rc == MATCH_ACC
7110    if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)    if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
7111      *(extra_data->mark) = (pcre_uchar *)md->mark;      *(extra_data->mark) = (pcre_uchar *)md->mark;
7112    DPRINTF((">>>> returning %d\n", rc));    DPRINTF((">>>> returning %d\n", rc));
7113    #ifdef NO_RECURSE
7114      release_match_heapframes(&frame_zero);
7115    #endif
7116    return rc;    return rc;
7117    }    }
7118    
# Line 6929  if (using_temporary_offsets) Line 7130  if (using_temporary_offsets)
7130  if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)  if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)
7131    {    {
7132    DPRINTF((">>>> error: returning %d\n", rc));    DPRINTF((">>>> error: returning %d\n", rc));
7133    #ifdef NO_RECURSE
7134      release_match_heapframes(&frame_zero);
7135    #endif
7136    return rc;    return rc;
7137    }    }
7138    
# Line 6958  else Line 7162  else
7162    
7163  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
7164    *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;    *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;
7165    #ifdef NO_RECURSE
7166      release_match_heapframes(&frame_zero);
7167    #endif
7168  return rc;  return rc;
7169  }  }
7170    

Legend:
Removed from v.893  
changed lines
  Added in v.1015

  ViewVC Help
Powered by ViewVC 1.1.5