/[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 895 by ph10, Fri Jan 20 12:12:03 2012 UTC revision 937 by ph10, Sun Feb 26 15:58:56 2012 UTC
# Line 140  Arguments: Line 140  Arguments:
140    md          points to match data block    md          points to match data block
141    caseless    TRUE if caseless    caseless    TRUE if caseless
142    
143  Returns:      < 0 if not matched, otherwise the number of subject bytes matched  Returns:      >= 0 the number of subject bytes matched
144                  -1 no match
145                  -2 partial match; always given if at end subject
146  */  */
147    
148  static int  static int
# Line 163  pchars(p, length, FALSE, md); Line 165  pchars(p, length, FALSE, md);
165  printf("\n");  printf("\n");
166  #endif  #endif
167    
168  /* Always fail if reference not set (and not JavaScript compatible). */  /* Always fail if reference not set (and not JavaScript compatible - in that
169    case the length is passed as zero). */
170    
171  if (length < 0) return -1;  if (length < 0) return -1;
172    
# Line 189  if (caseless) Line 192  if (caseless)
192      while (p < endptr)      while (p < endptr)
193        {        {
194        int c, d;        int c, d;
195        if (eptr >= md->end_subject) return -1;        if (eptr >= md->end_subject) return -2;   /* Partial match */
196        GETCHARINC(c, eptr);        GETCHARINC(c, eptr);
197        GETCHARINC(d, p);        GETCHARINC(d, p);
198        if (c != d && c != UCD_OTHERCASE(d)) return -1;        if (c != d && c != UCD_OTHERCASE(d)) return -1;
# Line 202  if (caseless) Line 205  if (caseless)
205    /* 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
206    is no UCP support. */    is no UCP support. */
207      {      {
     if (eptr + length > md->end_subject) return -1;  
208      while (length-- > 0)      while (length-- > 0)
209        {        {
210          if (eptr >= md->end_subject) return -2;   /* Partial match */
211        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;
212        p++;        p++;
213        eptr++;        eptr++;
# Line 217  are in UTF-8 mode. */ Line 220  are in UTF-8 mode. */
220    
221  else  else
222    {    {
223    if (eptr + length > md->end_subject) return -1;    while (length-- > 0)
224    while (length-- > 0) if (*p++ != *eptr++) return -1;      {
225        if (eptr >= md->end_subject) return -2;   /* Partial match */
226        if (*p++ != *eptr++) return -1;
227        }
228    }    }
229    
230  return (int)(eptr - eptr_start);  return (int)(eptr - eptr_start);
# Line 311  argument of match(), which never changes Line 317  argument of match(), which never changes
317    
318  #define RMATCH(ra,rb,rc,rd,re,rw)\  #define RMATCH(ra,rb,rc,rd,re,rw)\
319    {\    {\
320    heapframe *newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\    heapframe *newframe = frame->Xnextframe;\
321    if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\    if (newframe == NULL)\
322    frame->Xwhere = rw; \      {\
323        newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\
324        if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
325        newframe->Xnextframe = NULL;\
326        frame->Xnextframe = newframe;\
327        }\
328      frame->Xwhere = rw;\
329    newframe->Xeptr = ra;\    newframe->Xeptr = ra;\
330    newframe->Xecode = rb;\    newframe->Xecode = rb;\
331    newframe->Xmstart = mstart;\    newframe->Xmstart = mstart;\
# Line 332  argument of match(), which never changes Line 344  argument of match(), which never changes
344    {\    {\
345    heapframe *oldframe = frame;\    heapframe *oldframe = frame;\
346    frame = oldframe->Xprevframe;\    frame = oldframe->Xprevframe;\
   if (oldframe != &frame_zero) (PUBL(stack_free))(oldframe);\  
347    if (frame != NULL)\    if (frame != NULL)\
348      {\      {\
349      rrc = ra;\      rrc = ra;\
# Line 346  argument of match(), which never changes Line 357  argument of match(), which never changes
357    
358  typedef struct heapframe {  typedef struct heapframe {
359    struct heapframe *Xprevframe;    struct heapframe *Xprevframe;
360      struct heapframe *Xnextframe;
361    
362    /* Function arguments that may change */    /* Function arguments that may change */
363    
# Line 487  int condcode; Line 499  int condcode;
499  /* 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
500  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
501  frame on the stack here; subsequent instantiations are obtained from the heap  frame on the stack here; subsequent instantiations are obtained from the heap
502  whenever RMATCH() does a "recursion". See the macro definitions above. Putting  whenever RMATCH() does a "recursion". See the macro definitions above. Putting
503  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
504  boost in many cases where there is not much "recursion". */  boost in many cases where there is not much "recursion". */
505    
506  #ifdef NO_RECURSE  #ifdef NO_RECURSE
507  heapframe frame_zero;  heapframe *frame = (heapframe *)md->match_frames_base;
 heapframe *frame = &frame_zero;  
 frame->Xprevframe = NULL;            /* Marks the top level */  
508    
509  /* Copy in the original argument variables */  /* Copy in the original argument variables */
510    
# Line 616  int stacksave[REC_STACK_SAVE_MAX]; Line 626  int stacksave[REC_STACK_SAVE_MAX];
626    
627  eptrblock newptrb;  eptrblock newptrb;
628    
629  /* 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
630  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
631  recursion. The second argument (ecode) being NULL triggers this behaviour. It  recursion. The second argument (ecode) being NULL triggers this behaviour. It
632  cannot normally every be NULL. The return is the negated value of the frame  cannot normally ever be NULL. The return is the negated value of the frame
633  size. */  size. */
634    
635  if (ecode == NULL)  if (ecode == NULL)
# Line 631  if (ecode == NULL) Line 641  if (ecode == NULL)
641      int len = (char *)&rdepth - (char *)eptr;      int len = (char *)&rdepth - (char *)eptr;
642      return (len > 0)? -len : len;      return (len > 0)? -len : len;
643      }      }
644    }    }
645  #endif     /* NO_RECURSE */  #endif     /* NO_RECURSE */
646    
647  /* 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 838  for (;;) Line 848  for (;;)
848      case OP_ONCE_NC:      case OP_ONCE_NC:
849      prev = ecode;      prev = ecode;
850      saved_eptr = eptr;      saved_eptr = eptr;
851      save_mark = md->mark;      save_mark = md->mark;
852      do      do
853        {        {
854        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64);
# Line 857  for (;;) Line 867  for (;;)
867    
868        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
869        ecode += GET(ecode,1);        ecode += GET(ecode,1);
870        md->mark = save_mark;        md->mark = save_mark;
871        }        }
872      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
873    
# Line 937  for (;;) Line 947  for (;;)
947        save_offset2 = md->offset_vector[offset+1];        save_offset2 = md->offset_vector[offset+1];
948        save_offset3 = md->offset_vector[md->offset_end - number];        save_offset3 = md->offset_vector[md->offset_end - number];
949        save_capture_last = md->capture_last;        save_capture_last = md->capture_last;
950        save_mark = md->mark;        save_mark = md->mark;
951    
952        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
953        md->offset_vector[md->offset_end - number] =        md->offset_vector[md->offset_end - number] =
# Line 1043  for (;;) Line 1053  for (;;)
1053        save_mark = md->mark;        save_mark = md->mark;
1054        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
1055          RM2);          RM2);
1056    
1057        /* See comment in the code for capturing groups above about handling        /* See comment in the code for capturing groups above about handling
1058        THEN. */        THEN. */
1059    
# Line 1070  for (;;) Line 1080  for (;;)
1080          RRETURN(rrc);          RRETURN(rrc);
1081          }          }
1082        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1083        md->mark = save_mark;        md->mark = save_mark;
1084        if (*ecode != OP_ALT) break;        if (*ecode != OP_ALT) break;
1085        }        }
1086    
# Line 1549  for (;;) Line 1559  for (;;)
1559    
1560      case OP_ASSERT:      case OP_ASSERT:
1561      case OP_ASSERTBACK:      case OP_ASSERTBACK:
1562      save_mark = md->mark;      save_mark = md->mark;
1563      if (md->match_function_type == MATCH_CONDASSERT)      if (md->match_function_type == MATCH_CONDASSERT)
1564        {        {
1565        condassert = TRUE;        condassert = TRUE;
# Line 1566  for (;;) Line 1576  for (;;)
1576          break;          break;
1577          }          }
1578    
1579        /* PCRE does not allow THEN to escape beyond an assertion; it is treated        /* PCRE does not allow THEN or COMMIT to escape beyond an assertion; it
1580        as NOMATCH. */        is treated as NOMATCH. */
1581    
1582        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN &&
1583              rrc != MATCH_COMMIT) RRETURN(rrc);
1584    
1585        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1586        md->mark = save_mark;        md->mark = save_mark;
1587        }        }
1588      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
1589    
# Line 1595  for (;;) Line 1607  for (;;)
1607    
1608      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1609      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
1610      save_mark = md->mark;      save_mark = md->mark;
1611      if (md->match_function_type == MATCH_CONDASSERT)      if (md->match_function_type == MATCH_CONDASSERT)
1612        {        {
1613        condassert = TRUE;        condassert = TRUE;
# Line 1606  for (;;) Line 1618  for (;;)
1618      do      do
1619        {        {
1620        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);
1621        md->mark = save_mark;        md->mark = save_mark;
1622        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);
1623        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
1624          {          {
# Line 1779  for (;;) Line 1791  for (;;)
1791            goto RECURSION_MATCHED;        /* Exit loop; end processing */            goto RECURSION_MATCHED;        /* Exit loop; end processing */
1792            }            }
1793    
1794          /* 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
1795          as NOMATCH. */          is treated as NOMATCH. */
1796    
1797          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN &&
1798                     rrc != MATCH_COMMIT)
1799            {            {
1800            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1801            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
# Line 2059  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 2091  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 2219  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 2365  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 2595  for (;;) Line 2650  for (;;)
2650        if (UCD_CATEGORY(c) != ucp_M) break;        if (UCD_CATEGORY(c) != ucp_M) break;
2651        eptr += len;        eptr += len;
2652        }        }
2653        CHECK_PARTIAL();
2654      ecode++;      ecode++;
2655      break;      break;
2656  #endif  #endif
# Line 2660  for (;;) Line 2716  for (;;)
2716        default:               /* No repeat follows */        default:               /* No repeat follows */
2717        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)
2718          {          {
2719            if (length == -2) eptr = md->end_subject;   /* Partial match */
2720          CHECK_PARTIAL();          CHECK_PARTIAL();
2721          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2722          }          }
# Line 2685  for (;;) Line 2742  for (;;)
2742        int slength;        int slength;
2743        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2744          {          {
2745            if (slength == -2) eptr = md->end_subject;   /* Partial match */
2746          CHECK_PARTIAL();          CHECK_PARTIAL();
2747          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2748          }          }
# Line 2708  for (;;) Line 2766  for (;;)
2766          if (fi >= max) RRETURN(MATCH_NOMATCH);          if (fi >= max) RRETURN(MATCH_NOMATCH);
2767          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2768            {            {
2769              if (slength == -2) eptr = md->end_subject;   /* Partial match */
2770            CHECK_PARTIAL();            CHECK_PARTIAL();
2771            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2772            }            }
# Line 2726  for (;;) Line 2785  for (;;)
2785          int slength;          int slength;
2786          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2787            {            {
2788            CHECK_PARTIAL();            /* Can't use CHECK_PARTIAL because we don't want to update eptr in
2789              the soft partial matching case. */
2790    
2791              if (slength == -2 && md->partial != 0 &&
2792                  md->end_subject > md->start_used_ptr)
2793                {
2794                md->hitend = TRUE;
2795                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2796                }
2797            break;            break;
2798            }            }
2799          eptr += slength;          eptr += slength;
2800          }          }
2801    
2802        while (eptr >= pp)        while (eptr >= pp)
2803          {          {
2804          RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);          RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);
# Line 3504  for (;;) Line 3572  for (;;)
3572        SCHECK_PARTIAL();        SCHECK_PARTIAL();
3573        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
3574        }        }
     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  
3575  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3576        if (utf)
3577          {
3578          register unsigned int ch, och;
3579    
3580          ecode++;
3581          GETCHARINC(ch, ecode);
3582          GETCHARINC(c, eptr);
3583    
3584          if (op == OP_NOT)
3585            {
3586            if (ch == c) RRETURN(MATCH_NOMATCH);
3587            }
3588          else
3589            {
3590  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3591        if (utf && ch > 127)          if (ch > 127)
3592          och = UCD_OTHERCASE(ch);            och = UCD_OTHERCASE(ch);
3593  #else  #else
3594        if (utf && ch > 127)          if (ch > 127)
3595          och = ch;            och = ch;
3596  #endif /* SUPPORT_UCP */  #endif /* SUPPORT_UCP */
3597        else          else
3598  #endif /* SUPPORT_UTF */            och = TABLE_GET(ch, md->fcc, ch);
3599          och = TABLE_GET(ch, md->fcc, ch);          if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
3600  #endif /* COMPILE_PCRE8 */          }
       if (ch == c || och == c) RRETURN(MATCH_NOMATCH);  
3601        }        }
3602      else    /* Caseful */      else
3603    #endif
3604        {        {
3605        if (*ecode++ == c) RRETURN(MATCH_NOMATCH);        register unsigned int ch = ecode[1];
3606          c = *eptr++;
3607          if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c))
3608            RRETURN(MATCH_NOMATCH);
3609          ecode += 2;
3610        }        }
3611      break;      break;
3612    
# Line 3610  for (;;) Line 3686  for (;;)
3686      /* Common code for all repeated single-byte matches. */      /* Common code for all repeated single-byte matches. */
3687    
3688      REPEATNOTCHAR:      REPEATNOTCHAR:
3689      fc = *ecode++;      GETCHARINCTEST(fc, ecode);
3690    
3691      /* The code is duplicated for the caseless and caseful cases, for speed,      /* The code is duplicated for the caseless and caseful cases, for speed,
3692      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 3625  for (;;) Line 3701  for (;;)
3701    
3702      if (op >= OP_NOTSTARI)     /* Caseless */      if (op >= OP_NOTSTARI)     /* Caseless */
3703        {        {
 #ifdef COMPILE_PCRE8  
       /* fc must be < 128 if UTF is enabled. */  
       foc = md->fcc[fc];  
 #else  
3704  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3705  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3706        if (utf && fc > 127)        if (utf && fc > 127)
# Line 3640  for (;;) Line 3712  for (;;)
3712        else        else
3713  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
3714          foc = TABLE_GET(fc, md->fcc, fc);          foc = TABLE_GET(fc, md->fcc, fc);
 #endif /* COMPILE_PCRE8 */  
3715    
3716  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3717        if (utf)        if (utf)
# Line 3654  for (;;) Line 3725  for (;;)
3725              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3726              }              }
3727            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3728            if (fc == d || foc == d) RRETURN(MATCH_NOMATCH);            if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
3729            }            }
3730          }          }
3731        else        else
# Line 3692  for (;;) Line 3763  for (;;)
3763                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3764                }                }
3765              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3766              if (fc == d || foc == d) RRETURN(MATCH_NOMATCH);              if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
3767              }              }
3768            }            }
3769          else          else
# Line 3735  for (;;) Line 3806  for (;;)
3806                break;                break;
3807                }                }
3808              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3809              if (fc == d || foc == d) break;              if (fc == d || (unsigned int)foc == d) break;
3810              eptr += len;              eptr += len;
3811              }              }
3812            if (possessive) continue;            if (possessive) continue;
# Line 4164  for (;;) Line 4235  for (;;)
4235              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
4236              eptr += len;              eptr += len;
4237              }              }
4238              CHECK_PARTIAL();
4239            }            }
4240          }          }
4241    
# Line 4184  for (;;) Line 4256  for (;;)
4256              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4257              }              }
4258            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4259              if (md->partial != 0 &&
4260                  eptr + 1 >= md->end_subject &&
4261                  NLBLOCK->nltype == NLTYPE_FIXED &&
4262                  NLBLOCK->nllen == 2 &&
4263                  *eptr == NLBLOCK->nl[0])
4264                {
4265                md->hitend = TRUE;
4266                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
4267                }
4268            eptr++;            eptr++;
4269            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4270            }            }
# Line 4468  for (;;) Line 4549  for (;;)
4549              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4550              }              }
4551            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4552              if (md->partial != 0 &&
4553                  eptr + 1 >= md->end_subject &&
4554                  NLBLOCK->nltype == NLTYPE_FIXED &&
4555                  NLBLOCK->nllen == 2 &&
4556                  *eptr == NLBLOCK->nl[0])
4557                {
4558                md->hitend = TRUE;
4559                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
4560                }
4561            eptr++;            eptr++;
4562            }            }
4563          break;          break;
# Line 4948  for (;;) Line 5038  for (;;)
5038              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
5039              eptr += len;              eptr += len;
5040              }              }
5041              CHECK_PARTIAL();
5042            }            }
5043          }          }
5044        else        else
# Line 4971  for (;;) Line 5062  for (;;)
5062            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
5063            switch(ctype)            switch(ctype)
5064              {              {
5065              case OP_ANY:        /* This is the non-NL case */              case OP_ANY:               /* This is the non-NL case */
5066                if (md->partial != 0 &&    /* Take care with CRLF partial */
5067                    eptr >= md->end_subject &&
5068                    NLBLOCK->nltype == NLTYPE_FIXED &&
5069                    NLBLOCK->nllen == 2 &&
5070                    c == NLBLOCK->nl[0])
5071                  {
5072                  md->hitend = TRUE;
5073                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5074                  }
5075                break;
5076    
5077              case OP_ALLANY:              case OP_ALLANY:
5078              case OP_ANYBYTE:              case OP_ANYBYTE:
5079              break;              break;
# Line 5134  for (;;) Line 5236  for (;;)
5236            c = *eptr++;            c = *eptr++;
5237            switch(ctype)            switch(ctype)
5238              {              {
5239              case OP_ANY:     /* This is the non-NL case */              case OP_ANY:               /* This is the non-NL case */
5240                if (md->partial != 0 &&    /* Take care with CRLF partial */
5241                    eptr >= md->end_subject &&
5242                    NLBLOCK->nltype == NLTYPE_FIXED &&
5243                    NLBLOCK->nllen == 2 &&
5244                    c == NLBLOCK->nl[0])
5245                  {
5246                  md->hitend = TRUE;
5247                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5248                  }
5249                break;
5250    
5251              case OP_ALLANY:              case OP_ALLANY:
5252              case OP_ANYBYTE:              case OP_ANYBYTE:
5253              break;              break;
# Line 5491  for (;;) Line 5604  for (;;)
5604              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
5605              eptr += len;              eptr += len;
5606              }              }
5607              CHECK_PARTIAL();
5608            }            }
5609    
5610          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
# Line 5534  for (;;) Line 5648  for (;;)
5648                  break;                  break;
5649                  }                  }
5650                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5651                  if (md->partial != 0 &&    /* Take care with CRLF partial */
5652                      eptr + 1 >= md->end_subject &&
5653                      NLBLOCK->nltype == NLTYPE_FIXED &&
5654                      NLBLOCK->nllen == 2 &&
5655                      *eptr == NLBLOCK->nl[0])
5656                    {
5657                    md->hitend = TRUE;
5658                    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5659                    }
5660                eptr++;                eptr++;
5661                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5662                }                }
# Line 5551  for (;;) Line 5674  for (;;)
5674                  break;                  break;
5675                  }                  }
5676                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5677                  if (md->partial != 0 &&    /* Take care with CRLF partial */
5678                      eptr + 1 >= md->end_subject &&
5679                      NLBLOCK->nltype == NLTYPE_FIXED &&
5680                      NLBLOCK->nllen == 2 &&
5681                      *eptr == NLBLOCK->nl[0])
5682                    {
5683                    md->hitend = TRUE;
5684                    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5685                    }
5686                eptr++;                eptr++;
5687                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5688                }                }
# Line 5815  for (;;) Line 5947  for (;;)
5947                break;                break;
5948                }                }
5949              if (IS_NEWLINE(eptr)) break;              if (IS_NEWLINE(eptr)) break;
5950                if (md->partial != 0 &&    /* Take care with CRLF partial */
5951                    eptr + 1 >= md->end_subject &&
5952                    NLBLOCK->nltype == NLTYPE_FIXED &&
5953                    NLBLOCK->nllen == 2 &&
5954                    *eptr == NLBLOCK->nl[0])
5955                  {
5956                  md->hitend = TRUE;
5957                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5958                  }
5959              eptr++;              eptr++;
5960              }              }
5961            break;            break;
# Line 6145  Undefine all the macros that were define Line 6286  Undefine all the macros that were define
6286  ***************************************************************************/  ***************************************************************************/
6287    
6288    
6289    #ifdef NO_RECURSE
6290    /*************************************************
6291    *          Release allocated heap frames         *
6292    *************************************************/
6293    
6294    /* This function releases all the allocated frames. The base frame is on the
6295    machine stack, and so must not be freed.
6296    
6297    Argument: the address of the base frame
6298    Returns:  nothing
6299    */
6300    
6301    static void
6302    release_match_heapframes (heapframe *frame_base)
6303    {
6304    heapframe *nextframe = frame_base->Xnextframe;
6305    while (nextframe != NULL)
6306      {
6307      heapframe *oldframe = nextframe;
6308      nextframe = nextframe->Xnextframe;
6309      (PUBL(stack_free))(oldframe);
6310      }
6311    }
6312    #endif
6313    
6314    
6315  /*************************************************  /*************************************************
6316  *         Execute a Regular Expression           *  *         Execute a Regular Expression           *
# Line 6207  PCRE_PUCHAR req_char_ptr = start_match - Line 6373  PCRE_PUCHAR req_char_ptr = start_match -
6373  const pcre_study_data *study;  const pcre_study_data *study;
6374  const REAL_PCRE *re = (const REAL_PCRE *)argument_re;  const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
6375    
6376  /* Check for the special magic call that measures the size of the stack used  #ifdef NO_RECURSE
6377  per recursive call of match(). */  heapframe frame_zero;
6378    frame_zero.Xprevframe = NULL;            /* Marks the top level */
6379    frame_zero.Xnextframe = NULL;            /* None are allocated yet */
6380    md->match_frames_base = &frame_zero;
6381    #endif
6382    
6383  if (re == NULL && extra_data == NULL && subject == NULL && length == -1)  /* Check for the special magic call that measures the size of the stack used
6384    per recursive call of match(). Without the funny casting for sizeof, a Windows
6385    compiler gave this error: "unary minus operator applied to unsigned type,
6386    result still unsigned". Hopefully the cast fixes that. */
6387    
6388    if (re == NULL && extra_data == NULL && subject == NULL && length == -999 &&
6389        start_offset == -999)
6390  #ifdef NO_RECURSE  #ifdef NO_RECURSE
6391    return -sizeof(heapframe);    return -((int)sizeof(heapframe));
6392  #else  #else
6393    return match(NULL, NULL, NULL, 0, NULL, NULL, 0);    return match(NULL, NULL, NULL, 0, NULL, NULL, 0);
6394  #endif  #endif
6395    
6396  /* Plausibility checks */  /* Plausibility checks */
6397    
6398  if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;  if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
6399  if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0))  if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0))
6400    return PCRE_ERROR_NULL;    return PCRE_ERROR_NULL;
6401  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
6402  if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;  if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
# Line 6279  if (utf && (options & PCRE_NO_UTF8_CHECK Line 6455  if (utf && (options & PCRE_NO_UTF8_CHECK
6455  /* If the pattern was successfully studied with JIT support, run the JIT  /* If the pattern was successfully studied with JIT support, run the JIT
6456  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
6457  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
6458  an unsupported flag is set. In particular, JIT does not support partial  an unsupported flag is set. */
 matching. */  
6459    
6460  #ifdef SUPPORT_JIT  #ifdef SUPPORT_JIT
6461  if (extra_data != NULL  if (extra_data != NULL
6462      && (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0      && (extra_data->flags & (PCRE_EXTRA_EXECUTABLE_JIT |
6463                                 PCRE_EXTRA_TABLES)) == PCRE_EXTRA_EXECUTABLE_JIT
6464      && extra_data->executable_jit != NULL      && extra_data->executable_jit != NULL
     && (extra_data->flags & PCRE_EXTRA_TABLES) == 0  
6465      && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |      && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |
6466                      PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART)) == 0)                      PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART |
6467    return PRIV(jit_exec)(re, extra_data->executable_jit,                      PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD)) == 0)
6468      {
6469      rc = PRIV(jit_exec)(re, extra_data->executable_jit,
6470      (const pcre_uchar *)subject, length, start_offset, options,      (const pcre_uchar *)subject, length, start_offset, options,
6471      ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0)      ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0)
6472      ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount);      ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount,
6473        ((extra_data->flags & PCRE_EXTRA_MARK) != 0) ? extra_data->mark : NULL);
6474    
6475      /* PCRE_ERROR_NULL means that the selected normal or partial matching
6476      mode is not compiled. In this case we simply fallback to interpreter. */
6477    
6478      if (rc != PCRE_ERROR_NULL) return rc;
6479      }
6480  #endif  #endif
6481    
6482  /* 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 6495  if (!anchored) Line 6679  if (!anchored)
6679    if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->flags & PCRE_FIRSTSET) != 0)
6680      {      {
6681      has_first_char = TRUE;      has_first_char = TRUE;
6682      first_char = first_char2 = re->first_char;      first_char = first_char2 = (pcre_uchar)(re->first_char);
6683      if ((re->flags & PCRE_FCH_CASELESS) != 0)      if ((re->flags & PCRE_FCH_CASELESS) != 0)
6684        {        {
6685        first_char2 = TABLE_GET(first_char, md->fcc, first_char);        first_char2 = TABLE_GET(first_char, md->fcc, first_char);
# Line 6517  character" set. */ Line 6701  character" set. */
6701  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
6702    {    {
6703    has_req_char = TRUE;    has_req_char = TRUE;
6704    req_char = req_char2 = re->req_char;    req_char = req_char2 = (pcre_uchar)(re->req_char);
6705    if ((re->flags & PCRE_RCH_CASELESS) != 0)    if ((re->flags & PCRE_RCH_CASELESS) != 0)
6706      {      {
6707      req_char2 = TABLE_GET(req_char, md->fcc, req_char);      req_char2 = TABLE_GET(req_char, md->fcc, req_char);
# Line 6907  if (rc == MATCH_MATCH || rc == MATCH_ACC Line 7091  if (rc == MATCH_MATCH || rc == MATCH_ACC
7091    if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)    if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
7092      *(extra_data->mark) = (pcre_uchar *)md->mark;      *(extra_data->mark) = (pcre_uchar *)md->mark;
7093    DPRINTF((">>>> returning %d\n", rc));    DPRINTF((">>>> returning %d\n", rc));
7094    #ifdef NO_RECURSE
7095      release_match_heapframes(&frame_zero);
7096    #endif
7097    return rc;    return rc;
7098    }    }
7099    
# Line 6924  if (using_temporary_offsets) Line 7111  if (using_temporary_offsets)
7111  if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)  if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)
7112    {    {
7113    DPRINTF((">>>> error: returning %d\n", rc));    DPRINTF((">>>> error: returning %d\n", rc));
7114    #ifdef NO_RECURSE
7115      release_match_heapframes(&frame_zero);
7116    #endif
7117    return rc;    return rc;
7118    }    }
7119    
# Line 6953  else Line 7143  else
7143    
7144  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
7145    *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;    *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;
7146    #ifdef NO_RECURSE
7147      release_match_heapframes(&frame_zero);
7148    #endif
7149  return rc;  return rc;
7150  }  }
7151    

Legend:
Removed from v.895  
changed lines
  Added in v.937

  ViewVC Help
Powered by ViewVC 1.1.5