/[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 892 by ph10, Wed Jan 18 17:23:20 2012 UTC revision 933 by ph10, Sat Feb 25 12:18:23 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 615  int save_offset1, save_offset2, save_off Line 625  int save_offset1, save_offset2, save_off
625  int stacksave[REC_STACK_SAVE_MAX];  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
630    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
632    cannot normally ever be NULL. The return is the negated value of the frame
633    size. */
634    
635    if (ecode == NULL)
636      {
637      if (rdepth == 0)
638        return match((PCRE_PUCHAR)&rdepth, NULL, NULL, 0, NULL, NULL, 1);
639      else
640        {
641        int len = (char *)&rdepth - (char *)eptr;
642        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 821  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 840  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 920  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 1026  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 1053  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 1532  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 1554  for (;;) Line 1581  for (;;)
1581    
1582        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1583        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1584        md->mark = save_mark;        md->mark = save_mark;
1585        }        }
1586      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
1587    
# Line 1578  for (;;) Line 1605  for (;;)
1605    
1606      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1607      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
1608      save_mark = md->mark;      save_mark = md->mark;
1609      if (md->match_function_type == MATCH_CONDASSERT)      if (md->match_function_type == MATCH_CONDASSERT)
1610        {        {
1611        condassert = TRUE;        condassert = TRUE;
# Line 1589  for (;;) Line 1616  for (;;)
1616      do      do
1617        {        {
1618        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);
1619        md->mark = save_mark;        md->mark = save_mark;
1620        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);
1621        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
1622          {          {
# Line 2042  for (;;) Line 2069  for (;;)
2069    
2070      case OP_DOLLM:      case OP_DOLLM:
2071      if (eptr < md->end_subject)      if (eptr < md->end_subject)
2072        { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }        {
2073          if (!IS_NEWLINE(eptr))
2074            {
2075            if (md->partial != 0 &&
2076                eptr + 1 >= md->end_subject &&
2077                NLBLOCK->nltype == NLTYPE_FIXED &&
2078                NLBLOCK->nllen == 2 &&
2079                *eptr == NLBLOCK->nl[0])
2080              {
2081              md->hitend = TRUE;
2082              if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2083              }
2084            RRETURN(MATCH_NOMATCH);
2085            }
2086          }
2087      else      else
2088        {        {
2089        if (md->noteol) RRETURN(MATCH_NOMATCH);        if (md->noteol) RRETURN(MATCH_NOMATCH);
# Line 2074  for (;;) Line 2115  for (;;)
2115      ASSERT_NL_OR_EOS:      ASSERT_NL_OR_EOS:
2116      if (eptr < md->end_subject &&      if (eptr < md->end_subject &&
2117          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
2118          {
2119          if (md->partial != 0 &&
2120              eptr + 1 >= md->end_subject &&
2121              NLBLOCK->nltype == NLTYPE_FIXED &&
2122              NLBLOCK->nllen == 2 &&
2123              *eptr == NLBLOCK->nl[0])
2124            {
2125            md->hitend = TRUE;
2126            if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2127            }
2128        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2129          }
2130    
2131      /* Either at end of string or \n before end. */      /* Either at end of string or \n before end. */
2132    
# Line 2202  for (;;) Line 2254  for (;;)
2254        }        }
2255      break;      break;
2256    
2257      /* Match a single character type; inline for speed */      /* Match any single character type except newline; have to take care with
2258        CRLF newlines and partial matching. */
2259    
2260      case OP_ANY:      case OP_ANY:
2261      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
2262        if (md->partial != 0 &&
2263            eptr + 1 >= md->end_subject &&
2264            NLBLOCK->nltype == NLTYPE_FIXED &&
2265            NLBLOCK->nllen == 2 &&
2266            *eptr == NLBLOCK->nl[0])
2267          {
2268          md->hitend = TRUE;
2269          if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2270          }
2271    
2272      /* Fall through */      /* Fall through */
2273    
2274        /* Match any single character whatsoever. */
2275    
2276      case OP_ALLANY:      case OP_ALLANY:
2277      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 */
2278        {                            /* not be updated before SCHECK_PARTIAL. */        {                            /* not be updated before SCHECK_PARTIAL. */
# Line 2348  for (;;) Line 2413  for (;;)
2413        default: RRETURN(MATCH_NOMATCH);        default: RRETURN(MATCH_NOMATCH);
2414    
2415        case 0x000d:        case 0x000d:
2416        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;        if (eptr >= md->end_subject)
2417            {
2418            SCHECK_PARTIAL();
2419            }
2420          else if (*eptr == 0x0a) eptr++;
2421        break;        break;
2422    
2423        case 0x000a:        case 0x000a:
# Line 2578  for (;;) Line 2647  for (;;)
2647        if (UCD_CATEGORY(c) != ucp_M) break;        if (UCD_CATEGORY(c) != ucp_M) break;
2648        eptr += len;        eptr += len;
2649        }        }
2650        CHECK_PARTIAL();
2651      ecode++;      ecode++;
2652      break;      break;
2653  #endif  #endif
# Line 2643  for (;;) Line 2713  for (;;)
2713        default:               /* No repeat follows */        default:               /* No repeat follows */
2714        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)
2715          {          {
2716            if (length == -2) eptr = md->end_subject;   /* Partial match */
2717          CHECK_PARTIAL();          CHECK_PARTIAL();
2718          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2719          }          }
# Line 2668  for (;;) Line 2739  for (;;)
2739        int slength;        int slength;
2740        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2741          {          {
2742            if (slength == -2) eptr = md->end_subject;   /* Partial match */
2743          CHECK_PARTIAL();          CHECK_PARTIAL();
2744          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2745          }          }
# Line 2691  for (;;) Line 2763  for (;;)
2763          if (fi >= max) RRETURN(MATCH_NOMATCH);          if (fi >= max) RRETURN(MATCH_NOMATCH);
2764          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2765            {            {
2766              if (slength == -2) eptr = md->end_subject;   /* Partial match */
2767            CHECK_PARTIAL();            CHECK_PARTIAL();
2768            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2769            }            }
# Line 2709  for (;;) Line 2782  for (;;)
2782          int slength;          int slength;
2783          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2784            {            {
2785            CHECK_PARTIAL();            /* Can't use CHECK_PARTIAL because we don't want to update eptr in
2786              the soft partial matching case. */
2787    
2788              if (slength == -2 && md->partial != 0 &&
2789                  md->end_subject > md->start_used_ptr)
2790                {
2791                md->hitend = TRUE;
2792                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2793                }
2794            break;            break;
2795            }            }
2796          eptr += slength;          eptr += slength;
2797          }          }
2798    
2799        while (eptr >= pp)        while (eptr >= pp)
2800          {          {
2801          RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);          RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);
# Line 3487  for (;;) Line 3569  for (;;)
3569        SCHECK_PARTIAL();        SCHECK_PARTIAL();
3570        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
3571        }        }
     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  
3572  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3573        if (utf)
3574          {
3575          register unsigned int ch, och;
3576    
3577          ecode++;
3578          GETCHARINC(ch, ecode);
3579          GETCHARINC(c, eptr);
3580    
3581          if (op == OP_NOT)
3582            {
3583            if (ch == c) RRETURN(MATCH_NOMATCH);
3584            }
3585          else
3586            {
3587  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3588        if (utf && ch > 127)          if (ch > 127)
3589          och = UCD_OTHERCASE(ch);            och = UCD_OTHERCASE(ch);
3590  #else  #else
3591        if (utf && ch > 127)          if (ch > 127)
3592          och = ch;            och = ch;
3593  #endif /* SUPPORT_UCP */  #endif /* SUPPORT_UCP */
3594        else          else
3595  #endif /* SUPPORT_UTF */            och = TABLE_GET(ch, md->fcc, ch);
3596          och = TABLE_GET(ch, md->fcc, ch);          if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
3597  #endif /* COMPILE_PCRE8 */          }
       if (ch == c || och == c) RRETURN(MATCH_NOMATCH);  
3598        }        }
3599      else    /* Caseful */      else
3600    #endif
3601        {        {
3602        if (*ecode++ == c) RRETURN(MATCH_NOMATCH);        register unsigned int ch = ecode[1];
3603          c = *eptr++;
3604          if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c))
3605            RRETURN(MATCH_NOMATCH);
3606          ecode += 2;
3607        }        }
3608      break;      break;
3609    
# Line 3593  for (;;) Line 3683  for (;;)
3683      /* Common code for all repeated single-byte matches. */      /* Common code for all repeated single-byte matches. */
3684    
3685      REPEATNOTCHAR:      REPEATNOTCHAR:
3686      fc = *ecode++;      GETCHARINCTEST(fc, ecode);
3687    
3688      /* The code is duplicated for the caseless and caseful cases, for speed,      /* The code is duplicated for the caseless and caseful cases, for speed,
3689      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 3608  for (;;) Line 3698  for (;;)
3698    
3699      if (op >= OP_NOTSTARI)     /* Caseless */      if (op >= OP_NOTSTARI)     /* Caseless */
3700        {        {
 #ifdef COMPILE_PCRE8  
       /* fc must be < 128 if UTF is enabled. */  
       foc = md->fcc[fc];  
 #else  
3701  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3702  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3703        if (utf && fc > 127)        if (utf && fc > 127)
# Line 3623  for (;;) Line 3709  for (;;)
3709        else        else
3710  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
3711          foc = TABLE_GET(fc, md->fcc, fc);          foc = TABLE_GET(fc, md->fcc, fc);
 #endif /* COMPILE_PCRE8 */  
3712    
3713  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3714        if (utf)        if (utf)
# Line 3637  for (;;) Line 3722  for (;;)
3722              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3723              }              }
3724            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3725            if (fc == d || foc == d) RRETURN(MATCH_NOMATCH);            if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
3726            }            }
3727          }          }
3728        else        else
# Line 3675  for (;;) Line 3760  for (;;)
3760                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3761                }                }
3762              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3763              if (fc == d || foc == d) RRETURN(MATCH_NOMATCH);              if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
3764              }              }
3765            }            }
3766          else          else
# Line 3718  for (;;) Line 3803  for (;;)
3803                break;                break;
3804                }                }
3805              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3806              if (fc == d || foc == d) break;              if (fc == d || (unsigned int)foc == d) break;
3807              eptr += len;              eptr += len;
3808              }              }
3809            if (possessive) continue;            if (possessive) continue;
# Line 4147  for (;;) Line 4232  for (;;)
4232              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
4233              eptr += len;              eptr += len;
4234              }              }
4235              CHECK_PARTIAL();
4236            }            }
4237          }          }
4238    
# Line 4167  for (;;) Line 4253  for (;;)
4253              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4254              }              }
4255            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4256              if (md->partial != 0 &&
4257                  eptr + 1 >= md->end_subject &&
4258                  NLBLOCK->nltype == NLTYPE_FIXED &&
4259                  NLBLOCK->nllen == 2 &&
4260                  *eptr == NLBLOCK->nl[0])
4261                {
4262                md->hitend = TRUE;
4263                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
4264                }
4265            eptr++;            eptr++;
4266            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4267            }            }
# Line 4451  for (;;) Line 4546  for (;;)
4546              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4547              }              }
4548            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4549              if (md->partial != 0 &&
4550                  eptr + 1 >= md->end_subject &&
4551                  NLBLOCK->nltype == NLTYPE_FIXED &&
4552                  NLBLOCK->nllen == 2 &&
4553                  *eptr == NLBLOCK->nl[0])
4554                {
4555                md->hitend = TRUE;
4556                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
4557                }
4558            eptr++;            eptr++;
4559            }            }
4560          break;          break;
# Line 4931  for (;;) Line 5035  for (;;)
5035              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
5036              eptr += len;              eptr += len;
5037              }              }
5038              CHECK_PARTIAL();
5039            }            }
5040          }          }
5041        else        else
# Line 4954  for (;;) Line 5059  for (;;)
5059            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
5060            switch(ctype)            switch(ctype)
5061              {              {
5062              case OP_ANY:        /* This is the non-NL case */              case OP_ANY:               /* This is the non-NL case */
5063                if (md->partial != 0 &&    /* Take care with CRLF partial */
5064                    eptr >= md->end_subject &&
5065                    NLBLOCK->nltype == NLTYPE_FIXED &&
5066                    NLBLOCK->nllen == 2 &&
5067                    c == NLBLOCK->nl[0])
5068                  {
5069                  md->hitend = TRUE;
5070                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5071                  }
5072                break;
5073    
5074              case OP_ALLANY:              case OP_ALLANY:
5075              case OP_ANYBYTE:              case OP_ANYBYTE:
5076              break;              break;
# Line 5117  for (;;) Line 5233  for (;;)
5233            c = *eptr++;            c = *eptr++;
5234            switch(ctype)            switch(ctype)
5235              {              {
5236              case OP_ANY:     /* This is the non-NL case */              case OP_ANY:               /* This is the non-NL case */
5237                if (md->partial != 0 &&    /* Take care with CRLF partial */
5238                    eptr >= md->end_subject &&
5239                    NLBLOCK->nltype == NLTYPE_FIXED &&
5240                    NLBLOCK->nllen == 2 &&
5241                    c == NLBLOCK->nl[0])
5242                  {
5243                  md->hitend = TRUE;
5244                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5245                  }
5246                break;
5247    
5248              case OP_ALLANY:              case OP_ALLANY:
5249              case OP_ANYBYTE:              case OP_ANYBYTE:
5250              break;              break;
# Line 5474  for (;;) Line 5601  for (;;)
5601              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
5602              eptr += len;              eptr += len;
5603              }              }
5604              CHECK_PARTIAL();
5605            }            }
5606    
5607          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
# Line 5517  for (;;) Line 5645  for (;;)
5645                  break;                  break;
5646                  }                  }
5647                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5648                  if (md->partial != 0 &&    /* Take care with CRLF partial */
5649                      eptr + 1 >= md->end_subject &&
5650                      NLBLOCK->nltype == NLTYPE_FIXED &&
5651                      NLBLOCK->nllen == 2 &&
5652                      *eptr == NLBLOCK->nl[0])
5653                    {
5654                    md->hitend = TRUE;
5655                    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5656                    }
5657                eptr++;                eptr++;
5658                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5659                }                }
# Line 5534  for (;;) Line 5671  for (;;)
5671                  break;                  break;
5672                  }                  }
5673                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5674                  if (md->partial != 0 &&    /* Take care with CRLF partial */
5675                      eptr + 1 >= md->end_subject &&
5676                      NLBLOCK->nltype == NLTYPE_FIXED &&
5677                      NLBLOCK->nllen == 2 &&
5678                      *eptr == NLBLOCK->nl[0])
5679                    {
5680                    md->hitend = TRUE;
5681                    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5682                    }
5683                eptr++;                eptr++;
5684                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5685                }                }
# Line 5798  for (;;) Line 5944  for (;;)
5944                break;                break;
5945                }                }
5946              if (IS_NEWLINE(eptr)) break;              if (IS_NEWLINE(eptr)) break;
5947                if (md->partial != 0 &&    /* Take care with CRLF partial */
5948                    eptr + 1 >= md->end_subject &&
5949                    NLBLOCK->nltype == NLTYPE_FIXED &&
5950                    NLBLOCK->nllen == 2 &&
5951                    *eptr == NLBLOCK->nl[0])
5952                  {
5953                  md->hitend = TRUE;
5954                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5955                  }
5956              eptr++;              eptr++;
5957              }              }
5958            break;            break;
# Line 6128  Undefine all the macros that were define Line 6283  Undefine all the macros that were define
6283  ***************************************************************************/  ***************************************************************************/
6284    
6285    
6286    #ifdef NO_RECURSE
6287    /*************************************************
6288    *          Release allocated heap frames         *
6289    *************************************************/
6290    
6291    /* This function releases all the allocated frames. The base frame is on the
6292    machine stack, and so must not be freed.
6293    
6294    Argument: the address of the base frame
6295    Returns:  nothing
6296    */
6297    
6298    static void
6299    release_match_heapframes (heapframe *frame_base)
6300    {
6301    heapframe *nextframe = frame_base->Xnextframe;
6302    while (nextframe != NULL)
6303      {
6304      heapframe *oldframe = nextframe;
6305      nextframe = nextframe->Xnextframe;
6306      (PUBL(stack_free))(oldframe);
6307      }
6308    }
6309    #endif
6310    
6311    
6312  /*************************************************  /*************************************************
6313  *         Execute a Regular Expression           *  *         Execute a Regular Expression           *
# Line 6190  PCRE_PUCHAR req_char_ptr = start_match - Line 6370  PCRE_PUCHAR req_char_ptr = start_match -
6370  const pcre_study_data *study;  const pcre_study_data *study;
6371  const REAL_PCRE *re = (const REAL_PCRE *)argument_re;  const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
6372    
6373    #ifdef NO_RECURSE
6374    heapframe frame_zero;
6375    frame_zero.Xprevframe = NULL;            /* Marks the top level */
6376    frame_zero.Xnextframe = NULL;            /* None are allocated yet */
6377    md->match_frames_base = &frame_zero;
6378    #endif
6379    
6380    /* Check for the special magic call that measures the size of the stack used
6381    per recursive call of match(). Without the funny casting for sizeof, a Windows
6382    compiler gave this error: "unary minus operator applied to unsigned type,
6383    result still unsigned". Hopefully the cast fixes that. */
6384    
6385    if (re == NULL && extra_data == NULL && subject == NULL && length == -999 &&
6386        start_offset == -999)
6387    #ifdef NO_RECURSE
6388      return -((int)sizeof(heapframe));
6389    #else
6390      return match(NULL, NULL, NULL, 0, NULL, NULL, 0);
6391    #endif
6392    
6393  /* Plausibility checks */  /* Plausibility checks */
6394    
6395  if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;  if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
6396  if (re == NULL || subject == NULL ||  if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0))
6397     (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;    return PCRE_ERROR_NULL;
6398  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
6399  if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;  if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
6400    
6401    /* Check that the first field in the block is the magic number. If it is not,
6402    return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
6403    REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
6404    means that the pattern is likely compiled with different endianness. */
6405    
6406    if (re->magic_number != MAGIC_NUMBER)
6407      return re->magic_number == REVERSED_MAGIC_NUMBER?
6408        PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
6409    if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
6410    
6411  /* These two settings are used in the code for checking a UTF-8 string that  /* These two settings are used in the code for checking a UTF-8 string that
6412  follows immediately afterwards. Other values in the md block are used only  follows immediately afterwards. Other values in the md block are used only
6413  during "normal" pcre_exec() processing, not when the JIT support is in use,  during "normal" pcre_exec() processing, not when the JIT support is in use,
# Line 6242  if (utf && (options & PCRE_NO_UTF8_CHECK Line 6452  if (utf && (options & PCRE_NO_UTF8_CHECK
6452  /* If the pattern was successfully studied with JIT support, run the JIT  /* If the pattern was successfully studied with JIT support, run the JIT
6453  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
6454  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
6455  an unsupported flag is set. In particular, JIT does not support partial  an unsupported flag is set. */
 matching. */  
6456    
6457  #ifdef SUPPORT_JIT  #ifdef SUPPORT_JIT
6458  if (extra_data != NULL  if (extra_data != NULL
6459      && (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0      && (extra_data->flags & (PCRE_EXTRA_EXECUTABLE_JIT |
6460                                 PCRE_EXTRA_TABLES)) == PCRE_EXTRA_EXECUTABLE_JIT
6461      && extra_data->executable_jit != NULL      && extra_data->executable_jit != NULL
     && (extra_data->flags & PCRE_EXTRA_TABLES) == 0  
6462      && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |      && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |
6463                      PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART)) == 0)                      PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART |
6464    return PRIV(jit_exec)(re, extra_data->executable_jit,                      PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD)) == 0)
6465      {
6466      rc = PRIV(jit_exec)(re, extra_data->executable_jit,
6467      (const pcre_uchar *)subject, length, start_offset, options,      (const pcre_uchar *)subject, length, start_offset, options,
6468      ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0)      ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0)
6469      ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount);      ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount,
6470        ((extra_data->flags & PCRE_EXTRA_MARK) != 0) ? extra_data->mark : NULL);
6471    
6472      /* PCRE_ERROR_NULL means that the selected normal or partial matching
6473      mode is not compiled. In this case we simply fallback to interpreter. */
6474    
6475      if (rc != PCRE_ERROR_NULL) return rc;
6476      }
6477  #endif  #endif
6478    
6479  /* 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 6297  in other programs later. */ Line 6515  in other programs later. */
6515    
6516  if (tables == NULL) tables = PRIV(default_tables);  if (tables == NULL) tables = PRIV(default_tables);
6517    
 /* Check that the first field in the block is the magic number. If it is not,  
 return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to  
 REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which  
 means that the pattern is likely compiled with different endianness. */  
   
 if (re->magic_number != MAGIC_NUMBER)  
   return re->magic_number == REVERSED_MAGIC_NUMBER?  
     PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;  
 if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;  
   
6518  /* Set up other data */  /* Set up other data */
6519    
6520  anchored = ((re->options | options) & PCRE_ANCHORED) != 0;  anchored = ((re->options | options) & PCRE_ANCHORED) != 0;
# Line 6468  if (!anchored) Line 6676  if (!anchored)
6676    if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->flags & PCRE_FIRSTSET) != 0)
6677      {      {
6678      has_first_char = TRUE;      has_first_char = TRUE;
6679      first_char = first_char2 = re->first_char;      first_char = first_char2 = (pcre_uchar)(re->first_char);
6680      if ((re->flags & PCRE_FCH_CASELESS) != 0)      if ((re->flags & PCRE_FCH_CASELESS) != 0)
6681        {        {
6682        first_char2 = TABLE_GET(first_char, md->fcc, first_char);        first_char2 = TABLE_GET(first_char, md->fcc, first_char);
# Line 6490  character" set. */ Line 6698  character" set. */
6698  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
6699    {    {
6700    has_req_char = TRUE;    has_req_char = TRUE;
6701    req_char = req_char2 = re->req_char;    req_char = req_char2 = (pcre_uchar)(re->req_char);
6702    if ((re->flags & PCRE_RCH_CASELESS) != 0)    if ((re->flags & PCRE_RCH_CASELESS) != 0)
6703      {      {
6704      req_char2 = TABLE_GET(req_char, md->fcc, req_char);      req_char2 = TABLE_GET(req_char, md->fcc, req_char);
# Line 6880  if (rc == MATCH_MATCH || rc == MATCH_ACC Line 7088  if (rc == MATCH_MATCH || rc == MATCH_ACC
7088    if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)    if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
7089      *(extra_data->mark) = (pcre_uchar *)md->mark;      *(extra_data->mark) = (pcre_uchar *)md->mark;
7090    DPRINTF((">>>> returning %d\n", rc));    DPRINTF((">>>> returning %d\n", rc));
7091    #ifdef NO_RECURSE
7092      release_match_heapframes(&frame_zero);
7093    #endif
7094    return rc;    return rc;
7095    }    }
7096    
# Line 6897  if (using_temporary_offsets) Line 7108  if (using_temporary_offsets)
7108  if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)  if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)
7109    {    {
7110    DPRINTF((">>>> error: returning %d\n", rc));    DPRINTF((">>>> error: returning %d\n", rc));
7111    #ifdef NO_RECURSE
7112      release_match_heapframes(&frame_zero);
7113    #endif
7114    return rc;    return rc;
7115    }    }
7116    
# Line 6926  else Line 7140  else
7140    
7141  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
7142    *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;    *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;
7143    #ifdef NO_RECURSE
7144      release_match_heapframes(&frame_zero);
7145    #endif
7146  return rc;  return rc;
7147  }  }
7148    

Legend:
Removed from v.892  
changed lines
  Added in v.933

  ViewVC Help
Powered by ViewVC 1.1.5