/[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 1055 by chpe, Tue Oct 16 15:53:30 2012 UTC revision 1361 by ph10, Fri Sep 6 17:47:32 2013 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-2012 University of Cambridge             Copyright (c) 1997-2013 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 56  possible. There are also some static sup Line 56  possible. There are also some static sup
56  #undef min  #undef min
57  #undef max  #undef max
58    
59    /* The md->capture_last field uses the lower 16 bits for the last captured
60    substring (which can never be greater than 65535) and a bit in the top half
61    to mean "capture vector overflowed". This odd way of doing things was
62    implemented when it was realized that preserving and restoring the overflow bit
63    whenever the last capture number was saved/restored made for a neater
64    interface, and doing it this way saved on (a) another variable, which would
65    have increased the stack frame size (a big NO-NO in PCRE) and (b) another
66    separate set of save/restore instructions. The following defines are used in
67    implementing this. */
68    
69    #define CAPLMASK    0x0000ffff    /* The bits used for last_capture */
70    #define OVFLMASK    0xffff0000    /* The bits used for the overflow flag */
71    #define OVFLBIT     0x00010000    /* The bit that is set for overflow */
72    
73  /* Values for setting in md->match_function_type to indicate two special types  /* Values for setting in md->match_function_type to indicate two special types
74  of call to match(). We do it this way to save on using another stack variable,  of call to match(). We do it this way to save on using another stack variable,
75  as stack usage is to be discouraged. */  as stack usage is to be discouraged. */
# Line 73  defined PCRE_ERROR_xxx codes, which are Line 87  defined PCRE_ERROR_xxx codes, which are
87  negative to avoid the external error codes. */  negative to avoid the external error codes. */
88    
89  #define MATCH_ACCEPT       (-999)  #define MATCH_ACCEPT       (-999)
90  #define MATCH_COMMIT       (-998)  #define MATCH_KETRPOS      (-998)
91  #define MATCH_KETRPOS      (-997)  #define MATCH_ONCE         (-997)
92  #define MATCH_ONCE         (-996)  /* The next 5 must be kept together and in sequence so that a test that checks
93    for any one of them can use a range. */
94    #define MATCH_COMMIT       (-996)
95  #define MATCH_PRUNE        (-995)  #define MATCH_PRUNE        (-995)
96  #define MATCH_SKIP         (-994)  #define MATCH_SKIP         (-994)
97  #define MATCH_SKIP_ARG     (-993)  #define MATCH_SKIP_ARG     (-993)
98  #define MATCH_THEN         (-992)  #define MATCH_THEN         (-992)
99    #define MATCH_BACKTRACK_MAX MATCH_THEN
100    #define MATCH_BACKTRACK_MIN MATCH_COMMIT
101    
102  /* Maximum number of ints of offset to save on the stack for recursive calls.  /* Maximum number of ints of offset to save on the stack for recursive calls.
103  If the offset vector is bigger, malloc is used. This should be a multiple of 3,  If the offset vector is bigger, malloc is used. This should be a multiple of 3,
# Line 92  because the offset vector is always a mu Line 110  because the offset vector is always a mu
110  static const char rep_min[] = { 0, 0, 1, 1, 0, 0 };  static const char rep_min[] = { 0, 0, 1, 1, 0, 0 };
111  static const char rep_max[] = { 0, 0, 0, 0, 1, 1 };  static const char rep_max[] = { 0, 0, 0, 0, 1, 1 };
112    
   
   
113  #ifdef PCRE_DEBUG  #ifdef PCRE_DEBUG
114  /*************************************************  /*************************************************
115  *        Debugging function to print chars       *  *        Debugging function to print chars       *
# Line 114  Returns:     nothing Line 130  Returns:     nothing
130  static void  static void
131  pchars(const pcre_uchar *p, int length, BOOL is_subject, match_data *md)  pchars(const pcre_uchar *p, int length, BOOL is_subject, match_data *md)
132  {  {
133  unsigned int c;  pcre_uint32 c;
134    BOOL utf = md->utf;
135  if (is_subject && length > md->end_subject - p) length = md->end_subject - p;  if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
136  while (length-- > 0)  while (length-- > 0)
137    if (isprint(c = *(p++))) printf("%c", c); else printf("\\x%02x", c);    if (isprint(c = RAWUCHARINCTEST(p))) printf("%c", (char)c); else printf("\\x{%02x}", c);
138  }  }
139  #endif  #endif
140    
# Line 150  match_ref(int offset, register PCRE_PUCH Line 167  match_ref(int offset, register PCRE_PUCH
167  {  {
168  PCRE_PUCHAR eptr_start = eptr;  PCRE_PUCHAR eptr_start = eptr;
169  register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset];  register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset];
170    #ifdef SUPPORT_UTF
171    BOOL utf = md->utf;
172    #endif
173    
174  #ifdef PCRE_DEBUG  #ifdef PCRE_DEBUG
175  if (eptr >= md->end_subject)  if (eptr >= md->end_subject)
# Line 177  if (caseless) Line 197  if (caseless)
197    {    {
198  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
199  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
200    if (md->utf)    if (utf)
201      {      {
202      /* Match characters up to the end of the reference. NOTE: the number of      /* Match characters up to the end of the reference. NOTE: the number of
203      data units matched may differ, because in UTF-8 there are some characters      data units matched may differ, because in UTF-8 there are some characters
# Line 191  if (caseless) Line 211  if (caseless)
211      PCRE_PUCHAR endptr = p + length;      PCRE_PUCHAR endptr = p + length;
212      while (p < endptr)      while (p < endptr)
213        {        {
214        unsigned int c, d;        pcre_uint32 c, d;
215        const ucd_record *ur;        const ucd_record *ur;
216        if (eptr >= md->end_subject) return -2;   /* Partial match */        if (eptr >= md->end_subject) return -2;   /* Partial match */
217        GETCHARINC(c, eptr);        GETCHARINC(c, eptr);
218        GETCHARINC(d, p);        GETCHARINC(d, p);
219        ur = GET_UCD(d);        ur = GET_UCD(d);
220        if (c != d && c != d + ur->other_case)        if (c != d && c != d + ur->other_case)
221          {          {
222          const pcre_uint32 *pp = PRIV(ucd_caseless_sets) + ur->caseset;          const pcre_uint32 *pp = PRIV(ucd_caseless_sets) + ur->caseset;
223          for (;;)          for (;;)
224            {            {
225            if (c < *pp) return -1;            if (c < *pp) return -1;
# Line 217  if (caseless) Line 237  if (caseless)
237      {      {
238      while (length-- > 0)      while (length-- > 0)
239        {        {
240          pcre_uint32 cc, cp;
241        if (eptr >= md->end_subject) return -2;   /* Partial match */        if (eptr >= md->end_subject) return -2;   /* Partial match */
242        if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1;        cc = RAWUCHARTEST(eptr);
243          cp = RAWUCHARTEST(p);
244          if (TABLE_GET(cp, md->lcc, cp) != TABLE_GET(cc, md->lcc, cc)) return -1;
245        p++;        p++;
246        eptr++;        eptr++;
247        }        }
# Line 233  else Line 256  else
256    while (length-- > 0)    while (length-- > 0)
257      {      {
258      if (eptr >= md->end_subject) return -2;   /* Partial match */      if (eptr >= md->end_subject) return -2;   /* Partial match */
259      if (*p++ != *eptr++) return -1;      if (RAWUCHARINCTEST(p) != RAWUCHARINCTEST(eptr)) return -1;
260      }      }
261    }    }
262    
# Line 289  enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM Line 312  enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM
312         RM31,  RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,         RM31,  RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
313         RM41,  RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,         RM41,  RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,
314         RM51,  RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60,         RM51,  RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60,
315         RM61,  RM62, RM63, RM64, RM65, RM66 };         RM61,  RM62, RM63, RM64, RM65, RM66, RM67, RM68 };
316    
317  /* 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
318  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 307  actually used in this definition. */ Line 330  actually used in this definition. */
330    }    }
331  #define RRETURN(ra) \  #define RRETURN(ra) \
332    { \    { \
333    printf("match() returned %d from line %d ", ra, __LINE__); \    printf("match() returned %d from line %d\n", ra, __LINE__); \
334    return ra; \    return ra; \
335    }    }
336  #else  #else
# Line 398  typedef struct heapframe { Line 421  typedef struct heapframe {
421    
422  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
423    int Xprop_type;    int Xprop_type;
424    int Xprop_value;    unsigned int Xprop_value;
425    int Xprop_fail_result;    int Xprop_fail_result;
426    int Xoclength;    int Xoclength;
427    pcre_uchar Xocchars[6];    pcre_uchar Xocchars[6];
# Line 411  typedef struct heapframe { Line 434  typedef struct heapframe {
434    int Xlength;    int Xlength;
435    int Xmax;    int Xmax;
436    int Xmin;    int Xmin;
437    int Xnumber;    unsigned int Xnumber;
438    int Xoffset;    int Xoffset;
439    int Xop;    unsigned int Xop;
440    int Xsave_capture_last;    pcre_int32 Xsave_capture_last;
441    int Xsave_offset1, Xsave_offset2, Xsave_offset3;    int Xsave_offset1, Xsave_offset2, Xsave_offset3;
442    int Xstacksave[REC_STACK_SAVE_MAX];    int Xstacksave[REC_STACK_SAVE_MAX];
443    
# Line 499  so they can be ordinary variables in all Line 522  so they can be ordinary variables in all
522    
523  register int  rrc;         /* Returns from recursive calls */  register int  rrc;         /* Returns from recursive calls */
524  register int  i;           /* Used for loops not involving calls to RMATCH() */  register int  i;           /* Used for loops not involving calls to RMATCH() */
525  register unsigned int c;   /* Character values not kept over RMATCH() calls */  register pcre_uint32 c;    /* Character values not kept over RMATCH() calls */
526  register BOOL utf;         /* Local copy of UTF flag for speed */  register BOOL utf;         /* Local copy of UTF flag for speed */
527    
528  BOOL minimize, possessive; /* Quantifier options */  BOOL minimize, possessive; /* Quantifier options */
# Line 616  BOOL prev_is_word; Line 639  BOOL prev_is_word;
639    
640  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
641  int prop_type;  int prop_type;
642  int prop_value;  unsigned int prop_value;
643  int prop_fail_result;  int prop_fail_result;
644  int oclength;  int oclength;
645  pcre_uchar occhars[6];  pcre_uchar occhars[6];
# Line 627  int ctype; Line 650  int ctype;
650  int length;  int length;
651  int max;  int max;
652  int min;  int min;
653  int number;  unsigned int number;
654  int offset;  int offset;
655  int op;  unsigned int op;
656  int save_capture_last;  pcre_int32 save_capture_last;
657  int save_offset1, save_offset2, save_offset3;  int save_offset1, save_offset2, save_offset3;
658  int stacksave[REC_STACK_SAVE_MAX];  int stacksave[REC_STACK_SAVE_MAX];
659    
# Line 748  for (;;) Line 771  for (;;)
771      unaltered. */      unaltered. */
772    
773      else if (rrc == MATCH_SKIP_ARG &&      else if (rrc == MATCH_SKIP_ARG &&
774          STRCMP_UC_UC(ecode + 2, md->start_match_ptr) == 0)          STRCMP_UC_UC_TEST(ecode + 2, md->start_match_ptr) == 0)
775        {        {
776        md->start_match_ptr = eptr;        md->start_match_ptr = eptr;
777        RRETURN(MATCH_SKIP);        RRETURN(MATCH_SKIP);
# Line 758  for (;;) Line 781  for (;;)
781      case OP_FAIL:      case OP_FAIL:
782      RRETURN(MATCH_NOMATCH);      RRETURN(MATCH_NOMATCH);
783    
     /* COMMIT overrides PRUNE, SKIP, and THEN */  
   
784      case OP_COMMIT:      case OP_COMMIT:
785      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
786        eptrb, RM52);        eptrb, RM52);
787      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
         rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&  
         rrc != MATCH_THEN)  
       RRETURN(rrc);  
788      RRETURN(MATCH_COMMIT);      RRETURN(MATCH_COMMIT);
789    
     /* PRUNE overrides THEN */  
   
790      case OP_PRUNE:      case OP_PRUNE:
791      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
792        eptrb, RM51);        eptrb, RM51);
793      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
794      RRETURN(MATCH_PRUNE);      RRETURN(MATCH_PRUNE);
795    
796      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
# Line 784  for (;;) Line 800  for (;;)
800        eptrb, RM56);        eptrb, RM56);
801      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
802           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
803      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
804      RRETURN(MATCH_PRUNE);      RRETURN(MATCH_PRUNE);
805    
     /* SKIP overrides PRUNE and THEN */  
   
806      case OP_SKIP:      case OP_SKIP:
807      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
808        eptrb, RM53);        eptrb, RM53);
809      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
       RRETURN(rrc);  
810      md->start_match_ptr = eptr;   /* Pass back current position */      md->start_match_ptr = eptr;   /* Pass back current position */
811      RRETURN(MATCH_SKIP);      RRETURN(MATCH_SKIP);
812    
813      /* Note that, for Perl compatibility, SKIP with an argument does NOT set      /* Note that, for Perl compatibility, SKIP with an argument does NOT set
814      nomatch_mark. There is a flag that disables this opcode when re-matching a      nomatch_mark. When a pattern match ends with a SKIP_ARG for which there was
815      pattern that ended with a SKIP for which there was not a matching MARK. */      not a matching mark, we have to re-run the match, ignoring the SKIP_ARG
816        that failed and any that precede it (either they also failed, or were not
817        triggered). To do this, we maintain a count of executed SKIP_ARGs. If a
818        SKIP_ARG gets to top level, the match is re-run with md->ignore_skip_arg
819        set to the count of the one that failed. */
820    
821      case OP_SKIP_ARG:      case OP_SKIP_ARG:
822      if (md->ignore_skip_arg)      md->skip_arg_count++;
823        if (md->skip_arg_count <= md->ignore_skip_arg)
824        {        {
825        ecode += PRIV(OP_lengths)[*ecode] + ecode[1];        ecode += PRIV(OP_lengths)[*ecode] + ecode[1];
826        break;        break;
827        }        }
828      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
829        eptrb, RM57);        eptrb, RM57);
830      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
       RRETURN(rrc);  
831    
832      /* Pass back the current skip name by overloading md->start_match_ptr and      /* Pass back the current skip name by overloading md->start_match_ptr and
833      returning the special MATCH_SKIP_ARG return code. This will either be      returning the special MATCH_SKIP_ARG return code. This will either be
834      caught by a matching MARK, or get to the top, where it causes a rematch      caught by a matching MARK, or get to the top, where it causes a rematch
835      with the md->ignore_skip_arg flag set. */      with md->ignore_skip_arg set to the value of md->skip_arg_count. */
836    
837      md->start_match_ptr = ecode + 2;      md->start_match_ptr = ecode + 2;
838      RRETURN(MATCH_SKIP_ARG);      RRETURN(MATCH_SKIP_ARG);
# Line 1061  for (;;) Line 1078  for (;;)
1078        /* In all other cases, we have to make another call to match(). */        /* In all other cases, we have to make another call to match(). */
1079    
1080        save_mark = md->mark;        save_mark = md->mark;
1081          save_capture_last = md->capture_last;
1082        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
1083          RM2);          RM2);
1084    
# Line 1092  for (;;) Line 1110  for (;;)
1110        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1111        md->mark = save_mark;        md->mark = save_mark;
1112        if (*ecode != OP_ALT) break;        if (*ecode != OP_ALT) break;
1113          md->capture_last = save_capture_last;
1114        }        }
1115    
1116      RRETURN(MATCH_NOMATCH);      RRETURN(MATCH_NOMATCH);
# Line 1213  for (;;) Line 1232  for (;;)
1232      POSSESSIVE_NON_CAPTURE:      POSSESSIVE_NON_CAPTURE:
1233      matched_once = FALSE;      matched_once = FALSE;
1234      code_offset = (int)(ecode - md->start_code);      code_offset = (int)(ecode - md->start_code);
1235        save_capture_last = md->capture_last;
1236    
1237      for (;;)      for (;;)
1238        {        {
# Line 1242  for (;;) Line 1262  for (;;)
1262        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1263        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1264        if (*ecode != OP_ALT) break;        if (*ecode != OP_ALT) break;
1265          md->capture_last = save_capture_last;
1266        }        }
1267    
1268      if (matched_once || allow_zero)      if (matched_once || allow_zero)
# Line 1286  for (;;) Line 1307  for (;;)
1307          cb.pattern_position = GET(ecode, LINK_SIZE + 3);          cb.pattern_position = GET(ecode, LINK_SIZE + 3);
1308          cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);          cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);
1309          cb.capture_top      = offset_top/2;          cb.capture_top      = offset_top/2;
1310          cb.capture_last     = md->capture_last;          cb.capture_last     = md->capture_last & CAPLMASK;
1311            /* Internal change requires this for API compatibility. */
1312            if (cb.capture_last == 0) cb.capture_last = -1;
1313          cb.callout_data     = md->callout_data;          cb.callout_data     = md->callout_data;
1314          cb.mark             = md->nomatch_mark;          cb.mark             = md->nomatch_mark;
1315          if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);          if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1316          if (rrc < 0) RRETURN(rrc);          if (rrc < 0) RRETURN(rrc);
1317          }          }
1318        ecode += PRIV(OP_lengths)[OP_CALLOUT];        ecode += PRIV(OP_lengths)[OP_CALLOUT];
1319          codelink -= PRIV(OP_lengths)[OP_CALLOUT];
1320        }        }
1321    
1322      condcode = ecode[LINK_SIZE+1];      condcode = ecode[LINK_SIZE+1];
# Line 1308  for (;;) Line 1332  for (;;)
1332          }          }
1333        else        else
1334          {          {
1335          int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/          unsigned int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/
1336          condition = (recno == RREF_ANY || recno == md->recursive->group_num);          condition = (recno == RREF_ANY || recno == md->recursive->group_num);
1337    
1338          /* If the test is for recursion into a specific subpattern, and it is          /* If the test is for recursion into a specific subpattern, and it is
# Line 1380  for (;;) Line 1404  for (;;)
1404    
1405        if (!condition && condcode == OP_NCREF)        if (!condition && condcode == OP_NCREF)
1406          {          {
1407          int refno = offset >> 1;          unsigned int refno = offset >> 1;
1408          pcre_uchar *slotA = md->name_table;          pcre_uchar *slotA = md->name_table;
1409    
1410          for (i = 0; i < md->name_count; i++)          for (i = 0; i < md->name_count; i++)
# Line 1508  for (;;) Line 1532  for (;;)
1532      to close any currently open capturing brackets. */      to close any currently open capturing brackets. */
1533    
1534      case OP_CLOSE:      case OP_CLOSE:
1535      number = GET2(ecode, 1);      number = GET2(ecode, 1);   /* Must be less than 65536 */
1536      offset = number << 1;      offset = number << 1;
1537    
1538  #ifdef PCRE_DEBUG  #ifdef PCRE_DEBUG
# Line 1516  for (;;) Line 1540  for (;;)
1540        printf("\n");        printf("\n");
1541  #endif  #endif
1542    
1543      md->capture_last = number;      md->capture_last = (md->capture_last & OVFLMASK) | number;
1544      if (offset >= md->offset_max) md->offset_overflow = TRUE; else      if (offset >= md->offset_max) md->capture_last |= OVFLBIT; else
1545        {        {
1546        md->offset_vector[offset] =        md->offset_vector[offset] =
1547          md->offset_vector[md->offset_end - number];          md->offset_vector[md->offset_end - number];
# Line 1579  for (;;) Line 1603  for (;;)
1603        }        }
1604      else condassert = FALSE;      else condassert = FALSE;
1605    
1606        /* Loop for each branch */
1607    
1608      do      do
1609        {        {
1610        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM4);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM4);
1611    
1612          /* A match means that the assertion is true; break out of the loop
1613          that matches its alternatives. */
1614    
1615        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
1616          {          {
1617          mstart = md->start_match_ptr;   /* In case \K reset it */          mstart = md->start_match_ptr;   /* In case \K reset it */
1618          break;          break;
1619          }          }
1620    
1621          /* If not matched, restore the previous mark setting. */
1622    
1623        md->mark = save_mark;        md->mark = save_mark;
1624    
1625        /* A COMMIT failure must fail the entire assertion, without trying any        /* See comment in the code for capturing groups above about handling
1626        subsequent branches. */        THEN. */
1627    
1628        if (rrc == MATCH_COMMIT) RRETURN(MATCH_NOMATCH);        if (rrc == MATCH_THEN)
1629            {
1630            next = ecode + GET(ecode,1);
1631            if (md->start_match_ptr < next &&
1632                (*ecode == OP_ALT || *next == OP_ALT))
1633              rrc = MATCH_NOMATCH;
1634            }
1635    
1636        /* PCRE does not allow THEN to escape beyond an assertion; it        /* Anything other than NOMATCH causes the entire assertion to fail,
1637        is treated as NOMATCH. */        passing back the return code. This includes COMMIT, SKIP, PRUNE and an
1638          uncaptured THEN, which means they take their normal effect. This
1639          consistent approach does not always have exactly the same effect as in
1640          Perl. */
1641    
1642        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1643        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1644        }        }
1645      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);   /* Continue for next alternative */
1646    
1647        /* If we have tried all the alternative branches, the assertion has
1648        failed. If not, we broke out after a match. */
1649    
1650      if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);      if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);
1651    
# Line 1608  for (;;) Line 1653  for (;;)
1653    
1654      if (condassert) RRETURN(MATCH_MATCH);      if (condassert) RRETURN(MATCH_MATCH);
1655    
1656      /* Continue from after the assertion, updating the offsets high water      /* Continue from after a successful assertion, updating the offsets high
1657      mark, since extracts may have been taken during the assertion. */      water mark, since extracts may have been taken during the assertion. */
1658    
1659      do ecode += GET(ecode,1); while (*ecode == OP_ALT);      do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1660      ecode += 1 + LINK_SIZE;      ecode += 1 + LINK_SIZE;
1661      offset_top = md->end_offset_top;      offset_top = md->end_offset_top;
1662      continue;      continue;
1663    
1664      /* Negative assertion: all branches must fail to match. Encountering SKIP,      /* Negative assertion: all branches must fail to match for the assertion to
1665      PRUNE, or COMMIT means we must assume failure without checking subsequent      succeed. */
     branches. */  
1666    
1667      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1668      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
# Line 1630  for (;;) Line 1674  for (;;)
1674        }        }
1675      else condassert = FALSE;      else condassert = FALSE;
1676    
1677        /* Loop for each alternative branch. */
1678    
1679      do      do
1680        {        {
1681        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);
1682        md->mark = save_mark;        md->mark = save_mark;   /* Always restore the mark setting */
1683        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);  
1684        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)        switch(rrc)
1685          {          {
1686          do ecode += GET(ecode,1); while (*ecode == OP_ALT);          case MATCH_MATCH:            /* A successful match means */
1687            case MATCH_ACCEPT:           /* the assertion has failed. */
1688            RRETURN(MATCH_NOMATCH);
1689    
1690            case MATCH_NOMATCH:          /* Carry on with next branch */
1691          break;          break;
1692    
1693            /* See comment in the code for capturing groups above about handling
1694            THEN. */
1695    
1696            case MATCH_THEN:
1697            next = ecode + GET(ecode,1);
1698            if (md->start_match_ptr < next &&
1699                (*ecode == OP_ALT || *next == OP_ALT))
1700              {
1701              rrc = MATCH_NOMATCH;
1702              break;
1703              }
1704            /* Otherwise fall through. */
1705    
1706            /* COMMIT, SKIP, PRUNE, and an uncaptured THEN cause the whole
1707            assertion to fail to match, without considering any more alternatives.
1708            Failing to match means the assertion is true. This is a consistent
1709            approach, but does not always have the same effect as in Perl. */
1710    
1711            case MATCH_COMMIT:
1712            case MATCH_SKIP:
1713            case MATCH_SKIP_ARG:
1714            case MATCH_PRUNE:
1715            do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1716            goto NEG_ASSERT_TRUE;   /* Break out of alternation loop */
1717    
1718            /* Anything else is an error */
1719    
1720            default:
1721            RRETURN(rrc);
1722          }          }
1723    
1724        /* PCRE does not allow THEN to escape beyond an assertion; it is treated        /* Continue with next branch */
       as NOMATCH. */  
1725    
       if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);  
1726        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1727        }        }
1728      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
1729    
1730      if (condassert) RRETURN(MATCH_MATCH);  /* Condition assertion */      /* All branches in the assertion failed to match. */
1731    
1732      ecode += 1 + LINK_SIZE;      NEG_ASSERT_TRUE:
1733        if (condassert) RRETURN(MATCH_MATCH);  /* Condition assertion */
1734        ecode += 1 + LINK_SIZE;                /* Continue with current branch */
1735      continue;      continue;
1736    
1737      /* Move the subject pointer back. This occurs only at the start of      /* Move the subject pointer back. This occurs only at the start of
# Line 1711  for (;;) Line 1791  for (;;)
1791        cb.pattern_position = GET(ecode, 2);        cb.pattern_position = GET(ecode, 2);
1792        cb.next_item_length = GET(ecode, 2 + LINK_SIZE);        cb.next_item_length = GET(ecode, 2 + LINK_SIZE);
1793        cb.capture_top      = offset_top/2;        cb.capture_top      = offset_top/2;
1794        cb.capture_last     = md->capture_last;        cb.capture_last     = md->capture_last & CAPLMASK;
1795          /* Internal change requires this for API compatibility. */
1796          if (cb.capture_last == 0) cb.capture_last = -1;
1797        cb.callout_data     = md->callout_data;        cb.callout_data     = md->callout_data;
1798        cb.mark             = md->nomatch_mark;        cb.mark             = md->nomatch_mark;
1799        if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);        if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
# Line 1740  for (;;) Line 1822  for (;;)
1822      case OP_RECURSE:      case OP_RECURSE:
1823        {        {
1824        recursion_info *ri;        recursion_info *ri;
1825        int recno;        unsigned int recno;
1826    
1827        callpat = md->start_code + GET(ecode, 1);        callpat = md->start_code + GET(ecode, 1);
1828        recno = (callpat == md->start_code)? 0 :        recno = (callpat == md->start_code)? 0 :
# Line 1757  for (;;) Line 1839  for (;;)
1839        /* Add to "recursing stack" */        /* Add to "recursing stack" */
1840    
1841        new_recursive.group_num = recno;        new_recursive.group_num = recno;
1842          new_recursive.saved_capture_last = md->capture_last;
1843        new_recursive.subject_position = eptr;        new_recursive.subject_position = eptr;
1844        new_recursive.prevrec = md->recursive;        new_recursive.prevrec = md->recursive;
1845        md->recursive = &new_recursive;        md->recursive = &new_recursive;
# Line 1780  for (;;) Line 1863  for (;;)
1863              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
1864    
1865        /* OK, now we can do the recursion. After processing each alternative,        /* OK, now we can do the recursion. After processing each alternative,
1866        restore the offset data. If there were nested recursions, md->recursive        restore the offset data and the last captured value. If there were nested
1867        might be changed, so reset it before looping. */        recursions, md->recursive might be changed, so reset it before looping.
1868          */
1869    
1870        DPRINTF(("Recursing into group %d\n", new_recursive.group_num));        DPRINTF(("Recursing into group %d\n", new_recursive.group_num));
1871        cbegroup = (*callpat >= OP_SBRA);        cbegroup = (*callpat >= OP_SBRA);
# Line 1792  for (;;) Line 1876  for (;;)
1876            md, eptrb, RM6);            md, eptrb, RM6);
1877          memcpy(md->offset_vector, new_recursive.offset_save,          memcpy(md->offset_vector, new_recursive.offset_save,
1878              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
1879            md->capture_last = new_recursive.saved_capture_last;
1880          md->recursive = new_recursive.prevrec;          md->recursive = new_recursive.prevrec;
1881          if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)          if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
1882            {            {
# Line 1808  for (;;) Line 1893  for (;;)
1893            goto RECURSION_MATCHED;        /* Exit loop; end processing */            goto RECURSION_MATCHED;        /* Exit loop; end processing */
1894            }            }
1895    
1896          /* PCRE does not allow THEN or COMMIT to escape beyond a recursion; it          /* PCRE does not allow THEN, SKIP, PRUNE or COMMIT to escape beyond a
1897          is treated as NOMATCH. */          recursion; they cause a NOMATCH for the entire recursion. These codes
1898            are defined in a range that can be tested for. */
1899    
1900            if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX)
1901              RRETURN(MATCH_NOMATCH);
1902    
1903            /* Any return code other than NOMATCH is an error. */
1904    
1905          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN &&          if (rrc != MATCH_NOMATCH)
                  rrc != MATCH_COMMIT)  
1906            {            {
1907            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1908            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
# Line 1942  for (;;) Line 2032  for (;;)
2032    
2033        /* Deal with capturing */        /* Deal with capturing */
2034    
2035        md->capture_last = number;        md->capture_last = (md->capture_last & OVFLMASK) | number;
2036        if (offset >= md->offset_max) md->offset_overflow = TRUE; else        if (offset >= md->offset_max) md->capture_last |= OVFLBIT; else
2037          {          {
2038          /* If offset is greater than offset_top, it means that we are          /* If offset is greater than offset_top, it means that we are
2039          "skipping" a capturing group, and that group's offsets must be marked          "skipping" a capturing group, and that group's offsets must be marked
# Line 2094  for (;;) Line 2184  for (;;)
2184              eptr + 1 >= md->end_subject &&              eptr + 1 >= md->end_subject &&
2185              NLBLOCK->nltype == NLTYPE_FIXED &&              NLBLOCK->nltype == NLTYPE_FIXED &&
2186              NLBLOCK->nllen == 2 &&              NLBLOCK->nllen == 2 &&
2187              *eptr == NLBLOCK->nl[0])              RAWUCHARTEST(eptr) == NLBLOCK->nl[0])
2188            {            {
2189            md->hitend = TRUE;            md->hitend = TRUE;
2190            if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);            if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
# Line 2138  for (;;) Line 2228  for (;;)
2228            eptr + 1 >= md->end_subject &&            eptr + 1 >= md->end_subject &&
2229            NLBLOCK->nltype == NLTYPE_FIXED &&            NLBLOCK->nltype == NLTYPE_FIXED &&
2230            NLBLOCK->nllen == 2 &&            NLBLOCK->nllen == 2 &&
2231            *eptr == NLBLOCK->nl[0])            RAWUCHARTEST(eptr) == NLBLOCK->nl[0])
2232          {          {
2233          md->hitend = TRUE;          md->hitend = TRUE;
2234          if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);          if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
# Line 2281  for (;;) Line 2371  for (;;)
2371          eptr + 1 >= md->end_subject &&          eptr + 1 >= md->end_subject &&
2372          NLBLOCK->nltype == NLTYPE_FIXED &&          NLBLOCK->nltype == NLTYPE_FIXED &&
2373          NLBLOCK->nllen == 2 &&          NLBLOCK->nllen == 2 &&
2374          *eptr == NLBLOCK->nl[0])          RAWUCHARTEST(eptr) == NLBLOCK->nl[0])
2375        {        {
2376        md->hitend = TRUE;        md->hitend = TRUE;
2377        if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);        if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
# Line 2435  for (;;) Line 2525  for (;;)
2525          {          {
2526          SCHECK_PARTIAL();          SCHECK_PARTIAL();
2527          }          }
2528        else if (*eptr == CHAR_LF) eptr++;        else if (RAWUCHARTEST(eptr) == CHAR_LF) eptr++;
2529        break;        break;
2530    
2531        case CHAR_LF:        case CHAR_LF:
# Line 2527  for (;;) Line 2617  for (;;)
2617        }        }
2618      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2619        {        {
2620        const pcre_uint32 *cp;        const pcre_uint32 *cp;
2621        const ucd_record *prop = GET_UCD(c);        const ucd_record *prop = GET_UCD(c);
2622    
2623        switch(ecode[1])        switch(ecode[1])
# Line 2589  for (;;) Line 2679  for (;;)
2679          break;          break;
2680    
2681          case PT_CLIST:          case PT_CLIST:
2682          cp = PRIV(ucd_caseless_sets) + prop->caseset;          cp = PRIV(ucd_caseless_sets) + ecode[2];
2683          for (;;)          for (;;)
2684            {            {
2685            if (c < *cp)            if (c < *cp)
# Line 2599  for (;;) Line 2689  for (;;)
2689            }            }
2690          break;          break;
2691    
2692            case PT_UCNC:
2693            if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
2694                 c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
2695                 c >= 0xe000) == (op == OP_NOTPROP))
2696              RRETURN(MATCH_NOMATCH);
2697            break;
2698    
2699          /* This should never occur */          /* This should never occur */
2700    
2701          default:          default:
# Line 2645  for (;;) Line 2742  for (;;)
2742      similar code to character type repeats - written out again for speed.      similar code to character type repeats - written out again for speed.
2743      However, if the referenced string is the empty string, always treat      However, if the referenced string is the empty string, always treat
2744      it as matched, any number of times (otherwise there could be infinite      it as matched, any number of times (otherwise there could be infinite
2745      loops). */      loops). If the reference is unset, there are two possibilities:
   
     case OP_REF:  
     case OP_REFI:  
     caseless = op == OP_REFI;  
     offset = GET2(ecode, 1) << 1;               /* Doubled ref number */  
     ecode += 1 + IMM2_SIZE;  
   
     /* If the reference is unset, there are two possibilities:  
2746    
2747      (a) In the default, Perl-compatible state, set the length negative;      (a) In the default, Perl-compatible state, set the length negative;
2748      this ensures that every attempt at a match fails. We can't just fail      this ensures that every attempt at a match fails. We can't just fail
# Line 2663  for (;;) Line 2752  for (;;)
2752      so that the back reference matches an empty string.      so that the back reference matches an empty string.
2753    
2754      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
2755      referenced subpattern. */      referenced subpattern.
2756    
2757        The OP_REF and OP_REFI opcodes are used for a reference to a numbered group
2758        or to a non-duplicated named group. For a duplicated named group, OP_DNREF
2759        and OP_DNREFI are used. In this case we must scan the list of groups to
2760        which the name refers, and use the first one that is set. */
2761    
2762        case OP_DNREF:
2763        case OP_DNREFI:
2764        caseless = op == OP_DNREFI;
2765          {
2766          int count = GET2(ecode, 1+IMM2_SIZE);
2767          pcre_uchar *slot = md->name_table + GET2(ecode, 1) * md->name_entry_size;
2768          ecode += 1 + 2*IMM2_SIZE;
2769    
2770          while (count-- > 0)
2771            {
2772            offset = GET2(slot, 0) << 1;
2773            if (offset < offset_top && md->offset_vector[offset] >= 0) break;
2774            slot += md->name_entry_size;
2775            }
2776          if (count < 0)
2777            length = (md->jscript_compat)? 0 : -1;
2778          else
2779            length = md->offset_vector[offset+1] - md->offset_vector[offset];
2780          }
2781        goto REF_REPEAT;
2782    
2783        case OP_REF:
2784        case OP_REFI:
2785        caseless = op == OP_REFI;
2786        offset = GET2(ecode, 1) << 1;               /* Doubled ref number */
2787        ecode += 1 + IMM2_SIZE;
2788    
2789    
2790      if (offset >= offset_top || md->offset_vector[offset] < 0)      if (offset >= offset_top || md->offset_vector[offset] < 0)
2791        length = (md->jscript_compat)? 0 : -1;        length = (md->jscript_compat)? 0 : -1;
# Line 2672  for (;;) Line 2794  for (;;)
2794    
2795      /* Set up for repetition, or handle the non-repeated case */      /* Set up for repetition, or handle the non-repeated case */
2796    
2797        REF_REPEAT:
2798      switch (*ecode)      switch (*ecode)
2799        {        {
2800        case OP_CRSTAR:        case OP_CRSTAR:
# Line 3145  for (;;) Line 3268  for (;;)
3268          CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */          CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
3269          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3270          }          }
3271        while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);        while (length-- > 0) if (*ecode++ != RAWUCHARINC(eptr)) RRETURN(MATCH_NOMATCH);
3272        }        }
3273      else      else
3274  #endif  #endif
# Line 3185  for (;;) Line 3308  for (;;)
3308    
3309        if (fc < 128)        if (fc < 128)
3310          {          {
3311          if (md->lcc[fc]          pcre_uint32 cc = RAWUCHAR(eptr);
3312              != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);          if (md->lcc[fc] != TABLE_GET(cc, md->lcc, cc)) RRETURN(MATCH_NOMATCH);
3313          ecode++;          ecode++;
3314          eptr++;          eptr++;
3315          }          }
# Line 3197  for (;;) Line 3320  for (;;)
3320    
3321        else        else
3322          {          {
3323          unsigned int dc;          pcre_uint32 dc;
3324          GETCHARINC(dc, eptr);          GETCHARINC(dc, eptr);
3325          ecode += length;          ecode += length;
3326    
# Line 3290  for (;;) Line 3413  for (;;)
3413      max = rep_max[c];                 /* zero for max => infinity */      max = rep_max[c];                 /* zero for max => infinity */
3414      if (max == 0) max = INT_MAX;      if (max == 0) max = INT_MAX;
3415    
3416      /* Common code for all repeated single-character matches. */      /* Common code for all repeated single-character matches. We first check
3417        for the minimum number of characters. If the minimum equals the maximum, we
3418        are done. Otherwise, if minimizing, check the rest of the pattern for a
3419        match; if there isn't one, advance up to the maximum, one character at a
3420        time.
3421    
3422        If maximizing, advance up to the maximum number of matching characters,
3423        until eptr is past the end of the maximum run. If possessive, we are
3424        then done (no backing up). Otherwise, match at this position; anything
3425        other than no match is immediately returned. For nomatch, back up one
3426        character, unless we are matching \R and the last thing matched was
3427        \r\n, in which case, back up two bytes. When we reach the first optional
3428        character position, we can save stack by doing a tail recurse.
3429    
3430        The various UTF/non-UTF and caseful/caseless cases are handled separately,
3431        for speed. */
3432    
3433      REPEATCHAR:      REPEATCHAR:
3434  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 3307  for (;;) Line 3445  for (;;)
3445        if (length > 1)        if (length > 1)
3446          {          {
3447  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3448          unsigned int othercase;          pcre_uint32 othercase;
3449          if (op >= OP_STARI &&     /* Caseless */          if (op >= OP_STARI &&     /* Caseless */
3450              (othercase = UCD_OTHERCASE(fc)) != fc)              (othercase = UCD_OTHERCASE(fc)) != fc)
3451            oclength = PRIV(ord2utf)(othercase, occhars);            oclength = PRIV(ord2utf)(othercase, occhars);
# Line 3374  for (;;) Line 3512  for (;;)
3512                }                }
3513              }              }
3514    
3515            if (possessive) continue;            if (possessive) continue;    /* No backtracking */
   
3516            for(;;)            for(;;)
3517              {              {
3518                if (eptr == pp) goto TAIL_RECURSE;
3519              RMATCH(eptr, ecode, offset_top, md, eptrb, RM23);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM23);
3520              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
             if (eptr == pp) { RRETURN(MATCH_NOMATCH); }  
3521  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3522              eptr--;              eptr--;
3523              BACKCHAR(eptr);              BACKCHAR(eptr);
# Line 3434  for (;;) Line 3571  for (;;)
3571    
3572        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
3573          {          {
3574            pcre_uint32 cc;                 /* Faster than pcre_uchar */
3575          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
3576            {            {
3577            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3578            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3579            }            }
3580          if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);          cc = RAWUCHARTEST(eptr);
3581            if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH);
3582          eptr++;          eptr++;
3583          }          }
3584        if (min == max) continue;        if (min == max) continue;
# Line 3447  for (;;) Line 3586  for (;;)
3586          {          {
3587          for (fi = min;; fi++)          for (fi = min;; fi++)
3588            {            {
3589              pcre_uint32 cc;               /* Faster than pcre_uchar */
3590            RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);
3591            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3592            if (fi >= max) RRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
# Line 3455  for (;;) Line 3595  for (;;)
3595              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3596              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3597              }              }
3598            if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);            cc = RAWUCHARTEST(eptr);
3599              if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH);
3600            eptr++;            eptr++;
3601            }            }
3602          /* Control never gets here */          /* Control never gets here */
# Line 3465  for (;;) Line 3606  for (;;)
3606          pp = eptr;          pp = eptr;
3607          for (i = min; i < max; i++)          for (i = min; i < max; i++)
3608            {            {
3609              pcre_uint32 cc;               /* Faster than pcre_uchar */
3610            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3611              {              {
3612              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3613              break;              break;
3614              }              }
3615            if (fc != *eptr && foc != *eptr) break;            cc = RAWUCHARTEST(eptr);
3616              if (fc != cc && foc != cc) break;
3617            eptr++;            eptr++;
3618            }            }
3619            if (possessive) continue;       /* No backtracking */
3620          if (possessive) continue;          for (;;)
   
         while (eptr >= pp)  
3621            {            {
3622              if (eptr == pp) goto TAIL_RECURSE;
3623            RMATCH(eptr, ecode, offset_top, md, eptrb, RM25);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM25);
3624            eptr--;            eptr--;
3625            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3626            }            }
3627          RRETURN(MATCH_NOMATCH);          /* Control never gets here */
3628          }          }
       /* Control never gets here */  
3629        }        }
3630    
3631      /* Caseful comparisons (includes all multi-byte characters) */      /* Caseful comparisons (includes all multi-byte characters) */
# Line 3498  for (;;) Line 3639  for (;;)
3639            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3640            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3641            }            }
3642          if (fc != *eptr++) RRETURN(MATCH_NOMATCH);          if (fc != RAWUCHARINCTEST(eptr)) RRETURN(MATCH_NOMATCH);
3643          }          }
3644    
3645        if (min == max) continue;        if (min == max) continue;
# Line 3515  for (;;) Line 3656  for (;;)
3656              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3657              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3658              }              }
3659            if (fc != *eptr++) RRETURN(MATCH_NOMATCH);            if (fc != RAWUCHARINCTEST(eptr)) RRETURN(MATCH_NOMATCH);
3660            }            }
3661          /* Control never gets here */          /* Control never gets here */
3662          }          }
# Line 3529  for (;;) Line 3670  for (;;)
3670              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3671              break;              break;
3672              }              }
3673            if (fc != *eptr) break;            if (fc != RAWUCHARTEST(eptr)) break;
3674            eptr++;            eptr++;
3675            }            }
3676          if (possessive) continue;          if (possessive) continue;    /* No backtracking */
3677            for (;;)
         while (eptr >= pp)  
3678            {            {
3679              if (eptr == pp) goto TAIL_RECURSE;
3680            RMATCH(eptr, ecode, offset_top, md, eptrb, RM27);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM27);
3681            eptr--;            eptr--;
3682            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3683            }            }
3684          RRETURN(MATCH_NOMATCH);          /* Control never gets here */
3685          }          }
3686        }        }
3687      /* Control never gets here */      /* Control never gets here */
# Line 3558  for (;;) Line 3699  for (;;)
3699  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3700      if (utf)      if (utf)
3701        {        {
3702        register unsigned int ch, och;        register pcre_uint32 ch, och;
3703    
3704        ecode++;        ecode++;
3705        GETCHARINC(ch, ecode);        GETCHARINC(ch, ecode);
# Line 3585  for (;;) Line 3726  for (;;)
3726      else      else
3727  #endif  #endif
3728        {        {
3729        register unsigned int ch = ecode[1];        register pcre_uint32 ch = ecode[1];
3730        c = *eptr++;        c = *eptr++;
3731        if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c))        if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c))
3732          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
# Line 3699  for (;;) Line 3840  for (;;)
3840  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3841        if (utf)        if (utf)
3842          {          {
3843          register unsigned int d;          register pcre_uint32 d;
3844          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3845            {            {
3846            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
# Line 3712  for (;;) Line 3853  for (;;)
3853            }            }
3854          }          }
3855        else        else
3856  #endif  #endif  /* SUPPORT_UTF */
3857        /* Not UTF mode */        /* Not UTF mode */
3858          {          {
3859          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 3734  for (;;) Line 3875  for (;;)
3875  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3876          if (utf)          if (utf)
3877            {            {
3878            register unsigned int d;            register pcre_uint32 d;
3879            for (fi = min;; fi++)            for (fi = min;; fi++)
3880              {              {
3881              RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);
# Line 3750  for (;;) Line 3891  for (;;)
3891              }              }
3892            }            }
3893          else          else
3894  #endif  #endif  /*SUPPORT_UTF */
3895          /* Not UTF mode */          /* Not UTF mode */
3896            {            {
3897            for (fi = min;; fi++)            for (fi = min;; fi++)
# Line 3779  for (;;) Line 3920  for (;;)
3920  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3921          if (utf)          if (utf)
3922            {            {
3923            register unsigned int d;            register pcre_uint32 d;
3924            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3925              {              {
3926              int len = 1;              int len = 1;
# Line 3792  for (;;) Line 3933  for (;;)
3933              if (fc == d || (unsigned int)foc == d) break;              if (fc == d || (unsigned int)foc == d) break;
3934              eptr += len;              eptr += len;
3935              }              }
3936            if (possessive) continue;            if (possessive) continue;    /* No backtracking */
3937            for(;;)            for(;;)
3938              {              {
3939                if (eptr == pp) goto TAIL_RECURSE;
3940              RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);
3941              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3942              if (eptr-- == pp) break;        /* Stop if tried at original pos */              eptr--;
3943              BACKCHAR(eptr);              BACKCHAR(eptr);
3944              }              }
3945            }            }
3946          else          else
3947  #endif  #endif  /* SUPPORT_UTF */
3948          /* Not UTF mode */          /* Not UTF mode */
3949            {            {
3950            for (i = min; i < max; i++)            for (i = min; i < max; i++)
# Line 3815  for (;;) Line 3957  for (;;)
3957              if (fc == *eptr || foc == *eptr) break;              if (fc == *eptr || foc == *eptr) break;
3958              eptr++;              eptr++;
3959              }              }
3960            if (possessive) continue;            if (possessive) continue;    /* No backtracking */
3961            while (eptr >= pp)            for (;;)
3962              {              {
3963                if (eptr == pp) goto TAIL_RECURSE;
3964              RMATCH(eptr, ecode, offset_top, md, eptrb, RM31);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM31);
3965              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3966              eptr--;              eptr--;
3967              }              }
3968            }            }
3969            /* Control never gets here */
         RRETURN(MATCH_NOMATCH);  
3970          }          }
       /* Control never gets here */  
3971        }        }
3972    
3973      /* Caseful comparisons */      /* Caseful comparisons */
# Line 3836  for (;;) Line 3977  for (;;)
3977  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3978        if (utf)        if (utf)
3979          {          {
3980          register unsigned int d;          register pcre_uint32 d;
3981          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3982            {            {
3983            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
# Line 3870  for (;;) Line 4011  for (;;)
4011  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4012          if (utf)          if (utf)
4013            {            {
4014            register unsigned int d;            register pcre_uint32 d;
4015            for (fi = min;; fi++)            for (fi = min;; fi++)
4016              {              {
4017              RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);
# Line 3914  for (;;) Line 4055  for (;;)
4055  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4056          if (utf)          if (utf)
4057            {            {
4058            register unsigned int d;            register pcre_uint32 d;
4059            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4060              {              {
4061              int len = 1;              int len = 1;
# Line 3927  for (;;) Line 4068  for (;;)
4068              if (fc == d) break;              if (fc == d) break;
4069              eptr += len;              eptr += len;
4070              }              }
4071            if (possessive) continue;            if (possessive) continue;    /* No backtracking */
4072            for(;;)            for(;;)
4073              {              {
4074                if (eptr == pp) goto TAIL_RECURSE;
4075              RMATCH(eptr, ecode, offset_top, md, eptrb, RM34);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM34);
4076              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4077              if (eptr-- == pp) break;        /* Stop if tried at original pos */              eptr--;
4078              BACKCHAR(eptr);              BACKCHAR(eptr);
4079              }              }
4080            }            }
# Line 3950  for (;;) Line 4092  for (;;)
4092              if (fc == *eptr) break;              if (fc == *eptr) break;
4093              eptr++;              eptr++;
4094              }              }
4095            if (possessive) continue;            if (possessive) continue;    /* No backtracking */
4096            while (eptr >= pp)            for (;;)
4097              {              {
4098                if (eptr == pp) goto TAIL_RECURSE;
4099              RMATCH(eptr, ecode, offset_top, md, eptrb, RM35);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM35);
4100              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4101              eptr--;              eptr--;
4102              }              }
4103            }            }
4104            /* Control never gets here */
         RRETURN(MATCH_NOMATCH);  
4105          }          }
4106        }        }
4107      /* Control never gets here */      /* Control never gets here */
# Line 4189  for (;;) Line 4331  for (;;)
4331                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4332              }              }
4333            break;            break;
4334    
4335            case PT_CLIST:            case PT_CLIST:
4336            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
4337              {              {
4338              const pcre_uint32 *cp;              const pcre_uint32 *cp;
4339              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4340                {                {
# Line 4200  for (;;) Line 4342  for (;;)
4342                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4343                }                }
4344              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4345              cp = PRIV(ucd_caseless_sets) + UCD_CASESET(c);              cp = PRIV(ucd_caseless_sets) + prop_value;
4346              for (;;)              for (;;)
4347                {                {
4348                if (c < *cp)                if (c < *cp)
4349                  { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } }                  { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } }
4350                if (c == *cp++)                if (c == *cp++)
4351                  { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; }                  { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; }
4352                }                }
4353              }              }
4354            break;            break;
4355    
4356              case PT_UCNC:
4357              for (i = 1; i <= min; i++)
4358                {
4359                if (eptr >= md->end_subject)
4360                  {
4361                  SCHECK_PARTIAL();
4362                  RRETURN(MATCH_NOMATCH);
4363                  }
4364                GETCHARINCTEST(c, eptr);
4365                if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
4366                     c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
4367                     c >= 0xe000) == prop_fail_result)
4368                  RRETURN(MATCH_NOMATCH);
4369                }
4370              break;
4371    
4372            /* This should not occur */            /* This should not occur */
4373    
4374            default:            default:
# Line 4270  for (;;) Line 4428  for (;;)
4428                eptr + 1 >= md->end_subject &&                eptr + 1 >= md->end_subject &&
4429                NLBLOCK->nltype == NLTYPE_FIXED &&                NLBLOCK->nltype == NLTYPE_FIXED &&
4430                NLBLOCK->nllen == 2 &&                NLBLOCK->nllen == 2 &&
4431                *eptr == NLBLOCK->nl[0])                RAWUCHAR(eptr) == NLBLOCK->nl[0])
4432              {              {
4433              md->hitend = TRUE;              md->hitend = TRUE;
4434              if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);              if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
# Line 4312  for (;;) Line 4470  for (;;)
4470              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4471    
4472              case CHAR_CR:              case CHAR_CR:
4473              if (eptr < md->end_subject && *eptr == CHAR_LF) eptr++;              if (eptr < md->end_subject && RAWUCHAR(eptr) == CHAR_LF) eptr++;
4474              break;              break;
4475    
4476              case CHAR_LF:              case CHAR_LF:
# Line 4416  for (;;) Line 4574  for (;;)
4574          case OP_DIGIT:          case OP_DIGIT:
4575          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4576            {            {
4577              pcre_uint32 cc;
4578            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4579              {              {
4580              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4581              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4582              }              }
4583            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_digit) == 0)            cc = RAWUCHAR(eptr);
4584              if (cc >= 128 || (md->ctypes[cc] & ctype_digit) == 0)
4585              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4586            eptr++;            eptr++;
4587            /* No need to skip more bytes - we know it's a 1-byte character */            /* No need to skip more bytes - we know it's a 1-byte character */
# Line 4431  for (;;) Line 4591  for (;;)
4591          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
4592          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4593            {            {
4594              pcre_uint32 cc;
4595            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4596              {              {
4597              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4598              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4599              }              }
4600            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)            cc = RAWUCHAR(eptr);
4601              if (cc < 128 && (md->ctypes[cc] & ctype_space) != 0)
4602              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4603            eptr++;            eptr++;
4604            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
# Line 4446  for (;;) Line 4608  for (;;)
4608          case OP_WHITESPACE:          case OP_WHITESPACE:
4609          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4610            {            {
4611              pcre_uint32 cc;
4612            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4613              {              {
4614              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4615              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4616              }              }
4617            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_space) == 0)            cc = RAWUCHAR(eptr);
4618              if (cc >= 128 || (md->ctypes[cc] & ctype_space) == 0)
4619              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4620            eptr++;            eptr++;
4621            /* No need to skip more bytes - we know it's a 1-byte character */            /* No need to skip more bytes - we know it's a 1-byte character */
# Line 4461  for (;;) Line 4625  for (;;)
4625          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
4626          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4627            {            {
4628              pcre_uint32 cc;
4629            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4630              {              {
4631              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4632              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4633              }              }
4634            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)            cc = RAWUCHAR(eptr);
4635              if (cc < 128 && (md->ctypes[cc] & ctype_word) != 0)
4636              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4637            eptr++;            eptr++;
4638            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
# Line 4476  for (;;) Line 4642  for (;;)
4642          case OP_WORDCHAR:          case OP_WORDCHAR:
4643          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4644            {            {
4645              pcre_uint32 cc;
4646            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4647              {              {
4648              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4649              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4650              }              }
4651            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_word) == 0)            cc = RAWUCHAR(eptr);
4652              if (cc >= 128 || (md->ctypes[cc] & ctype_word) == 0)
4653              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4654            eptr++;            eptr++;
4655            /* No need to skip more bytes - we know it's a 1-byte character */            /* No need to skip more bytes - we know it's a 1-byte character */
# Line 4925  for (;;) Line 5093  for (;;)
5093    
5094            case PT_CLIST:            case PT_CLIST:
5095            for (fi = min;; fi++)            for (fi = min;; fi++)
5096              {              {
5097              const pcre_uint32 *cp;              const pcre_uint32 *cp;
5098              RMATCH(eptr, ecode, offset_top, md, eptrb, RM62);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM67);
5099              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5100              if (fi >= max) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
5101              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
# Line 4936  for (;;) Line 5104  for (;;)
5104                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5105                }                }
5106              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
5107              cp = PRIV(ucd_caseless_sets) + UCD_CASESET(c);              cp = PRIV(ucd_caseless_sets) + prop_value;
5108              for (;;)              for (;;)
5109                {                {
5110                if (c < *cp)                if (c < *cp)
# Line 4947  for (;;) Line 5115  for (;;)
5115              }              }
5116            /* Control never gets here */            /* Control never gets here */
5117    
5118              case PT_UCNC:
5119              for (fi = min;; fi++)
5120                {
5121                RMATCH(eptr, ecode, offset_top, md, eptrb, RM68);
5122                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5123                if (fi >= max) RRETURN(MATCH_NOMATCH);
5124                if (eptr >= md->end_subject)
5125                  {
5126                  SCHECK_PARTIAL();
5127                  RRETURN(MATCH_NOMATCH);
5128                  }
5129                GETCHARINCTEST(c, eptr);
5130                if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
5131                     c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
5132                     c >= 0xe000) == prop_fail_result)
5133                  RRETURN(MATCH_NOMATCH);
5134                }
5135              /* Control never gets here */
5136    
5137            /* This should never occur */            /* This should never occur */
5138            default:            default:
5139            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
# Line 5028  for (;;) Line 5215  for (;;)
5215                {                {
5216                default: RRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5217                case CHAR_CR:                case CHAR_CR:
5218                if (eptr < md->end_subject && *eptr == CHAR_LF) eptr++;                if (eptr < md->end_subject && RAWUCHAR(eptr) == CHAR_LF) eptr++;
5219                break;                break;
5220    
5221                case CHAR_LF:                case CHAR_LF:
# Line 5416  for (;;) Line 5603  for (;;)
5603              eptr+= len;              eptr+= len;
5604              }              }
5605            break;            break;
5606    
5607            case PT_CLIST:            case PT_CLIST:
5608            for (i = min; i < max; i++)            for (i = min; i < max; i++)
5609              {              {
# Line 5428  for (;;) Line 5615  for (;;)
5615                break;                break;
5616                }                }
5617              GETCHARLENTEST(c, eptr, len);              GETCHARLENTEST(c, eptr, len);
5618              cp = PRIV(ucd_caseless_sets) + UCD_CASESET(c);              cp = PRIV(ucd_caseless_sets) + prop_value;
5619              for (;;)              for (;;)
5620                {                {
5621                if (c < *cp)                if (c < *cp)
5622                  { if (prop_fail_result) break; else goto GOT_MAX; }                  { if (prop_fail_result) break; else goto GOT_MAX; }
5623                if (c == *cp++)                if (c == *cp++)
5624                  { if (prop_fail_result) goto GOT_MAX; else break; }                  { if (prop_fail_result) goto GOT_MAX; else break; }
5625                }                }
5626              eptr += len;              eptr += len;
5627                }
5628              GOT_MAX:
5629              break;
5630    
5631              case PT_UCNC:
5632              for (i = min; i < max; i++)
5633                {
5634                int len = 1;
5635                if (eptr >= md->end_subject)
5636                  {
5637                  SCHECK_PARTIAL();
5638                  break;
5639                  }
5640                GETCHARLENTEST(c, eptr, len);
5641                if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
5642                     c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
5643                     c >= 0xe000) == prop_fail_result)
5644                  break;
5645                eptr += len;
5646              }              }
           GOT_MAX:  
5647            break;            break;
5648    
5649            default:            default:
# Line 5447  for (;;) Line 5652  for (;;)
5652    
5653          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
5654    
5655          if (possessive) continue;          if (possessive) continue;    /* No backtracking */
5656          for(;;)          for(;;)
5657            {            {
5658              if (eptr == pp) goto TAIL_RECURSE;
5659            RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);
5660            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5661            if (eptr-- == pp) break;        /* Stop if tried at original pos */            eptr--;
5662            if (utf) BACKCHAR(eptr);            if (utf) BACKCHAR(eptr);
5663            }            }
5664          }          }
5665    
5666        /* Match extended Unicode sequences. We will get here only if the        /* Match extended Unicode grapheme clusters. We will get here only if the
5667        support is in the binary; otherwise a compile-time error occurs. */        support is in the binary; otherwise a compile-time error occurs. */
5668    
5669        else if (ctype == OP_EXTUNI)        else if (ctype == OP_EXTUNI)
# Line 5489  for (;;) Line 5695  for (;;)
5695    
5696          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
5697    
5698          if (possessive) continue;          if (possessive) continue;    /* No backtracking */
5699    
5700          for(;;)          for(;;)
5701            {            {
5702              int lgb, rgb;
5703              PCRE_PUCHAR fptr;
5704    
5705              if (eptr == pp) goto TAIL_RECURSE;   /* At start of char run */
5706            RMATCH(eptr, ecode, offset_top, md, eptrb, RM45);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM45);
5707            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5708            if (eptr-- == pp) break;        /* Stop if tried at original pos */  
5709            for (;;)                        /* Move back over one extended */            /* Backtracking over an extended grapheme cluster involves inspecting
5710              the previous two characters (if present) to see if a break is
5711              permitted between them. */
5712    
5713              eptr--;
5714              if (!utf) c = *eptr; else
5715              {              {
5716              if (!utf) c = *eptr; else              BACKCHAR(eptr);
5717                {              GETCHAR(c, eptr);
5718                BACKCHAR(eptr);              }
5719                GETCHAR(c, eptr);            rgb = UCD_GRAPHBREAK(c);
5720                }  
5721              if (UCD_CATEGORY(c) != ucp_M) break;            for (;;)
5722              eptr--;              {
5723                if (eptr == pp) goto TAIL_RECURSE;   /* At start of char run */
5724                fptr = eptr - 1;
5725                if (!utf) c = *fptr; else
5726                  {
5727                  BACKCHAR(fptr);
5728                  GETCHAR(c, fptr);
5729                  }
5730                lgb = UCD_GRAPHBREAK(c);
5731                if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
5732                eptr = fptr;
5733                rgb = lgb;
5734              }              }
5735            }            }
5736          }          }
# Line 5532  for (;;) Line 5758  for (;;)
5758                    eptr + 1 >= md->end_subject &&                    eptr + 1 >= md->end_subject &&
5759                    NLBLOCK->nltype == NLTYPE_FIXED &&                    NLBLOCK->nltype == NLTYPE_FIXED &&
5760                    NLBLOCK->nllen == 2 &&                    NLBLOCK->nllen == 2 &&
5761                    *eptr == NLBLOCK->nl[0])                    RAWUCHAR(eptr) == NLBLOCK->nl[0])
5762                  {                  {
5763                  md->hitend = TRUE;                  md->hitend = TRUE;
5764                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
# Line 5558  for (;;) Line 5784  for (;;)
5784                    eptr + 1 >= md->end_subject &&                    eptr + 1 >= md->end_subject &&
5785                    NLBLOCK->nltype == NLTYPE_FIXED &&                    NLBLOCK->nltype == NLTYPE_FIXED &&
5786                    NLBLOCK->nllen == 2 &&                    NLBLOCK->nllen == 2 &&
5787                    *eptr == NLBLOCK->nl[0])                    RAWUCHAR(eptr) == NLBLOCK->nl[0])
5788                  {                  {
5789                  md->hitend = TRUE;                  md->hitend = TRUE;
5790                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
# Line 5615  for (;;) Line 5841  for (;;)
5841              if (c == CHAR_CR)              if (c == CHAR_CR)
5842                {                {
5843                if (++eptr >= md->end_subject) break;                if (++eptr >= md->end_subject) break;
5844                if (*eptr == CHAR_LF) eptr++;                if (RAWUCHAR(eptr) == CHAR_LF) eptr++;
5845                }                }
5846              else              else
5847                {                {
# Line 5770  for (;;) Line 5996  for (;;)
5996            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
5997            }            }
5998    
5999          /* eptr is now past the end of the maximum run. If possessive, we are          if (possessive) continue;    /* No backtracking */
         done (no backing up). Otherwise, match at this position; anything other  
         than no match is immediately returned. For nomatch, back up one  
         character, unless we are matching \R and the last thing matched was  
         \r\n, in which case, back up two bytes. */  
   
         if (possessive) continue;  
6000          for(;;)          for(;;)
6001            {            {
6002              if (eptr == pp) goto TAIL_RECURSE;
6003            RMATCH(eptr, ecode, offset_top, md, eptrb, RM46);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM46);
6004            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
6005            if (eptr-- == pp) break;        /* Stop if tried at original pos */            eptr--;
6006            BACKCHAR(eptr);            BACKCHAR(eptr);
6007            if (ctype == OP_ANYNL && eptr > pp  && *eptr == CHAR_NL &&            if (ctype == OP_ANYNL && eptr > pp  && RAWUCHAR(eptr) == CHAR_NL &&
6008                eptr[-1] == CHAR_CR) eptr--;                RAWUCHAR(eptr - 1) == CHAR_CR) eptr--;
6009            }            }
6010          }          }
6011        else        else
# Line 6019  for (;;) Line 6240  for (;;)
6240            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
6241            }            }
6242    
6243          /* eptr is now past the end of the maximum run. If possessive, we are          if (possessive) continue;    /* No backtracking */
6244          done (no backing up). Otherwise, match at this position; anything other          for (;;)
         than no match is immediately returned. For nomatch, back up one  
         character (byte), unless we are matching \R and the last thing matched  
         was \r\n, in which case, back up two bytes. */  
   
         if (possessive) continue;  
         while (eptr >= pp)  
6245            {            {
6246              if (eptr == pp) goto TAIL_RECURSE;
6247            RMATCH(eptr, ecode, offset_top, md, eptrb, RM47);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM47);
6248            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
6249            eptr--;            eptr--;
# Line 6035  for (;;) Line 6251  for (;;)
6251                eptr[-1] == CHAR_CR) eptr--;                eptr[-1] == CHAR_CR) eptr--;
6252            }            }
6253          }          }
6254    
6255        /* Get here if we can't make it match with any permitted repetitions */        /* Control never gets here */
   
       RRETURN(MATCH_NOMATCH);  
6256        }        }
     /* Control never gets here */  
6257    
6258      /* There's been some horrible disaster. Arrival here can only mean there is      /* There's been some horrible disaster. Arrival here can only mean there is
6259      something seriously wrong in the code above or the OP_xxx definitions. */      something seriously wrong in the code above or the OP_xxx definitions. */
# Line 6082  switch (frame->Xwhere) Line 6295  switch (frame->Xwhere)
6295    LBL(32) LBL(34) LBL(42) LBL(46)    LBL(32) LBL(34) LBL(42) LBL(46)
6296  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6297    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)
6298    LBL(59) LBL(60) LBL(61) LBL(62)    LBL(59) LBL(60) LBL(61) LBL(62) LBL(67) LBL(68)
6299  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
6300  #endif  /* SUPPORT_UTF */  #endif  /* SUPPORT_UTF */
6301    default:    default:
6302    DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere));    DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere));
   
 printf("+++jump error in pcre match: label %d non-existent\n", frame->Xwhere);  
   
6303    return PCRE_ERROR_INTERNAL;    return PCRE_ERROR_INTERNAL;
6304    }    }
6305  #undef LBL  #undef LBL
# Line 6238  const pcre_uint8 *start_bits = NULL; Line 6448  const pcre_uint8 *start_bits = NULL;
6448  PCRE_PUCHAR start_match = (PCRE_PUCHAR)subject + start_offset;  PCRE_PUCHAR start_match = (PCRE_PUCHAR)subject + start_offset;
6449  PCRE_PUCHAR end_subject;  PCRE_PUCHAR end_subject;
6450  PCRE_PUCHAR start_partial = NULL;  PCRE_PUCHAR start_partial = NULL;
6451    PCRE_PUCHAR match_partial = NULL;
6452  PCRE_PUCHAR req_char_ptr = start_match - 1;  PCRE_PUCHAR req_char_ptr = start_match - 1;
6453    
6454  const pcre_study_data *study;  const pcre_study_data *study;
# Line 6269  if ((options & ~PUBLIC_EXEC_OPTIONS) != Line 6480  if ((options & ~PUBLIC_EXEC_OPTIONS) !=
6480  if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0))  if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0))
6481    return PCRE_ERROR_NULL;    return PCRE_ERROR_NULL;
6482  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
6483    if (length < 0) return PCRE_ERROR_BADLENGTH;
6484  if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;  if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
6485    
6486  /* Check that the first field in the block is the magic number. If it is not,  /* Check that the first field in the block is the magic number. If it is not,
# Line 6335  if (extra_data != NULL Line 6547  if (extra_data != NULL
6547      && (extra_data->flags & (PCRE_EXTRA_EXECUTABLE_JIT |      && (extra_data->flags & (PCRE_EXTRA_EXECUTABLE_JIT |
6548                               PCRE_EXTRA_TABLES)) == PCRE_EXTRA_EXECUTABLE_JIT                               PCRE_EXTRA_TABLES)) == PCRE_EXTRA_EXECUTABLE_JIT
6549      && extra_data->executable_jit != NULL      && extra_data->executable_jit != NULL
6550      && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |      && (options & ~PUBLIC_JIT_EXEC_OPTIONS) == 0)
                     PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART |  
                     PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD)) == 0)  
6551    {    {
6552    rc = PRIV(jit_exec)(re, extra_data, (const pcre_uchar *)subject, length,    rc = PRIV(jit_exec)(extra_data, (const pcre_uchar *)subject, length,
6553         start_offset, options, offsets, offsetcount);         start_offset, options, offsets, offsetcount);
6554    
6555    /* PCRE_ERROR_NULL means that the selected normal or partial matching    /* PCRE_ERROR_NULL means that the selected normal or partial matching
6556    mode is not compiled. In this case we simply fallback to interpreter. */    mode is not compiled. In this case we simply fallback to interpreter. */
6557    
6558    if (rc != PCRE_ERROR_NULL) return rc;    if (rc != PCRE_ERROR_JIT_BADOPTION) return rc;
6559    }    }
6560  #endif  #endif
6561    
# Line 6368  md->callout_data = NULL; Line 6578  md->callout_data = NULL;
6578    
6579  tables = re->tables;  tables = re->tables;
6580    
6581    /* The two limit values override the defaults, whatever their value. */
6582    
6583  if (extra_data != NULL)  if (extra_data != NULL)
6584    {    {
6585    register unsigned int flags = extra_data->flags;    register unsigned int flags = extra_data->flags;
# Line 6382  if (extra_data != NULL) Line 6594  if (extra_data != NULL)
6594    if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables;    if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables;
6595    }    }
6596    
6597    /* Limits in the regex override only if they are smaller. */
6598    
6599    if ((re->flags & PCRE_MLSET) != 0 && re->limit_match < md->match_limit)
6600      md->match_limit = re->limit_match;
6601    
6602    if ((re->flags & PCRE_RLSET) != 0 &&
6603        re->limit_recursion < md->match_limit_recursion)
6604      md->match_limit_recursion = re->limit_recursion;
6605    
6606  /* If the exec call supplied NULL for tables, use the inbuilt ones. This  /* If the exec call supplied NULL for tables, use the inbuilt ones. This
6607  is a feature that makes it possible to save compiled regex and re-use them  is a feature that makes it possible to save compiled regex and re-use them
6608  in other programs later. */  in other programs later. */
# Line 6407  end_subject = md->end_subject; Line 6628  end_subject = md->end_subject;
6628  md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
6629  md->use_ucp = (re->options & PCRE_UCP) != 0;  md->use_ucp = (re->options & PCRE_UCP) != 0;
6630  md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
6631  md->ignore_skip_arg = FALSE;  md->ignore_skip_arg = 0;
6632    
6633  /* Some options are unpacked into BOOL variables in the hope that testing  /* Some options are unpacked into BOOL variables in the hope that testing
6634  them will be faster than individual option bits. */  them will be faster than individual option bits. */
# Line 6517  if (re->top_backref > 0 && re->top_backr Line 6738  if (re->top_backref > 0 && re->top_backr
6738    DPRINTF(("Got memory to hold back references\n"));    DPRINTF(("Got memory to hold back references\n"));
6739    }    }
6740  else md->offset_vector = offsets;  else md->offset_vector = offsets;
   
6741  md->offset_end = ocount;  md->offset_end = ocount;
6742  md->offset_max = (2*ocount)/3;  md->offset_max = (2*ocount)/3;
6743  md->offset_overflow = FALSE;  md->capture_last = 0;
 md->capture_last = -1;  
6744    
6745  /* Reset the working variable associated with each extraction. These should  /* Reset the working variable associated with each extraction. These should
6746  never be used unless previously set, but they get saved and restored, and so we  never be used unless previously set, but they get saved and restored, and so we
# Line 6629  for(;;) Line 6848  for(;;)
6848    
6849      if (has_first_char)      if (has_first_char)
6850        {        {
6851          pcre_uchar smc;
6852    
6853        if (first_char != first_char2)        if (first_char != first_char2)
6854          while (start_match < end_subject &&          while (start_match < end_subject &&
6855              *start_match != first_char && *start_match != first_char2)            (smc = RAWUCHARTEST(start_match)) != first_char && smc != first_char2)
6856            start_match++;            start_match++;
6857        else        else
6858          while (start_match < end_subject && *start_match != first_char)          while (start_match < end_subject && RAWUCHARTEST(start_match) != first_char)
6859            start_match++;            start_match++;
6860        }        }
6861    
# Line 6666  for(;;) Line 6887  for(;;)
6887          if (start_match[-1] == CHAR_CR &&          if (start_match[-1] == CHAR_CR &&
6888               (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&               (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
6889               start_match < end_subject &&               start_match < end_subject &&
6890               *start_match == CHAR_NL)               RAWUCHARTEST(start_match) == CHAR_NL)
6891            start_match++;            start_match++;
6892          }          }
6893        }        }
# Line 6677  for(;;) Line 6898  for(;;)
6898        {        {
6899        while (start_match < end_subject)        while (start_match < end_subject)
6900          {          {
6901          register unsigned int c = *start_match;          register pcre_uint32 c = RAWUCHARTEST(start_match);
6902  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
6903          if (c > 255) c = 255;          if (c > 255) c = 255;
6904  #endif  #endif
# Line 6745  for(;;) Line 6966  for(;;)
6966            {            {
6967            while (p < end_subject)            while (p < end_subject)
6968              {              {
6969              register int pp = *p++;              register pcre_uint32 pp = RAWUCHARINCTEST(p);
6970              if (pp == req_char || pp == req_char2) { p--; break; }              if (pp == req_char || pp == req_char2) { p--; break; }
6971              }              }
6972            }            }
# Line 6753  for(;;) Line 6974  for(;;)
6974            {            {
6975            while (p < end_subject)            while (p < end_subject)
6976              {              {
6977              if (*p++ == req_char) { p--; break; }              if (RAWUCHARINCTEST(p) == req_char) { p--; break; }
6978              }              }
6979            }            }
6980    
# Line 6789  for(;;) Line 7010  for(;;)
7010    md->match_call_count = 0;    md->match_call_count = 0;
7011    md->match_function_type = 0;    md->match_function_type = 0;
7012    md->end_offset_top = 0;    md->end_offset_top = 0;
7013      md->skip_arg_count = 0;
7014    rc = match(start_match, md->start_code, start_match, 2, md, NULL, 0);    rc = match(start_match, md->start_code, start_match, 2, md, NULL, 0);
7015    if (md->hitend && start_partial == NULL) start_partial = md->start_used_ptr;    if (md->hitend && start_partial == NULL)
7016        {
7017        start_partial = md->start_used_ptr;
7018        match_partial = start_match;
7019        }
7020    
7021    switch(rc)    switch(rc)
7022      {      {
# Line 6803  for(;;) Line 7029  for(;;)
7029    
7030      case MATCH_SKIP_ARG:      case MATCH_SKIP_ARG:
7031      new_start_match = start_match;      new_start_match = start_match;
7032      md->ignore_skip_arg = TRUE;      md->ignore_skip_arg = md->skip_arg_count;
7033      break;      break;
7034    
7035      /* SKIP passes back the next starting point explicitly, but if it is the      /* SKIP passes back the next starting point explicitly, but if it is no
7036      same as the match we have just done, treat it as NOMATCH. */      greater than the match we have just done, treat it as NOMATCH. */
7037    
7038      case MATCH_SKIP:      case MATCH_SKIP:
7039      if (md->start_match_ptr != start_match)      if (md->start_match_ptr > start_match)
7040        {        {
7041        new_start_match = md->start_match_ptr;        new_start_match = md->start_match_ptr;
7042        break;        break;
# Line 6818  for(;;) Line 7044  for(;;)
7044      /* Fall through */      /* Fall through */
7045    
7046      /* NOMATCH and PRUNE advance by one character. THEN at this level acts      /* NOMATCH and PRUNE advance by one character. THEN at this level acts
7047      exactly like PRUNE. Unset the ignore SKIP-with-argument flag. */      exactly like PRUNE. Unset ignore SKIP-with-argument. */
7048    
7049      case MATCH_NOMATCH:      case MATCH_NOMATCH:
7050      case MATCH_PRUNE:      case MATCH_PRUNE:
7051      case MATCH_THEN:      case MATCH_THEN:
7052      md->ignore_skip_arg = FALSE;      md->ignore_skip_arg = 0;
7053      new_start_match = start_match + 1;      new_start_match = start_match + 1;
7054  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
7055      if (utf)      if (utf)
# Line 6916  if (rc == MATCH_MATCH || rc == MATCH_ACC Line 7142  if (rc == MATCH_MATCH || rc == MATCH_ACC
7142          (arg_offset_max - 2) * sizeof(int));          (arg_offset_max - 2) * sizeof(int));
7143        DPRINTF(("Copied offsets from temporary memory\n"));        DPRINTF(("Copied offsets from temporary memory\n"));
7144        }        }
7145      if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE;      if (md->end_offset_top > arg_offset_max) md->capture_last |= OVFLBIT;
7146      DPRINTF(("Freeing temporary memory\n"));      DPRINTF(("Freeing temporary memory\n"));
7147      (PUBL(free))(md->offset_vector);      (PUBL(free))(md->offset_vector);
7148      }      }
# Line 6924  if (rc == MATCH_MATCH || rc == MATCH_ACC Line 7150  if (rc == MATCH_MATCH || rc == MATCH_ACC
7150    /* Set the return code to the number of captured strings, or 0 if there were    /* Set the return code to the number of captured strings, or 0 if there were
7151    too many to fit into the vector. */    too many to fit into the vector. */
7152    
7153    rc = (md->offset_overflow && md->end_offset_top >= arg_offset_max)?    rc = ((md->capture_last & OVFLBIT) != 0 &&
7154             md->end_offset_top >= arg_offset_max)?
7155      0 : md->end_offset_top/2;      0 : md->end_offset_top/2;
7156    
7157    /* If there is space in the offset vector, set any unused pairs at the end of    /* If there is space in the offset vector, set any unused pairs at the end of
# Line 6989  if (rc != MATCH_NOMATCH && rc != PCRE_ER Line 7216  if (rc != MATCH_NOMATCH && rc != PCRE_ER
7216    
7217  /* Handle partial matches - disable any mark data */  /* Handle partial matches - disable any mark data */
7218    
7219  if (start_partial != NULL)  if (match_partial != NULL)
7220    {    {
7221    DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));    DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));
7222    md->mark = NULL;    md->mark = NULL;
# Line 6997  if (start_partial != NULL) Line 7224  if (start_partial != NULL)
7224      {      {
7225      offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject);      offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject);
7226      offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);      offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);
7227        if (offsetcount > 2)
7228          offsets[2] = (int)(match_partial - (PCRE_PUCHAR)subject);
7229      }      }
7230    rc = PCRE_ERROR_PARTIAL;    rc = PCRE_ERROR_PARTIAL;
7231    }    }

Legend:
Removed from v.1055  
changed lines
  Added in v.1361

  ViewVC Help
Powered by ViewVC 1.1.5