/[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 510 by ph10, Sat Mar 27 17:45:29 2010 UTC revision 598 by ph10, Sat May 7 15:37:31 2011 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2010 University of Cambridge             Copyright (c) 1997-2011 University of Cambridge
10    
11  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
12  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 71  defined PCRE_ERROR_xxx codes, which are Line 71  defined PCRE_ERROR_xxx codes, which are
71  /* Special internal returns from the match() function. Make them sufficiently  /* Special internal returns from the match() function. Make them sufficiently
72  negative to avoid the external error codes. */  negative to avoid the external error codes. */
73    
74  #define MATCH_COMMIT       (-999)  #define MATCH_ACCEPT       (-999)
75  #define MATCH_PRUNE        (-998)  #define MATCH_COMMIT       (-998)
76  #define MATCH_SKIP         (-997)  #define MATCH_PRUNE        (-997)
77  #define MATCH_SKIP_ARG     (-996)  #define MATCH_SKIP         (-996)
78  #define MATCH_THEN         (-995)  #define MATCH_SKIP_ARG     (-995)
79    #define MATCH_THEN         (-994)
80    
81  /* This is a convenience macro for code that occurs many times. */  /* This is a convenience macro for code that occurs many times. */
82    
# Line 131  while (length-- > 0) Line 132  while (length-- > 0)
132  *          Match a back-reference                *  *          Match a back-reference                *
133  *************************************************/  *************************************************/
134    
135  /* If a back reference hasn't been set, the length that is passed is greater  /* Normally, if a back reference hasn't been set, the length that is passed is
136  than the number of characters left in the string, so the match fails.  negative, so the match always fails. However, in JavaScript compatibility mode,
137    the length passed is zero. Note that in caseless UTF-8 mode, the number of
138    subject bytes matched may be different to the number of reference bytes.
139    
140  Arguments:  Arguments:
141    offset      index into the offset vector    offset      index into the offset vector
142    eptr        points into the subject    eptr        pointer into the subject
143    length      length to be matched    length      length of reference to be matched (number of bytes)
144    md          points to match data block    md          points to match data block
145    ims         the ims flags    ims         the ims flags
146    
147  Returns:      TRUE if matched  Returns:      < 0 if not matched, otherwise the number of subject bytes matched
148  */  */
149    
150  static BOOL  static int
151  match_ref(int offset, register USPTR eptr, int length, match_data *md,  match_ref(int offset, register USPTR eptr, int length, match_data *md,
152    unsigned long int ims)    unsigned long int ims)
153  {  {
154  USPTR p = md->start_subject + md->offset_vector[offset];  USPTR eptr_start = eptr;
155    register USPTR p = md->start_subject + md->offset_vector[offset];
156    
157  #ifdef PCRE_DEBUG  #ifdef PCRE_DEBUG
158  if (eptr >= md->end_subject)  if (eptr >= md->end_subject)
# Line 163  pchars(p, length, FALSE, md); Line 167  pchars(p, length, FALSE, md);
167  printf("\n");  printf("\n");
168  #endif  #endif
169    
170  /* Always fail if not enough characters left */  /* Always fail if reference not set (and not JavaScript compatible). */
171    
172  if (length > md->end_subject - eptr) return FALSE;  if (length < 0) return -1;
173    
174  /* Separate the caseless case for speed. In UTF-8 mode we can only do this  /* Separate the caseless case for speed. In UTF-8 mode we can only do this
175  properly if Unicode properties are supported. Otherwise, we can check only  properly if Unicode properties are supported. Otherwise, we can check only
# Line 177  if ((ims & PCRE_CASELESS) != 0) Line 181  if ((ims & PCRE_CASELESS) != 0)
181  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
182    if (md->utf8)    if (md->utf8)
183      {      {
184      USPTR endptr = eptr + length;      /* Match characters up to the end of the reference. NOTE: the number of
185      while (eptr < endptr)      bytes matched may differ, because there are some characters whose upper and
186        lower case versions code as different numbers of bytes. For example, U+023A
187        (2 bytes in UTF-8) is the upper case version of U+2C65 (3 bytes in UTF-8);
188        a sequence of 3 of the former uses 6 bytes, as does a sequence of two of
189        the latter. It is important, therefore, to check the length along the
190        reference, not along the subject (earlier code did this wrong). */
191    
192        USPTR endptr = p + length;
193        while (p < endptr)
194        {        {
195        int c, d;        int c, d;
196          if (eptr >= md->end_subject) return -1;
197        GETCHARINC(c, eptr);        GETCHARINC(c, eptr);
198        GETCHARINC(d, p);        GETCHARINC(d, p);
199        if (c != d && c != UCD_OTHERCASE(d)) return FALSE;        if (c != d && c != UCD_OTHERCASE(d)) return -1;
200        }        }
201      }      }
202    else    else
# Line 192  if ((ims & PCRE_CASELESS) != 0) Line 205  if ((ims & PCRE_CASELESS) != 0)
205    
206    /* 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
207    is no UCP support. */    is no UCP support. */
208        {
209    while (length-- > 0)      if (eptr + length > md->end_subject) return -1;
210      { if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE; }      while (length-- > 0)
211          { if (md->lcc[*p++] != md->lcc[*eptr++]) return -1; }
212        }
213    }    }
214    
215  /* In the caseful case, we can just compare the bytes, whether or not we  /* In the caseful case, we can just compare the bytes, whether or not we
216  are in UTF-8 mode. */  are in UTF-8 mode. */
217    
218  else  else
219    { while (length-- > 0) if (*p++ != *eptr++) return FALSE; }    {
220      if (eptr + length > md->end_subject) return -1;
221      while (length-- > 0) if (*p++ != *eptr++) return -1;
222      }
223    
224  return TRUE;  return eptr - eptr_start;
225  }  }
226    
227    
# Line 254  enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM Line 272  enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM
272         RM21,  RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,         RM21,  RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
273         RM31,  RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,         RM31,  RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
274         RM41,  RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,         RM41,  RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,
275         RM51,  RM52, RM53, RM54 };         RM51,  RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60,
276           RM61,  RM62 };
277    
278  /* These versions of the macros use the stack, as normal. There are debugging  /* These versions of the macros use the stack, as normal. There are debugging
279  versions and production versions. Note that the "rw" argument of RMATCH isn't  versions and production versions. Note that the "rw" argument of RMATCH isn't
# Line 292  argument of match(), which never changes Line 311  argument of match(), which never changes
311    
312  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\
313    {\    {\
314    heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\    heapframe *newframe = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));\
315      if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
316    frame->Xwhere = rw; \    frame->Xwhere = rw; \
317    newframe->Xeptr = ra;\    newframe->Xeptr = ra;\
318    newframe->Xecode = rb;\    newframe->Xecode = rb;\
# Line 313  argument of match(), which never changes Line 333  argument of match(), which never changes
333    
334  #define RRETURN(ra)\  #define RRETURN(ra)\
335    {\    {\
336    heapframe *newframe = frame;\    heapframe *oldframe = frame;\
337    frame = newframe->Xprevframe;\    frame = oldframe->Xprevframe;\
338    (pcre_stack_free)(newframe);\    (pcre_stack_free)(oldframe);\
339    if (frame != NULL)\    if (frame != NULL)\
340      {\      {\
341      rrc = ra;\      rrc = ra;\
# Line 419  immediately. The second one is used when Line 439  immediately. The second one is used when
439  the subject. */  the subject. */
440    
441  #define CHECK_PARTIAL()\  #define CHECK_PARTIAL()\
442    if (md->partial != 0 && eptr >= md->end_subject && eptr > mstart)\    if (md->partial != 0 && eptr >= md->end_subject && \
443      {\        eptr > md->start_used_ptr) \
444      md->hitend = TRUE;\      { \
445      if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL);\      md->hitend = TRUE; \
446        if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL); \
447      }      }
448    
449  #define SCHECK_PARTIAL()\  #define SCHECK_PARTIAL()\
450    if (md->partial != 0 && eptr > mstart)\    if (md->partial != 0 && eptr > md->start_used_ptr) \
451      {\      { \
452      md->hitend = TRUE;\      md->hitend = TRUE; \
453      if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL);\      if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL); \
454      }      }
455    
456    
# Line 485  heap storage. Set up the top-level frame Line 506  heap storage. Set up the top-level frame
506  heap whenever RMATCH() does a "recursion". See the macro definitions above. */  heap whenever RMATCH() does a "recursion". See the macro definitions above. */
507    
508  #ifdef NO_RECURSE  #ifdef NO_RECURSE
509  heapframe *frame = (pcre_stack_malloc)(sizeof(heapframe));  heapframe *frame = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));
510    if (frame == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
511  frame->Xprevframe = NULL;            /* Marks the top level */  frame->Xprevframe = NULL;            /* Marks the top level */
512    
513  /* Copy in the original argument variables */  /* Copy in the original argument variables */
# Line 684  for (;;) Line 706  for (;;)
706      case OP_MARK:      case OP_MARK:
707      markptr = ecode + 2;      markptr = ecode + 2;
708      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
709        ims, eptrb, flags, RM51);        ims, eptrb, flags, RM55);
710    
711      /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an      /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
712      argument, and we must check whether that argument matches this MARK's      argument, and we must check whether that argument matches this MARK's
713      argument. It is passed back in md->start_match_ptr (an overloading of that      argument. It is passed back in md->start_match_ptr (an overloading of that
714      variable). If it does match, we reset that variable to the current subject      variable). If it does match, we reset that variable to the current subject
715      position and return MATCH_SKIP. Otherwise, pass back the return code      position and return MATCH_SKIP. Otherwise, pass back the return code
716      unaltered. */      unaltered. */
717    
718      if (rrc == MATCH_SKIP_ARG &&      if (rrc == MATCH_SKIP_ARG &&
719          strcmp((char *)markptr, (char *)(md->start_match_ptr)) == 0)          strcmp((char *)markptr, (char *)(md->start_match_ptr)) == 0)
720        {        {
721        md->start_match_ptr = eptr;        md->start_match_ptr = eptr;
722        RRETURN(MATCH_SKIP);        RRETURN(MATCH_SKIP);
723        }        }
724    
725      if (md->mark == NULL) md->mark = markptr;      if (md->mark == NULL) md->mark = markptr;
726      RRETURN(rrc);      RRETURN(rrc);
727    
728      case OP_FAIL:      case OP_FAIL:
729      MRRETURN(MATCH_NOMATCH);      MRRETURN(MATCH_NOMATCH);
730    
731        /* COMMIT overrides PRUNE, SKIP, and THEN */
732    
733      case OP_COMMIT:      case OP_COMMIT:
734      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
735        ims, eptrb, flags, RM52);        ims, eptrb, flags, RM52);
736      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&
737            rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&
738            rrc != MATCH_THEN)
739          RRETURN(rrc);
740      MRRETURN(MATCH_COMMIT);      MRRETURN(MATCH_COMMIT);
741    
742        /* PRUNE overrides THEN */
743    
744      case OP_PRUNE:      case OP_PRUNE:
745      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
746        ims, eptrb, flags, RM51);        ims, eptrb, flags, RM51);
747      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
748      MRRETURN(MATCH_PRUNE);      MRRETURN(MATCH_PRUNE);
749    
750      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
751      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
752        ims, eptrb, flags, RM51);        ims, eptrb, flags, RM56);
753      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
754      md->mark = ecode + 2;      md->mark = ecode + 2;
755      RRETURN(MATCH_PRUNE);      RRETURN(MATCH_PRUNE);
756    
757        /* SKIP overrides PRUNE and THEN */
758    
759      case OP_SKIP:      case OP_SKIP:
760      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
761        ims, eptrb, flags, RM53);        ims, eptrb, flags, RM53);
762      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
763          RRETURN(rrc);
764      md->start_match_ptr = eptr;   /* Pass back current position */      md->start_match_ptr = eptr;   /* Pass back current position */
765      MRRETURN(MATCH_SKIP);      MRRETURN(MATCH_SKIP);
766    
767      case OP_SKIP_ARG:      case OP_SKIP_ARG:
768      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
769        ims, eptrb, flags, RM53);        ims, eptrb, flags, RM57);
770      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
771          RRETURN(rrc);
772      /* Pass back the current skip name by overloading md->start_match_ptr and  
773      returning the special MATCH_SKIP_ARG return code. This will either be      /* Pass back the current skip name by overloading md->start_match_ptr and
774      caught by a matching MARK, or get to the top, where it is treated the same      returning the special MATCH_SKIP_ARG return code. This will either be
775        caught by a matching MARK, or get to the top, where it is treated the same
776      as PRUNE. */      as PRUNE. */
777    
778      md->start_match_ptr = ecode + 2;      md->start_match_ptr = ecode + 2;
779      RRETURN(MATCH_SKIP_ARG);      RRETURN(MATCH_SKIP_ARG);
780    
781        /* For THEN (and THEN_ARG) we pass back the address of the bracket or
782        the alt that is at the start of the current branch. This makes it possible
783        to skip back past alternatives that precede the THEN within the current
784        branch. */
785    
786      case OP_THEN:      case OP_THEN:
787      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
788        ims, eptrb, flags, RM54);        ims, eptrb, flags, RM54);
789      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
790        md->start_match_ptr = ecode - GET(ecode, 1);
791      MRRETURN(MATCH_THEN);      MRRETURN(MATCH_THEN);
792    
793      case OP_THEN_ARG:      case OP_THEN_ARG:
794      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1+LINK_SIZE],
795        ims, eptrb, flags, RM54);        offset_top, md, ims, eptrb, flags, RM58);
796      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
797      md->mark = ecode + 2;      md->start_match_ptr = ecode - GET(ecode, 1);
798        md->mark = ecode + LINK_SIZE + 2;
799      RRETURN(MATCH_THEN);      RRETURN(MATCH_THEN);
800    
801      /* Handle a capturing bracket. If there is space in the offset vector, save      /* Handle a capturing bracket. If there is space in the offset vector, save
# Line 792  for (;;) Line 832  for (;;)
832        save_capture_last = md->capture_last;        save_capture_last = md->capture_last;
833    
834        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
835        md->offset_vector[md->offset_end - number] = eptr - md->start_subject;        md->offset_vector[md->offset_end - number] =
836            (int)(eptr - md->start_subject);
837    
838        flags = (op == OP_SCBRA)? match_cbegroup : 0;        flags = (op == OP_SCBRA)? match_cbegroup : 0;
839        do        do
840          {          {
841          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
842            ims, eptrb, flags, RM1);            ims, eptrb, flags, RM1);
843          if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);          if (rrc != MATCH_NOMATCH &&
844                (rrc != MATCH_THEN || md->start_match_ptr != ecode))
845              RRETURN(rrc);
846          md->capture_last = save_capture_last;          md->capture_last = save_capture_last;
847          ecode += GET(ecode, 1);          ecode += GET(ecode, 1);
848          }          }
# Line 851  for (;;) Line 894  for (;;)
894    
895          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
896            eptrb, flags, RM48);            eptrb, flags, RM48);
897          if (rrc == MATCH_NOMATCH) md->mark = markptr;          if (rrc == MATCH_NOMATCH) md->mark = markptr;
898          RRETURN(rrc);          RRETURN(rrc);
899          }          }
900    
901        /* For non-final alternatives, continue the loop for a NOMATCH result;        /* For non-final alternatives, continue the loop for a NOMATCH result;
# Line 860  for (;;) Line 903  for (;;)
903    
904        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
905          eptrb, flags, RM2);          eptrb, flags, RM2);
906        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH &&
907              (rrc != MATCH_THEN || md->start_match_ptr != ecode))
908            RRETURN(rrc);
909        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
910        }        }
911      /* Control never reaches here. */      /* Control never reaches here. */
# Line 887  for (;;) Line 932  for (;;)
932          cb.callout_number   = ecode[LINK_SIZE+2];          cb.callout_number   = ecode[LINK_SIZE+2];
933          cb.offset_vector    = md->offset_vector;          cb.offset_vector    = md->offset_vector;
934          cb.subject          = (PCRE_SPTR)md->start_subject;          cb.subject          = (PCRE_SPTR)md->start_subject;
935          cb.subject_length   = md->end_subject - md->start_subject;          cb.subject_length   = (int)(md->end_subject - md->start_subject);
936          cb.start_match      = mstart - md->start_subject;          cb.start_match      = (int)(mstart - md->start_subject);
937          cb.current_position = eptr - md->start_subject;          cb.current_position = (int)(eptr - md->start_subject);
938          cb.pattern_position = GET(ecode, LINK_SIZE + 3);          cb.pattern_position = GET(ecode, LINK_SIZE + 3);
939          cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);          cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);
940          cb.capture_top      = offset_top/2;          cb.capture_top      = offset_top/2;
# Line 1061  for (;;) Line 1106  for (;;)
1106          ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);          ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
1107          while (*ecode == OP_ALT) ecode += GET(ecode, 1);          while (*ecode == OP_ALT) ecode += GET(ecode, 1);
1108          }          }
1109        else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)        else if (rrc != MATCH_NOMATCH &&
1110                  (rrc != MATCH_THEN || md->start_match_ptr != ecode))
1111          {          {
1112          RRETURN(rrc);         /* Need braces because of following else */          RRETURN(rrc);         /* Need braces because of following else */
1113          }          }
# Line 1115  for (;;) Line 1161  for (;;)
1161        {        {
1162        md->offset_vector[offset] =        md->offset_vector[offset] =
1163          md->offset_vector[md->offset_end - number];          md->offset_vector[md->offset_end - number];
1164        md->offset_vector[offset+1] = eptr - md->start_subject;        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
1165        if (offset_top <= offset) offset_top = offset + 2;        if (offset_top <= offset) offset_top = offset + 2;
1166        }        }
1167      ecode += 3;      ecode += 3;
# Line 1157  for (;;) Line 1203  for (;;)
1203      md->end_match_ptr = eptr;           /* Record where we ended */      md->end_match_ptr = eptr;           /* Record where we ended */
1204      md->end_offset_top = offset_top;    /* and how many extracts were taken */      md->end_offset_top = offset_top;    /* and how many extracts were taken */
1205      md->start_match_ptr = mstart;       /* and the start (\K can modify) */      md->start_match_ptr = mstart;       /* and the start (\K can modify) */
1206      MRRETURN(MATCH_MATCH);  
1207        /* For some reason, the macros don't work properly if an expression is
1208        given as the argument to MRRETURN when the heap is in use. */
1209    
1210        rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;
1211        MRRETURN(rrc);
1212    
1213      /* Change option settings */      /* Change option settings */
1214    
# Line 1179  for (;;) Line 1230  for (;;)
1230        {        {
1231        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
1232          RM4);          RM4);
1233        if (rrc == MATCH_MATCH)        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
1234          {          {
1235          mstart = md->start_match_ptr;   /* In case \K reset it */          mstart = md->start_match_ptr;   /* In case \K reset it */
1236          break;          break;
1237          }          }
1238        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH &&
1239              (rrc != MATCH_THEN || md->start_match_ptr != ecode))
1240            RRETURN(rrc);
1241        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1242        }        }
1243      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
# Line 1212  for (;;) Line 1265  for (;;)
1265        {        {
1266        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
1267          RM5);          RM5);
1268        if (rrc == MATCH_MATCH) MRRETURN(MATCH_NOMATCH);        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) MRRETURN(MATCH_NOMATCH);
1269        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
1270          {          {
1271          do ecode += GET(ecode,1); while (*ecode == OP_ALT);          do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1272          break;          break;
1273          }          }
1274        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH &&
1275              (rrc != MATCH_THEN || md->start_match_ptr != ecode))
1276            RRETURN(rrc);
1277        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1278        }        }
1279      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
# Line 1273  for (;;) Line 1328  for (;;)
1328        cb.callout_number   = ecode[1];        cb.callout_number   = ecode[1];
1329        cb.offset_vector    = md->offset_vector;        cb.offset_vector    = md->offset_vector;
1330        cb.subject          = (PCRE_SPTR)md->start_subject;        cb.subject          = (PCRE_SPTR)md->start_subject;
1331        cb.subject_length   = md->end_subject - md->start_subject;        cb.subject_length   = (int)(md->end_subject - md->start_subject);
1332        cb.start_match      = mstart - md->start_subject;        cb.start_match      = (int)(mstart - md->start_subject);
1333        cb.current_position = eptr - md->start_subject;        cb.current_position = (int)(eptr - md->start_subject);
1334        cb.pattern_position = GET(ecode, 2);        cb.pattern_position = GET(ecode, 2);
1335        cb.next_item_length = GET(ecode, 2 + LINK_SIZE);        cb.next_item_length = GET(ecode, 2 + LINK_SIZE);
1336        cb.capture_top      = offset_top/2;        cb.capture_top      = offset_top/2;
# Line 1347  for (;;) Line 1402  for (;;)
1402          {          {
1403          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,
1404            md, ims, eptrb, flags, RM6);            md, ims, eptrb, flags, RM6);
1405          if (rrc == MATCH_MATCH)          if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
1406            {            {
1407            DPRINTF(("Recursion matched\n"));            DPRINTF(("Recursion matched\n"));
1408            md->recursive = new_recursive.prevrec;            md->recursive = new_recursive.prevrec;
# Line 1355  for (;;) Line 1410  for (;;)
1410              (pcre_free)(new_recursive.offset_save);              (pcre_free)(new_recursive.offset_save);
1411            MRRETURN(MATCH_MATCH);            MRRETURN(MATCH_MATCH);
1412            }            }
1413          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)          else if (rrc != MATCH_NOMATCH &&
1414                    (rrc != MATCH_THEN || md->start_match_ptr != ecode))
1415            {            {
1416            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1417            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
# Line 1393  for (;;) Line 1449  for (;;)
1449      do      do
1450        {        {
1451        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7);
1452        if (rrc == MATCH_MATCH)        if (rrc == MATCH_MATCH)  /* Note: _not_ MATCH_ACCEPT */
1453          {          {
1454          mstart = md->start_match_ptr;          mstart = md->start_match_ptr;
1455          break;          break;
1456          }          }
1457        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH &&
1458              (rrc != MATCH_THEN || md->start_match_ptr != ecode))
1459            RRETURN(rrc);
1460        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1461        }        }
1462      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
# Line 1552  for (;;) Line 1610  for (;;)
1610          {          {
1611          md->offset_vector[offset] =          md->offset_vector[offset] =
1612            md->offset_vector[md->offset_end - number];            md->offset_vector[md->offset_end - number];
1613          md->offset_vector[offset+1] = eptr - md->start_subject;          md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
1614          if (offset_top <= offset) offset_top = offset + 2;          if (offset_top <= offset) offset_top = offset + 2;
1615          }          }
1616    
# Line 1664  for (;;) Line 1722  for (;;)
1722        if (eptr < md->end_subject)        if (eptr < md->end_subject)
1723          { if (!IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); }          { if (!IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); }
1724        else        else
1725          { if (md->noteol) MRRETURN(MATCH_NOMATCH); }          {
1726            if (md->noteol) MRRETURN(MATCH_NOMATCH);
1727            SCHECK_PARTIAL();
1728            }
1729        ecode++;        ecode++;
1730        break;        break;
1731        }        }
1732      else      else  /* Not multiline */
1733        {        {
1734        if (md->noteol) MRRETURN(MATCH_NOMATCH);        if (md->noteol) MRRETURN(MATCH_NOMATCH);
1735        if (!md->endonly)        if (!md->endonly) goto ASSERT_NL_OR_EOS;
         {  
         if (eptr != md->end_subject &&  
             (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))  
           MRRETURN(MATCH_NOMATCH);  
         ecode++;  
         break;  
         }  
1736        }        }
1737    
1738      /* ... else fall through for endonly */      /* ... else fall through for endonly */
1739    
1740      /* End of subject assertion (\z) */      /* End of subject assertion (\z) */
1741    
1742      case OP_EOD:      case OP_EOD:
1743      if (eptr < md->end_subject) MRRETURN(MATCH_NOMATCH);      if (eptr < md->end_subject) MRRETURN(MATCH_NOMATCH);
1744        SCHECK_PARTIAL();
1745      ecode++;      ecode++;
1746      break;      break;
1747    
1748      /* End of subject or ending \n assertion (\Z) */      /* End of subject or ending \n assertion (\Z) */
1749    
1750      case OP_EODN:      case OP_EODN:
1751      if (eptr != md->end_subject &&      ASSERT_NL_OR_EOS:
1752        if (eptr < md->end_subject &&
1753          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
1754        MRRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1755    
1756        /* Either at end of string or \n before end. */
1757    
1758        SCHECK_PARTIAL();
1759      ecode++;      ecode++;
1760      break;      break;
1761    
# Line 1712  for (;;) Line 1773  for (;;)
1773  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1774        if (utf8)        if (utf8)
1775          {          {
1776            /* Get status of previous character */
1777    
1778          if (eptr == md->start_subject) prev_is_word = FALSE; else          if (eptr == md->start_subject) prev_is_word = FALSE; else
1779            {            {
1780            USPTR lastptr = eptr - 1;            USPTR lastptr = eptr - 1;
1781            while((*lastptr & 0xc0) == 0x80) lastptr--;            while((*lastptr & 0xc0) == 0x80) lastptr--;
1782            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
1783            GETCHAR(c, lastptr);            GETCHAR(c, lastptr);
1784    #ifdef SUPPORT_UCP
1785              if (md->use_ucp)
1786                {
1787                if (c == '_') prev_is_word = TRUE; else
1788                  {
1789                  int cat = UCD_CATEGORY(c);
1790                  prev_is_word = (cat == ucp_L || cat == ucp_N);
1791                  }
1792                }
1793              else
1794    #endif
1795            prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;            prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1796            }            }
1797    
1798            /* Get status of next character */
1799    
1800          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
1801            {            {
1802            SCHECK_PARTIAL();            SCHECK_PARTIAL();
# Line 1728  for (;;) Line 1805  for (;;)
1805          else          else
1806            {            {
1807            GETCHAR(c, eptr);            GETCHAR(c, eptr);
1808    #ifdef SUPPORT_UCP
1809              if (md->use_ucp)
1810                {
1811                if (c == '_') cur_is_word = TRUE; else
1812                  {
1813                  int cat = UCD_CATEGORY(c);
1814                  cur_is_word = (cat == ucp_L || cat == ucp_N);
1815                  }
1816                }
1817              else
1818    #endif
1819            cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;            cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1820            }            }
1821          }          }
1822        else        else
1823  #endif  #endif
1824    
1825        /* Not in UTF-8 mode */        /* Not in UTF-8 mode, but we may still have PCRE_UCP set, and for
1826          consistency with the behaviour of \w we do use it in this case. */
1827    
1828          {          {
1829            /* Get status of previous character */
1830    
1831          if (eptr == md->start_subject) prev_is_word = FALSE; else          if (eptr == md->start_subject) prev_is_word = FALSE; else
1832            {            {
1833            if (eptr <= md->start_used_ptr) md->start_used_ptr = eptr - 1;            if (eptr <= md->start_used_ptr) md->start_used_ptr = eptr - 1;
1834    #ifdef SUPPORT_UCP
1835              if (md->use_ucp)
1836                {
1837                c = eptr[-1];
1838                if (c == '_') prev_is_word = TRUE; else
1839                  {
1840                  int cat = UCD_CATEGORY(c);
1841                  prev_is_word = (cat == ucp_L || cat == ucp_N);
1842                  }
1843                }
1844              else
1845    #endif
1846            prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);            prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);
1847            }            }
1848    
1849            /* Get status of next character */
1850    
1851          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
1852            {            {
1853            SCHECK_PARTIAL();            SCHECK_PARTIAL();
1854            cur_is_word = FALSE;            cur_is_word = FALSE;
1855            }            }
1856          else cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);          else
1857    #ifdef SUPPORT_UCP
1858            if (md->use_ucp)
1859              {
1860              c = *eptr;
1861              if (c == '_') cur_is_word = TRUE; else
1862                {
1863                int cat = UCD_CATEGORY(c);
1864                cur_is_word = (cat == ucp_L || cat == ucp_N);
1865                }
1866              }
1867            else
1868    #endif
1869            cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);
1870          }          }
1871    
1872        /* Now see if the situation is what we want */        /* Now see if the situation is what we want */
# Line 2054  for (;;) Line 2173  for (;;)
2173               prop->chartype == ucp_Ll ||               prop->chartype == ucp_Ll ||
2174               prop->chartype == ucp_Lt) == (op == OP_NOTPROP))               prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
2175            MRRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2176           break;          break;
2177    
2178          case PT_GC:          case PT_GC:
2179          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))
# Line 2071  for (;;) Line 2190  for (;;)
2190            MRRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2191          break;          break;
2192    
2193            /* These are specials */
2194    
2195            case PT_ALNUM:
2196            if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||
2197                 _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
2198              MRRETURN(MATCH_NOMATCH);
2199            break;
2200    
2201            case PT_SPACE:    /* Perl space */
2202            if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
2203                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
2204                   == (op == OP_NOTPROP))
2205              MRRETURN(MATCH_NOMATCH);
2206            break;
2207    
2208            case PT_PXSPACE:  /* POSIX space */
2209            if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
2210                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
2211                 c == CHAR_FF || c == CHAR_CR)
2212                   == (op == OP_NOTPROP))
2213              MRRETURN(MATCH_NOMATCH);
2214            break;
2215    
2216            case PT_WORD:
2217            if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||
2218                 _pcre_ucp_gentype[prop->chartype] == ucp_N ||
2219                 c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
2220              MRRETURN(MATCH_NOMATCH);
2221            break;
2222    
2223            /* This should never occur */
2224    
2225          default:          default:
2226          RRETURN(PCRE_ERROR_INTERNAL);          RRETURN(PCRE_ERROR_INTERNAL);
2227          }          }
# Line 2118  for (;;) Line 2269  for (;;)
2269      loops). */      loops). */
2270    
2271      case OP_REF:      case OP_REF:
2272        {      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */
2273        offset = GET2(ecode, 1) << 1;               /* Doubled ref number */      ecode += 3;
       ecode += 3;  
2274    
2275        /* If the reference is unset, there are two possibilities:      /* If the reference is unset, there are two possibilities:
2276    
2277        (a) In the default, Perl-compatible state, set the length to be longer      (a) In the default, Perl-compatible state, set the length negative;
2278        than the amount of subject left; this ensures that every attempt at a      this ensures that every attempt at a match fails. We can't just fail
2279        match fails. We can't just fail here, because of the possibility of      here, because of the possibility of quantifiers with zero minima.
       quantifiers with zero minima.  
2280    
2281        (b) If the JavaScript compatibility flag is set, set the length to zero      (b) If the JavaScript compatibility flag is set, set the length to zero
2282        so that the back reference matches an empty string.      so that the back reference matches an empty string.
2283    
2284        Otherwise, set the length to the length of what was matched by the      Otherwise, set the length to the length of what was matched by the
2285        referenced subpattern. */      referenced subpattern. */
2286    
2287        if (offset >= offset_top || md->offset_vector[offset] < 0)      if (offset >= offset_top || md->offset_vector[offset] < 0)
2288          length = (md->jscript_compat)? 0 : md->end_subject - eptr + 1;        length = (md->jscript_compat)? 0 : -1;
2289        else      else
2290          length = md->offset_vector[offset+1] - md->offset_vector[offset];        length = md->offset_vector[offset+1] - md->offset_vector[offset];
2291    
2292        /* Set up for repetition, or handle the non-repeated case */      /* Set up for repetition, or handle the non-repeated case */
2293    
2294        switch (*ecode)      switch (*ecode)
2295          {        {
2296          case OP_CRSTAR:        case OP_CRSTAR:
2297          case OP_CRMINSTAR:        case OP_CRMINSTAR:
2298          case OP_CRPLUS:        case OP_CRPLUS:
2299          case OP_CRMINPLUS:        case OP_CRMINPLUS:
2300          case OP_CRQUERY:        case OP_CRQUERY:
2301          case OP_CRMINQUERY:        case OP_CRMINQUERY:
2302          c = *ecode++ - OP_CRSTAR;        c = *ecode++ - OP_CRSTAR;
2303          minimize = (c & 1) != 0;        minimize = (c & 1) != 0;
2304          min = rep_min[c];                 /* Pick up values from tables; */        min = rep_min[c];                 /* Pick up values from tables; */
2305          max = rep_max[c];                 /* zero for max => infinity */        max = rep_max[c];                 /* zero for max => infinity */
2306          if (max == 0) max = INT_MAX;        if (max == 0) max = INT_MAX;
2307          break;        break;
2308    
2309          case OP_CRRANGE:        case OP_CRRANGE:
2310          case OP_CRMINRANGE:        case OP_CRMINRANGE:
2311          minimize = (*ecode == OP_CRMINRANGE);        minimize = (*ecode == OP_CRMINRANGE);
2312          min = GET2(ecode, 1);        min = GET2(ecode, 1);
2313          max = GET2(ecode, 3);        max = GET2(ecode, 3);
2314          if (max == 0) max = INT_MAX;        if (max == 0) max = INT_MAX;
2315          ecode += 5;        ecode += 5;
2316          break;        break;
2317    
2318          default:               /* No repeat follows */        default:               /* No repeat follows */
2319          if (!match_ref(offset, eptr, length, md, ims))        if ((length = match_ref(offset, eptr, length, md, ims)) < 0)
2320            {          {
2321            CHECK_PARTIAL();          CHECK_PARTIAL();
2322            MRRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
           }  
         eptr += length;  
         continue;              /* With the main loop */  
2323          }          }
2324          eptr += length;
2325          continue;              /* With the main loop */
2326          }
2327    
2328        /* If the length of the reference is zero, just continue with the      /* Handle repeated back references. If the length of the reference is
2329        main loop. */      zero, just continue with the main loop. */
2330    
2331        if (length == 0) continue;      if (length == 0) continue;
2332    
2333        /* First, ensure the minimum number of matches are present. We get back      /* First, ensure the minimum number of matches are present. We get back
2334        the length of the reference string explicitly rather than passing the      the length of the reference string explicitly rather than passing the
2335        address of eptr, so that eptr can be a register variable. */      address of eptr, so that eptr can be a register variable. */
2336    
2337        for (i = 1; i <= min; i++)      for (i = 1; i <= min; i++)
2338          {
2339          int slength;
2340          if ((slength = match_ref(offset, eptr, length, md, ims)) < 0)
2341          {          {
2342          if (!match_ref(offset, eptr, length, md, ims))          CHECK_PARTIAL();
2343            {          MRRETURN(MATCH_NOMATCH);
           CHECK_PARTIAL();  
           MRRETURN(MATCH_NOMATCH);  
           }  
         eptr += length;  
2344          }          }
2345          eptr += slength;
2346          }
2347    
2348        /* If min = max, continue at the same level without recursion.      /* If min = max, continue at the same level without recursion.
2349        They are not both allowed to be zero. */      They are not both allowed to be zero. */
2350    
2351        if (min == max) continue;      if (min == max) continue;
2352    
2353        /* If minimizing, keep trying and advancing the pointer */      /* If minimizing, keep trying and advancing the pointer */
2354    
2355        if (minimize)      if (minimize)
2356          {
2357          for (fi = min;; fi++)
2358          {          {
2359          for (fi = min;; fi++)          int slength;
2360            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);
2361            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2362            if (fi >= max) MRRETURN(MATCH_NOMATCH);
2363            if ((slength = match_ref(offset, eptr, length, md, ims)) < 0)
2364            {            {
2365            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);            CHECK_PARTIAL();
2366            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            MRRETURN(MATCH_NOMATCH);
           if (fi >= max) MRRETURN(MATCH_NOMATCH);  
           if (!match_ref(offset, eptr, length, md, ims))  
             {  
             CHECK_PARTIAL();  
             MRRETURN(MATCH_NOMATCH);  
             }  
           eptr += length;  
2367            }            }
2368          /* Control never gets here */          eptr += slength;
2369          }          }
2370          /* Control never gets here */
2371          }
2372    
2373        /* If maximizing, find the longest string and work backwards */      /* If maximizing, find the longest string and work backwards */
2374    
2375        else      else
2376          {
2377          pp = eptr;
2378          for (i = min; i < max; i++)
2379          {          {
2380          pp = eptr;          int slength;
2381          for (i = min; i < max; i++)          if ((slength = match_ref(offset, eptr, length, md, ims)) < 0)
           {  
           if (!match_ref(offset, eptr, length, md, ims))  
             {  
             CHECK_PARTIAL();  
             break;  
             }  
           eptr += length;  
           }  
         while (eptr >= pp)  
2382            {            {
2383            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15);            CHECK_PARTIAL();
2384            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            break;
           eptr -= length;  
2385            }            }
2386          MRRETURN(MATCH_NOMATCH);          eptr += slength;
2387          }          }
2388          while (eptr >= pp)
2389            {
2390            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15);
2391            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2392            eptr -= length;
2393            }
2394          MRRETURN(MATCH_NOMATCH);
2395        }        }
2396      /* Control never gets here */      /* Control never gets here */
2397    
# Line 3487  for (;;) Line 3638  for (;;)
3638              }              }
3639            break;            break;
3640    
3641              case PT_ALNUM:
3642              for (i = 1; i <= min; i++)
3643                {
3644                if (eptr >= md->end_subject)
3645                  {
3646                  SCHECK_PARTIAL();
3647                  MRRETURN(MATCH_NOMATCH);
3648                  }
3649                GETCHARINCTEST(c, eptr);
3650                prop_category = UCD_CATEGORY(c);
3651                if ((prop_category == ucp_L || prop_category == ucp_N)
3652                       == prop_fail_result)
3653                  MRRETURN(MATCH_NOMATCH);
3654                }
3655              break;
3656    
3657              case PT_SPACE:    /* Perl space */
3658              for (i = 1; i <= min; i++)
3659                {
3660                if (eptr >= md->end_subject)
3661                  {
3662                  SCHECK_PARTIAL();
3663                  MRRETURN(MATCH_NOMATCH);
3664                  }
3665                GETCHARINCTEST(c, eptr);
3666                prop_category = UCD_CATEGORY(c);
3667                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
3668                     c == CHAR_FF || c == CHAR_CR)
3669                       == prop_fail_result)
3670                  MRRETURN(MATCH_NOMATCH);
3671                }
3672              break;
3673    
3674              case PT_PXSPACE:  /* POSIX space */
3675              for (i = 1; i <= min; i++)
3676                {
3677                if (eptr >= md->end_subject)
3678                  {
3679                  SCHECK_PARTIAL();
3680                  MRRETURN(MATCH_NOMATCH);
3681                  }
3682                GETCHARINCTEST(c, eptr);
3683                prop_category = UCD_CATEGORY(c);
3684                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
3685                     c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
3686                       == prop_fail_result)
3687                  MRRETURN(MATCH_NOMATCH);
3688                }
3689              break;
3690    
3691              case PT_WORD:
3692              for (i = 1; i <= min; i++)
3693                {
3694                if (eptr >= md->end_subject)
3695                  {
3696                  SCHECK_PARTIAL();
3697                  MRRETURN(MATCH_NOMATCH);
3698                  }
3699                GETCHARINCTEST(c, eptr);
3700                prop_category = UCD_CATEGORY(c);
3701                if ((prop_category == ucp_L || prop_category == ucp_N ||
3702                     c == CHAR_UNDERSCORE)
3703                       == prop_fail_result)
3704                  MRRETURN(MATCH_NOMATCH);
3705                }
3706              break;
3707    
3708              /* This should not occur */
3709    
3710            default:            default:
3711            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
3712            }            }
# Line 4047  for (;;) Line 4267  for (;;)
4267                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4268                MRRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4269                }                }
4270              GETCHARINC(c, eptr);              GETCHARINCTEST(c, eptr);
4271              if (prop_fail_result) MRRETURN(MATCH_NOMATCH);              if (prop_fail_result) MRRETURN(MATCH_NOMATCH);
4272              }              }
4273            /* Control never gets here */            /* Control never gets here */
# Line 4063  for (;;) Line 4283  for (;;)
4283                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4284                MRRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4285                }                }
4286              GETCHARINC(c, eptr);              GETCHARINCTEST(c, eptr);
4287              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4288              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
4289                   prop_chartype == ucp_Ll ||                   prop_chartype == ucp_Ll ||
# Line 4083  for (;;) Line 4303  for (;;)
4303                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4304                MRRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4305                }                }
4306              GETCHARINC(c, eptr);              GETCHARINCTEST(c, eptr);
4307              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
4308              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
4309                MRRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
# Line 4101  for (;;) Line 4321  for (;;)
4321                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4322                MRRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4323                }                }
4324              GETCHARINC(c, eptr);              GETCHARINCTEST(c, eptr);
4325              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4326              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
4327                MRRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
# Line 4119  for (;;) Line 4339  for (;;)
4339                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4340                MRRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4341                }                }
4342              GETCHARINC(c, eptr);              GETCHARINCTEST(c, eptr);
4343              prop_script = UCD_SCRIPT(c);              prop_script = UCD_SCRIPT(c);
4344              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
4345                MRRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4346              }              }
4347            /* Control never gets here */            /* Control never gets here */
4348    
4349              case PT_ALNUM:
4350              for (fi = min;; fi++)
4351                {
4352                RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM59);
4353                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4354                if (fi >= max) MRRETURN(MATCH_NOMATCH);
4355                if (eptr >= md->end_subject)
4356                  {
4357                  SCHECK_PARTIAL();
4358                  MRRETURN(MATCH_NOMATCH);
4359                  }
4360                GETCHARINCTEST(c, eptr);
4361                prop_category = UCD_CATEGORY(c);
4362                if ((prop_category == ucp_L || prop_category == ucp_N)
4363                       == prop_fail_result)
4364                  MRRETURN(MATCH_NOMATCH);
4365                }
4366              /* Control never gets here */
4367    
4368              case PT_SPACE:    /* Perl space */
4369              for (fi = min;; fi++)
4370                {
4371                RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM60);
4372                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4373                if (fi >= max) MRRETURN(MATCH_NOMATCH);
4374                if (eptr >= md->end_subject)
4375                  {
4376                  SCHECK_PARTIAL();
4377                  MRRETURN(MATCH_NOMATCH);
4378                  }
4379                GETCHARINCTEST(c, eptr);
4380                prop_category = UCD_CATEGORY(c);
4381                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4382                     c == CHAR_FF || c == CHAR_CR)
4383                       == prop_fail_result)
4384                  MRRETURN(MATCH_NOMATCH);
4385                }
4386              /* Control never gets here */
4387    
4388              case PT_PXSPACE:  /* POSIX space */
4389              for (fi = min;; fi++)
4390                {
4391                RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM61);
4392                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4393                if (fi >= max) MRRETURN(MATCH_NOMATCH);
4394                if (eptr >= md->end_subject)
4395                  {
4396                  SCHECK_PARTIAL();
4397                  MRRETURN(MATCH_NOMATCH);
4398                  }
4399                GETCHARINCTEST(c, eptr);
4400                prop_category = UCD_CATEGORY(c);
4401                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4402                     c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
4403                       == prop_fail_result)
4404                  MRRETURN(MATCH_NOMATCH);
4405                }
4406              /* Control never gets here */
4407    
4408              case PT_WORD:
4409              for (fi = min;; fi++)
4410                {
4411                RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM62);
4412                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4413                if (fi >= max) MRRETURN(MATCH_NOMATCH);
4414                if (eptr >= md->end_subject)
4415                  {
4416                  SCHECK_PARTIAL();
4417                  MRRETURN(MATCH_NOMATCH);
4418                  }
4419                GETCHARINCTEST(c, eptr);
4420                prop_category = UCD_CATEGORY(c);
4421                if ((prop_category == ucp_L ||
4422                     prop_category == ucp_N ||
4423                     c == CHAR_UNDERSCORE)
4424                       == prop_fail_result)
4425                  MRRETURN(MATCH_NOMATCH);
4426                }
4427              /* Control never gets here */
4428    
4429              /* This should never occur */
4430    
4431            default:            default:
4432            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
4433            }            }
# Line 4472  for (;;) Line 4774  for (;;)
4774                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4775                break;                break;
4776                }                }
4777              GETCHARLEN(c, eptr, len);              GETCHARLENTEST(c, eptr, len);
4778              if (prop_fail_result) break;              if (prop_fail_result) break;
4779              eptr+= len;              eptr+= len;
4780              }              }
# Line 4487  for (;;) Line 4789  for (;;)
4789                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4790                break;                break;
4791                }                }
4792              GETCHARLEN(c, eptr, len);              GETCHARLENTEST(c, eptr, len);
4793              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4794              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
4795                   prop_chartype == ucp_Ll ||                   prop_chartype == ucp_Ll ||
# Line 4506  for (;;) Line 4808  for (;;)
4808                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4809                break;                break;
4810                }                }
4811              GETCHARLEN(c, eptr, len);              GETCHARLENTEST(c, eptr, len);
4812              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
4813              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
4814                break;                break;
# Line 4523  for (;;) Line 4825  for (;;)
4825                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4826                break;                break;
4827                }                }
4828              GETCHARLEN(c, eptr, len);              GETCHARLENTEST(c, eptr, len);
4829              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4830              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
4831                break;                break;
# Line 4540  for (;;) Line 4842  for (;;)
4842                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4843                break;                break;
4844                }                }
4845              GETCHARLEN(c, eptr, len);              GETCHARLENTEST(c, eptr, len);
4846              prop_script = UCD_SCRIPT(c);              prop_script = UCD_SCRIPT(c);
4847              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
4848                break;                break;
4849              eptr+= len;              eptr+= len;
4850              }              }
4851            break;            break;
4852    
4853              case PT_ALNUM:
4854              for (i = min; i < max; i++)
4855                {
4856                int len = 1;
4857                if (eptr >= md->end_subject)
4858                  {
4859                  SCHECK_PARTIAL();
4860                  break;
4861                  }
4862                GETCHARLENTEST(c, eptr, len);
4863                prop_category = UCD_CATEGORY(c);
4864                if ((prop_category == ucp_L || prop_category == ucp_N)
4865                     == prop_fail_result)
4866                  break;
4867                eptr+= len;
4868                }
4869              break;
4870    
4871              case PT_SPACE:    /* Perl space */
4872              for (i = min; i < max; i++)
4873                {
4874                int len = 1;
4875                if (eptr >= md->end_subject)
4876                  {
4877                  SCHECK_PARTIAL();
4878                  break;
4879                  }
4880                GETCHARLENTEST(c, eptr, len);
4881                prop_category = UCD_CATEGORY(c);
4882                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4883                     c == CHAR_FF || c == CHAR_CR)
4884                     == prop_fail_result)
4885                  break;
4886                eptr+= len;
4887                }
4888              break;
4889    
4890              case PT_PXSPACE:  /* POSIX space */
4891              for (i = min; i < max; i++)
4892                {
4893                int len = 1;
4894                if (eptr >= md->end_subject)
4895                  {
4896                  SCHECK_PARTIAL();
4897                  break;
4898                  }
4899                GETCHARLENTEST(c, eptr, len);
4900                prop_category = UCD_CATEGORY(c);
4901                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4902                     c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
4903                     == prop_fail_result)
4904                  break;
4905                eptr+= len;
4906                }
4907              break;
4908    
4909              case PT_WORD:
4910              for (i = min; i < max; i++)
4911                {
4912                int len = 1;
4913                if (eptr >= md->end_subject)
4914                  {
4915                  SCHECK_PARTIAL();
4916                  break;
4917                  }
4918                GETCHARLENTEST(c, eptr, len);
4919                prop_category = UCD_CATEGORY(c);
4920                if ((prop_category == ucp_L || prop_category == ucp_N ||
4921                     c == CHAR_UNDERSCORE) == prop_fail_result)
4922                  break;
4923                eptr+= len;
4924                }
4925              break;
4926    
4927              default:
4928              RRETURN(PCRE_ERROR_INTERNAL);
4929            }            }
4930    
4931          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
# Line 5132  switch (frame->Xwhere) Line 5511  switch (frame->Xwhere)
5511    LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17)    LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17)
5512    LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33)    LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33)
5513    LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52)    LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52)
5514    LBL(53) LBL(54)    LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58)
5515  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
5516    LBL(16) LBL(18) LBL(20) LBL(21) LBL(22) LBL(23) LBL(28) LBL(30)    LBL(16) LBL(18) LBL(20) LBL(21) LBL(22) LBL(23) LBL(28) LBL(30)
5517    LBL(32) LBL(34) LBL(42) LBL(46)    LBL(32) LBL(34) LBL(42) LBL(46)
5518  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
5519    LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45)    LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45)
5520      LBL(59) LBL(60) LBL(61) LBL(62)
5521  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
5522  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF8 */
5523    default:    default:
# Line 5271  if ((options & ~PUBLIC_EXEC_OPTIONS) != Line 5651  if ((options & ~PUBLIC_EXEC_OPTIONS) !=
5651  if (re == NULL || subject == NULL ||  if (re == NULL || subject == NULL ||
5652     (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;     (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
5653  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
5654    if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
5655    
5656  /* This information is for finding all the numbers associated with a given  /* This information is for finding all the numbers associated with a given
5657  name, for condition testing. */  name, for condition testing. */
# Line 5341  end_subject = md->end_subject; Line 5722  end_subject = md->end_subject;
5722    
5723  md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
5724  utf8 = md->utf8 = (re->options & PCRE_UTF8) != 0;  utf8 = md->utf8 = (re->options & PCRE_UTF8) != 0;
5725    md->use_ucp = (re->options & PCRE_UCP) != 0;
5726  md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
5727    
5728  md->notbol = (options & PCRE_NOTBOL) != 0;  md->notbol = (options & PCRE_NOTBOL) != 0;
# Line 5430  defined (though never set). So there's n Line 5812  defined (though never set). So there's n
5812  if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0)  if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0)
5813    return PCRE_ERROR_BADPARTIAL;    return PCRE_ERROR_BADPARTIAL;
5814    
5815  /* Check a UTF-8 string if required. Unfortunately there's no way of passing  /* Check a UTF-8 string if required. Pass back the character offset and error
5816  back the character offset. */  code if a results vector is available. */
5817    
5818  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
5819  if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)  if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)
5820    {    {
5821    if (_pcre_valid_utf8((USPTR)subject, length) >= 0)    int errorcode;
5822      return PCRE_ERROR_BADUTF8;    int tb = _pcre_valid_utf8((USPTR)subject, length, &errorcode);
5823    if (start_offset > 0 && start_offset < length)    if (tb >= 0)
5824      {      {
5825      int tb = ((USPTR)subject)[start_offset];      if (offsetcount >= 2)
     if (tb > 127)  
5826        {        {
5827        tb &= 0xc0;        offsets[0] = tb;
5828        if (tb != 0 && tb != 0xc0) return PCRE_ERROR_BADUTF8_OFFSET;        offsets[1] = errorcode;
5829        }        }
5830        return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)?
5831          PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
5832        }
5833      if (start_offset > 0 && start_offset < length)
5834        {
5835        tb = ((USPTR)subject)[start_offset] & 0xc0;
5836        if (tb == 0x80) return PCRE_ERROR_BADUTF8_OFFSET;
5837      }      }
5838    }    }
5839  #endif  #endif
# Line 5573  for(;;) Line 5961  for(;;)
5961    /* There are some optimizations that avoid running the match if a known    /* There are some optimizations that avoid running the match if a known
5962    starting point is not found, or if a known later character is not present.    starting point is not found, or if a known later character is not present.
5963    However, there is an option that disables these, for testing and for ensuring    However, there is an option that disables these, for testing and for ensuring
5964    that all callouts do actually occur. */    that all callouts do actually occur. The option can be set in the regex by
5965      (*NO_START_OPT) or passed in match-time options. */
5966    
5967    if ((options & PCRE_NO_START_OPTIMIZE) == 0)    if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)
5968      {      {
5969      /* Advance to a unique first byte if there is one. */      /* Advance to a unique first byte if there is one. */
5970    
# Line 5629  for(;;) Line 6018  for(;;)
6018        while (start_match < end_subject)        while (start_match < end_subject)
6019          {          {
6020          register unsigned int c = *start_match;          register unsigned int c = *start_match;
6021          if ((start_bits[c/8] & (1 << (c&7))) == 0) start_match++;          if ((start_bits[c/8] & (1 << (c&7))) == 0)
6022            else break;            {
6023              start_match++;
6024    #ifdef SUPPORT_UTF8
6025              if (utf8)
6026                while(start_match < end_subject && (*start_match & 0xc0) == 0x80)
6027                  start_match++;
6028    #endif
6029              }
6030            else break;
6031          }          }
6032        }        }
6033      }   /* Starting optimizations */      }   /* Starting optimizations */
# Line 5721  for(;;) Line 6118  for(;;)
6118    
6119    /* OK, we can now run the match. If "hitend" is set afterwards, remember the    /* OK, we can now run the match. If "hitend" is set afterwards, remember the
6120    first starting point for which a partial match was found. */    first starting point for which a partial match was found. */
6121    
6122    md->start_match_ptr = start_match;    md->start_match_ptr = start_match;
6123    md->start_used_ptr = start_match;    md->start_used_ptr = start_match;
6124    md->match_call_count = 0;    md->match_call_count = 0;
# Line 5731  for(;;) Line 6128  for(;;)
6128    
6129    switch(rc)    switch(rc)
6130      {      {
6131      /* NOMATCH and PRUNE advance by one character. If MATCH_SKIP_ARG reaches      /* SKIP passes back the next starting point explicitly, but if it is the
6132      this level it means that a MARK that matched the SKIP's arg was not found.      same as the match we have just done, treat it as NOMATCH. */
6133      We treat this as NOMATCH. THEN at this level acts exactly like PRUNE. */  
6134        case MATCH_SKIP:
6135        if (md->start_match_ptr != start_match)
6136          {
6137          new_start_match = md->start_match_ptr;
6138          break;
6139          }
6140        /* Fall through */
6141    
6142        /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched
6143        the SKIP's arg was not found. We also treat this as NOMATCH. */
6144    
6145        case MATCH_SKIP_ARG:
6146        /* Fall through */
6147    
6148        /* NOMATCH and PRUNE advance by one character. THEN at this level acts
6149        exactly like PRUNE. */
6150    
6151      case MATCH_NOMATCH:      case MATCH_NOMATCH:
6152      case MATCH_PRUNE:      case MATCH_PRUNE:
     case MATCH_SKIP_ARG:  
6153      case MATCH_THEN:      case MATCH_THEN:
6154      new_start_match = start_match + 1;      new_start_match = start_match + 1;
6155  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 5747  for(;;) Line 6159  for(;;)
6159  #endif  #endif
6160      break;      break;
6161    
     /* SKIP passes back the next starting point explicitly. */  
   
     case MATCH_SKIP:  
     new_start_match = md->start_match_ptr;  
     break;  
   
6162      /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */      /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */
6163    
6164      case MATCH_COMMIT:      case MATCH_COMMIT:
# Line 5823  capturing parentheses than vector slots. Line 6229  capturing parentheses than vector slots.
6229    
6230  ENDLOOP:  ENDLOOP:
6231    
6232  if (rc == MATCH_MATCH)  if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
6233    {    {
6234    if (using_temporary_offsets)    if (using_temporary_offsets)
6235      {      {
# Line 5849  if (rc == MATCH_MATCH) Line 6255  if (rc == MATCH_MATCH)
6255    
6256    if (offsetcount < 2) rc = 0; else    if (offsetcount < 2) rc = 0; else
6257      {      {
6258      offsets[0] = md->start_match_ptr - md->start_subject;      offsets[0] = (int)(md->start_match_ptr - md->start_subject);
6259      offsets[1] = md->end_match_ptr - md->start_subject;      offsets[1] = (int)(md->end_match_ptr - md->start_subject);
6260      }      }
6261    
6262    DPRINTF((">>>> returning %d\n", rc));    DPRINTF((">>>> returning %d\n", rc));
# Line 5865  if (using_temporary_offsets) Line 6271  if (using_temporary_offsets)
6271    DPRINTF(("Freeing temporary memory\n"));    DPRINTF(("Freeing temporary memory\n"));
6272    (pcre_free)(md->offset_vector);    (pcre_free)(md->offset_vector);
6273    }    }
6274    
6275  /* For anything other than nomatch or partial match, just return the code. */  /* For anything other than nomatch or partial match, just return the code. */
6276    
6277  if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)  if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)
6278    {    {
6279    DPRINTF((">>>> error: returning %d\n", rc));    DPRINTF((">>>> error: returning %d\n", rc));
6280    return rc;    return rc;
6281    }    }
6282    
6283  /* Handle partial matches - disable any mark data */  /* Handle partial matches - disable any mark data */
6284    
6285  if (start_partial != NULL)  if (start_partial != NULL)
6286    {    {
6287    DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));    DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));
6288    md->mark = NULL;    md->mark = NULL;
6289    if (offsetcount > 1)    if (offsetcount > 1)
6290      {      {
6291      offsets[0] = start_partial - (USPTR)subject;      offsets[0] = (int)(start_partial - (USPTR)subject);
6292      offsets[1] = end_subject - (USPTR)subject;      offsets[1] = (int)(end_subject - (USPTR)subject);
6293      }      }
6294    rc = PCRE_ERROR_PARTIAL;    rc = PCRE_ERROR_PARTIAL;
6295    }    }
6296    
6297  /* This is the classic nomatch case */  /* This is the classic nomatch case */
6298    
6299  else  else
6300    {    {
6301    DPRINTF((">>>> returning PCRE_ERROR_NOMATCH\n"));    DPRINTF((">>>> returning PCRE_ERROR_NOMATCH\n"));
6302    rc = PCRE_ERROR_NOMATCH;    rc = PCRE_ERROR_NOMATCH;
6303    }    }
6304    
6305  /* Return the MARK data if it has been requested. */  /* Return the MARK data if it has been requested. */
6306    
6307  RETURN_MARK:  RETURN_MARK:
6308    
6309  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
6310    *(extra_data->mark) = (unsigned char *)(md->mark);    *(extra_data->mark) = (unsigned char *)(md->mark);
6311  return rc;  return rc;
6312  }  }
6313    
6314  /* End of pcre_exec.c */  /* End of pcre_exec.c */

Legend:
Removed from v.510  
changed lines
  Added in v.598

  ViewVC Help
Powered by ViewVC 1.1.5