/[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 1187 by zherczeg, Mon Oct 29 11:30:45 2012 UTC revision 1296 by ph10, Tue Mar 19 16:29:12 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 199  if (caseless) Line 217  if (caseless)
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 219  if (caseless) Line 237  if (caseless)
237      {      {
238      while (length-- > 0)      while (length-- > 0)
239        {        {
240        pcre_uchar cc, cp;        pcre_uint32 cc, cp;
241        if (eptr >= md->end_subject) return -2;   /* Partial match */        if (eptr >= md->end_subject) return -2;   /* Partial match */
242        cc = RAWUCHARTEST(eptr);        cc = RAWUCHARTEST(eptr);
243        cp = RAWUCHARTEST(p);        cp = RAWUCHARTEST(p);
# Line 294  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, RM67 };         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 416  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 634  int max; Line 652  int max;
652  int min;  int min;
653  unsigned int number;  unsigned int number;
654  int offset;  int offset;
655  pcre_uchar 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 763  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 789  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 preceed 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);
831        RRETURN(rrc);  
   
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 1066  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 1097  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 1218  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 1247  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 1291  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 1513  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 1521  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 1584  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);
# Line 1594  for (;;) Line 1615  for (;;)
1615          }          }
1616        md->mark = save_mark;        md->mark = save_mark;
1617    
1618        /* A COMMIT failure must fail the entire assertion, without trying any        /* See comment in the code for capturing groups above about handling
1619        subsequent branches. */        THEN. */
   
       if (rrc == MATCH_COMMIT) RRETURN(MATCH_NOMATCH);  
1620    
1621        /* PCRE does not allow THEN to escape beyond an assertion; it        if (rrc == MATCH_THEN)
1622        is treated as NOMATCH. */          {
1623            next = ecode + GET(ecode,1);
1624            if (md->start_match_ptr < next &&
1625                (*ecode == OP_ALT || *next == OP_ALT))
1626              rrc = MATCH_NOMATCH;
1627            }
1628    
1629          /* Anything other than NOMATCH causes the assertion to fail. This
1630          includes COMMIT, SKIP, and PRUNE. However, this consistent approach does
1631          not always have exactly the same effect as in Perl. */
1632    
1633        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1634        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1635        }        }
1636      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
1637    
1638        /* If we have tried all the alternative branches, the assertion has
1639        failed. */
1640    
1641      if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);      if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);
1642    
# Line 1613  for (;;) Line 1644  for (;;)
1644    
1645      if (condassert) RRETURN(MATCH_MATCH);      if (condassert) RRETURN(MATCH_MATCH);
1646    
1647      /* Continue from after the assertion, updating the offsets high water      /* Continue from after a successful assertion, updating the offsets high
1648      mark, since extracts may have been taken during the assertion. */      water mark, since extracts may have been taken during the assertion. */
1649    
1650      do ecode += GET(ecode,1); while (*ecode == OP_ALT);      do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1651      ecode += 1 + LINK_SIZE;      ecode += 1 + LINK_SIZE;
1652      offset_top = md->end_offset_top;      offset_top = md->end_offset_top;
1653      continue;      continue;
1654    
1655      /* Negative assertion: all branches must fail to match. Encountering SKIP,      /* Negative assertion: all branches must fail to match for the assertion to
1656      PRUNE, or COMMIT means we must assume failure without checking subsequent      succeed. */
     branches. */  
1657    
1658      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1659      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
# Line 1635  for (;;) Line 1665  for (;;)
1665        }        }
1666      else condassert = FALSE;      else condassert = FALSE;
1667    
1668        /* Loop for each alternative branch. */
1669    
1670      do      do
1671        {        {
1672        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);
1673        md->mark = save_mark;        md->mark = save_mark;
1674    
1675          /* A successful match means the assertion has failed. */
1676    
1677        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);
1678        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)  
1679          /* See comment in the code for capturing groups above about handling
1680          THEN. */
1681    
1682          if (rrc == MATCH_THEN)
1683          {          {
1684          do ecode += GET(ecode,1); while (*ecode == OP_ALT);          next = ecode + GET(ecode,1);
1685          break;          if (md->start_match_ptr < next &&
1686                (*ecode == OP_ALT || *next == OP_ALT))
1687              rrc = MATCH_NOMATCH;
1688          }          }
1689    
1690          /* No match on a branch means we must carry on and try the next branch.
1691          Anything else, in particular, SKIP, PRUNE, etc. causes a failure in the
1692          enclosing branch. This is a consistent approach, but does not always have
1693          the same effect as in Perl. */
1694    
1695        /* PCRE does not allow THEN to escape beyond an assertion; it is treated        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
       as NOMATCH. */  
   
       if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);  
1696        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1697        }        }
1698      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
1699    
1700        /* All branches in the assertion failed to match. */
1701    
1702      if (condassert) RRETURN(MATCH_MATCH);  /* Condition assertion */      if (condassert) RRETURN(MATCH_MATCH);  /* Condition assertion */
1703        ecode += 1 + LINK_SIZE;                /* Continue with current branch */
     ecode += 1 + LINK_SIZE;  
1704      continue;      continue;
1705    
1706      /* 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 1716  for (;;) Line 1760  for (;;)
1760        cb.pattern_position = GET(ecode, 2);        cb.pattern_position = GET(ecode, 2);
1761        cb.next_item_length = GET(ecode, 2 + LINK_SIZE);        cb.next_item_length = GET(ecode, 2 + LINK_SIZE);
1762        cb.capture_top      = offset_top/2;        cb.capture_top      = offset_top/2;
1763        cb.capture_last     = md->capture_last;        cb.capture_last     = md->capture_last & CAPLMASK;
1764          /* Internal change requires this for API compatibility. */
1765          if (cb.capture_last == 0) cb.capture_last = -1;
1766        cb.callout_data     = md->callout_data;        cb.callout_data     = md->callout_data;
1767        cb.mark             = md->nomatch_mark;        cb.mark             = md->nomatch_mark;
1768        if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);        if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
# Line 1762  for (;;) Line 1808  for (;;)
1808        /* Add to "recursing stack" */        /* Add to "recursing stack" */
1809    
1810        new_recursive.group_num = recno;        new_recursive.group_num = recno;
1811          new_recursive.saved_capture_last = md->capture_last;
1812        new_recursive.subject_position = eptr;        new_recursive.subject_position = eptr;
1813        new_recursive.prevrec = md->recursive;        new_recursive.prevrec = md->recursive;
1814        md->recursive = &new_recursive;        md->recursive = &new_recursive;
# Line 1785  for (;;) Line 1832  for (;;)
1832              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
1833    
1834        /* OK, now we can do the recursion. After processing each alternative,        /* OK, now we can do the recursion. After processing each alternative,
1835        restore the offset data. If there were nested recursions, md->recursive        restore the offset data and the last captured value. If there were nested
1836        might be changed, so reset it before looping. */        recursions, md->recursive might be changed, so reset it before looping.
1837          */
1838    
1839        DPRINTF(("Recursing into group %d\n", new_recursive.group_num));        DPRINTF(("Recursing into group %d\n", new_recursive.group_num));
1840        cbegroup = (*callpat >= OP_SBRA);        cbegroup = (*callpat >= OP_SBRA);
# Line 1797  for (;;) Line 1845  for (;;)
1845            md, eptrb, RM6);            md, eptrb, RM6);
1846          memcpy(md->offset_vector, new_recursive.offset_save,          memcpy(md->offset_vector, new_recursive.offset_save,
1847              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
1848            md->capture_last = new_recursive.saved_capture_last;
1849          md->recursive = new_recursive.prevrec;          md->recursive = new_recursive.prevrec;
1850          if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)          if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
1851            {            {
# Line 1813  for (;;) Line 1862  for (;;)
1862            goto RECURSION_MATCHED;        /* Exit loop; end processing */            goto RECURSION_MATCHED;        /* Exit loop; end processing */
1863            }            }
1864    
1865          /* 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
1866          is treated as NOMATCH. */          recursion; they are treated as NOMATCH. These codes are defined in a
1867            range that can be tested for. Any other return code is an error. */
1868    
1869          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN &&          else if (rrc != MATCH_NOMATCH &&
1870                   rrc != MATCH_COMMIT)                   (rrc < MATCH_BACKTRACK_MIN || rrc > MATCH_BACKTRACK_MAX))
1871            {            {
1872            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1873            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
# Line 1947  for (;;) Line 1997  for (;;)
1997    
1998        /* Deal with capturing */        /* Deal with capturing */
1999    
2000        md->capture_last = number;        md->capture_last = (md->capture_last & OVFLMASK) | number;
2001        if (offset >= md->offset_max) md->offset_overflow = TRUE; else        if (offset >= md->offset_max) md->capture_last |= OVFLBIT; else
2002          {          {
2003          /* If offset is greater than offset_top, it means that we are          /* If offset is greater than offset_top, it means that we are
2004          "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 2532  for (;;) Line 2582  for (;;)
2582        }        }
2583      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2584        {        {
2585        const pcre_uint32 *cp;        const pcre_uint32 *cp;
2586        const ucd_record *prop = GET_UCD(c);        const ucd_record *prop = GET_UCD(c);
2587    
2588        switch(ecode[1])        switch(ecode[1])
# Line 2594  for (;;) Line 2644  for (;;)
2644          break;          break;
2645    
2646          case PT_CLIST:          case PT_CLIST:
2647          cp = PRIV(ucd_caseless_sets) + prop->caseset;          cp = PRIV(ucd_caseless_sets) + ecode[2];
2648          for (;;)          for (;;)
2649            {            {
2650            if (c < *cp)            if (c < *cp)
# Line 2604  for (;;) Line 2654  for (;;)
2654            }            }
2655          break;          break;
2656    
2657            case PT_UCNC:
2658            if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
2659                 c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
2660                 c >= 0xe000) == (op == OP_NOTPROP))
2661              RRETURN(MATCH_NOMATCH);
2662            break;
2663    
2664          /* This should never occur */          /* This should never occur */
2665    
2666          default:          default:
# Line 3190  for (;;) Line 3247  for (;;)
3247    
3248        if (fc < 128)        if (fc < 128)
3249          {          {
3250          pcre_uchar cc = RAWUCHAR(eptr);          pcre_uint32 cc = RAWUCHAR(eptr);
3251          if (md->lcc[fc] != TABLE_GET(cc, md->lcc, cc)) RRETURN(MATCH_NOMATCH);          if (md->lcc[fc] != TABLE_GET(cc, md->lcc, cc)) RRETURN(MATCH_NOMATCH);
3252          ecode++;          ecode++;
3253          eptr++;          eptr++;
# Line 3439  for (;;) Line 3496  for (;;)
3496    
3497        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
3498          {          {
3499          pcre_uchar cc;          pcre_uint32 cc;                 /* Faster than pcre_uchar */
   
3500          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
3501            {            {
3502            SCHECK_PARTIAL();            SCHECK_PARTIAL();
# Line 3455  for (;;) Line 3511  for (;;)
3511          {          {
3512          for (fi = min;; fi++)          for (fi = min;; fi++)
3513            {            {
3514            pcre_uchar cc;            pcre_uint32 cc;               /* Faster than pcre_uchar */
   
3515            RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);
3516            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3517            if (fi >= max) RRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
# Line 3476  for (;;) Line 3531  for (;;)
3531          pp = eptr;          pp = eptr;
3532          for (i = min; i < max; i++)          for (i = min; i < max; i++)
3533            {            {
3534            pcre_uchar cc;            pcre_uint32 cc;               /* Faster than pcre_uchar */
   
3535            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3536              {              {
3537              SCHECK_PARTIAL();              SCHECK_PARTIAL();
# Line 4203  for (;;) Line 4257  for (;;)
4257                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4258              }              }
4259            break;            break;
4260    
4261            case PT_CLIST:            case PT_CLIST:
4262            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
4263              {              {
4264              const pcre_uint32 *cp;              const pcre_uint32 *cp;
4265              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4266                {                {
# Line 4214  for (;;) Line 4268  for (;;)
4268                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4269                }                }
4270              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4271              cp = PRIV(ucd_caseless_sets) + UCD_CASESET(c);              cp = PRIV(ucd_caseless_sets) + prop_value;
4272              for (;;)              for (;;)
4273                {                {
4274                if (c < *cp)                if (c < *cp)
4275                  { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } }                  { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } }
4276                if (c == *cp++)                if (c == *cp++)
4277                  { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; }                  { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; }
4278                }                }
4279              }              }
4280            break;            break;
4281    
4282              case PT_UCNC:
4283              for (i = 1; i <= min; i++)
4284                {
4285                if (eptr >= md->end_subject)
4286                  {
4287                  SCHECK_PARTIAL();
4288                  RRETURN(MATCH_NOMATCH);
4289                  }
4290                GETCHARINCTEST(c, eptr);
4291                if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
4292                     c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
4293                     c >= 0xe000) == prop_fail_result)
4294                  RRETURN(MATCH_NOMATCH);
4295                }
4296              break;
4297    
4298            /* This should not occur */            /* This should not occur */
4299    
4300            default:            default:
# Line 4430  for (;;) Line 4500  for (;;)
4500          case OP_DIGIT:          case OP_DIGIT:
4501          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4502            {            {
4503            pcre_uchar cc;            pcre_uint32 cc;
   
4504            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4505              {              {
4506              SCHECK_PARTIAL();              SCHECK_PARTIAL();
# Line 4448  for (;;) Line 4517  for (;;)
4517          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
4518          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4519            {            {
4520            pcre_uchar cc;            pcre_uint32 cc;
   
4521            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4522              {              {
4523              SCHECK_PARTIAL();              SCHECK_PARTIAL();
# Line 4466  for (;;) Line 4534  for (;;)
4534          case OP_WHITESPACE:          case OP_WHITESPACE:
4535          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4536            {            {
4537            pcre_uchar cc;            pcre_uint32 cc;
   
4538            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4539              {              {
4540              SCHECK_PARTIAL();              SCHECK_PARTIAL();
# Line 4484  for (;;) Line 4551  for (;;)
4551          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
4552          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4553            {            {
4554            pcre_uchar cc;            pcre_uint32 cc;
   
4555            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4556              {              {
4557              SCHECK_PARTIAL();              SCHECK_PARTIAL();
# Line 4502  for (;;) Line 4568  for (;;)
4568          case OP_WORDCHAR:          case OP_WORDCHAR:
4569          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4570            {            {
4571            pcre_uchar cc;            pcre_uint32 cc;
   
4572            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4573              {              {
4574              SCHECK_PARTIAL();              SCHECK_PARTIAL();
# Line 4954  for (;;) Line 5019  for (;;)
5019    
5020            case PT_CLIST:            case PT_CLIST:
5021            for (fi = min;; fi++)            for (fi = min;; fi++)
5022              {              {
5023              const pcre_uint32 *cp;              const pcre_uint32 *cp;
5024              RMATCH(eptr, ecode, offset_top, md, eptrb, RM67);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM67);
5025              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
# Line 4965  for (;;) Line 5030  for (;;)
5030                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5031                }                }
5032              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
5033              cp = PRIV(ucd_caseless_sets) + UCD_CASESET(c);              cp = PRIV(ucd_caseless_sets) + prop_value;
5034              for (;;)              for (;;)
5035                {                {
5036                if (c < *cp)                if (c < *cp)
# Line 4976  for (;;) Line 5041  for (;;)
5041              }              }
5042            /* Control never gets here */            /* Control never gets here */
5043    
5044              case PT_UCNC:
5045              for (fi = min;; fi++)
5046                {
5047                RMATCH(eptr, ecode, offset_top, md, eptrb, RM68);
5048                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5049                if (fi >= max) RRETURN(MATCH_NOMATCH);
5050                if (eptr >= md->end_subject)
5051                  {
5052                  SCHECK_PARTIAL();
5053                  RRETURN(MATCH_NOMATCH);
5054                  }
5055                GETCHARINCTEST(c, eptr);
5056                if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
5057                     c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
5058                     c >= 0xe000) == prop_fail_result)
5059                  RRETURN(MATCH_NOMATCH);
5060                }
5061              /* Control never gets here */
5062    
5063            /* This should never occur */            /* This should never occur */
5064            default:            default:
5065            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
# Line 5445  for (;;) Line 5529  for (;;)
5529              eptr+= len;              eptr+= len;
5530              }              }
5531            break;            break;
5532    
5533            case PT_CLIST:            case PT_CLIST:
5534            for (i = min; i < max; i++)            for (i = min; i < max; i++)
5535              {              {
# Line 5457  for (;;) Line 5541  for (;;)
5541                break;                break;
5542                }                }
5543              GETCHARLENTEST(c, eptr, len);              GETCHARLENTEST(c, eptr, len);
5544              cp = PRIV(ucd_caseless_sets) + UCD_CASESET(c);              cp = PRIV(ucd_caseless_sets) + prop_value;
5545              for (;;)              for (;;)
5546                {                {
5547                if (c < *cp)                if (c < *cp)
5548                  { if (prop_fail_result) break; else goto GOT_MAX; }                  { if (prop_fail_result) break; else goto GOT_MAX; }
5549                if (c == *cp++)                if (c == *cp++)
5550                  { if (prop_fail_result) goto GOT_MAX; else break; }                  { if (prop_fail_result) goto GOT_MAX; else break; }
5551                }                }
5552              eptr += len;              eptr += len;
5553                }
5554              GOT_MAX:
5555              break;
5556    
5557              case PT_UCNC:
5558              for (i = min; i < max; i++)
5559                {
5560                int len = 1;
5561                if (eptr >= md->end_subject)
5562                  {
5563                  SCHECK_PARTIAL();
5564                  break;
5565                  }
5566                GETCHARLENTEST(c, eptr, len);
5567                if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
5568                     c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
5569                     c >= 0xe000) == prop_fail_result)
5570                  break;
5571                eptr += len;
5572              }              }
           GOT_MAX:  
5573            break;            break;
5574    
5575            default:            default:
# Line 6111  switch (frame->Xwhere) Line 6213  switch (frame->Xwhere)
6213    LBL(32) LBL(34) LBL(42) LBL(46)    LBL(32) LBL(34) LBL(42) LBL(46)
6214  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6215    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)
6216    LBL(59) LBL(60) LBL(61) LBL(62) LBL(67)    LBL(59) LBL(60) LBL(61) LBL(62) LBL(67) LBL(68)
6217  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
6218  #endif  /* SUPPORT_UTF */  #endif  /* SUPPORT_UTF */
6219    default:    default:
# Line 6264  const pcre_uint8 *start_bits = NULL; Line 6366  const pcre_uint8 *start_bits = NULL;
6366  PCRE_PUCHAR start_match = (PCRE_PUCHAR)subject + start_offset;  PCRE_PUCHAR start_match = (PCRE_PUCHAR)subject + start_offset;
6367  PCRE_PUCHAR end_subject;  PCRE_PUCHAR end_subject;
6368  PCRE_PUCHAR start_partial = NULL;  PCRE_PUCHAR start_partial = NULL;
6369    PCRE_PUCHAR match_partial;
6370  PCRE_PUCHAR req_char_ptr = start_match - 1;  PCRE_PUCHAR req_char_ptr = start_match - 1;
6371    
6372  const pcre_study_data *study;  const pcre_study_data *study;
# Line 6295  if ((options & ~PUBLIC_EXEC_OPTIONS) != Line 6398  if ((options & ~PUBLIC_EXEC_OPTIONS) !=
6398  if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0))  if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0))
6399    return PCRE_ERROR_NULL;    return PCRE_ERROR_NULL;
6400  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
6401    if (length < 0) return PCRE_ERROR_BADLENGTH;
6402  if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;  if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
6403    
6404  /* 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 6431  end_subject = md->end_subject; Line 6535  end_subject = md->end_subject;
6535  md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
6536  md->use_ucp = (re->options & PCRE_UCP) != 0;  md->use_ucp = (re->options & PCRE_UCP) != 0;
6537  md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
6538  md->ignore_skip_arg = FALSE;  md->ignore_skip_arg = 0;
6539    
6540  /* Some options are unpacked into BOOL variables in the hope that testing  /* Some options are unpacked into BOOL variables in the hope that testing
6541  them will be faster than individual option bits. */  them will be faster than individual option bits. */
# Line 6541  if (re->top_backref > 0 && re->top_backr Line 6645  if (re->top_backref > 0 && re->top_backr
6645    DPRINTF(("Got memory to hold back references\n"));    DPRINTF(("Got memory to hold back references\n"));
6646    }    }
6647  else md->offset_vector = offsets;  else md->offset_vector = offsets;
   
6648  md->offset_end = ocount;  md->offset_end = ocount;
6649  md->offset_max = (2*ocount)/3;  md->offset_max = (2*ocount)/3;
6650  md->offset_overflow = FALSE;  md->capture_last = 0;
 md->capture_last = -1;  
6651    
6652  /* Reset the working variable associated with each extraction. These should  /* Reset the working variable associated with each extraction. These should
6653  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 6815  for(;;) Line 6917  for(;;)
6917    md->match_call_count = 0;    md->match_call_count = 0;
6918    md->match_function_type = 0;    md->match_function_type = 0;
6919    md->end_offset_top = 0;    md->end_offset_top = 0;
6920      md->skip_arg_count = 0;
6921    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);
6922    if (md->hitend && start_partial == NULL) start_partial = md->start_used_ptr;    if (md->hitend && start_partial == NULL)
6923        {
6924        start_partial = md->start_used_ptr;
6925        match_partial = start_match;
6926        }
6927    
6928    switch(rc)    switch(rc)
6929      {      {
# Line 6829  for(;;) Line 6936  for(;;)
6936    
6937      case MATCH_SKIP_ARG:      case MATCH_SKIP_ARG:
6938      new_start_match = start_match;      new_start_match = start_match;
6939      md->ignore_skip_arg = TRUE;      md->ignore_skip_arg = md->skip_arg_count;
6940      break;      break;
6941    
6942      /* 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
6943      same as the match we have just done, treat it as NOMATCH. */      greater than the match we have just done, treat it as NOMATCH. */
6944    
6945      case MATCH_SKIP:      case MATCH_SKIP:
6946      if (md->start_match_ptr != start_match)      if (md->start_match_ptr > start_match)
6947        {        {
6948        new_start_match = md->start_match_ptr;        new_start_match = md->start_match_ptr;
6949        break;        break;
# Line 6844  for(;;) Line 6951  for(;;)
6951      /* Fall through */      /* Fall through */
6952    
6953      /* NOMATCH and PRUNE advance by one character. THEN at this level acts      /* NOMATCH and PRUNE advance by one character. THEN at this level acts
6954      exactly like PRUNE. Unset the ignore SKIP-with-argument flag. */      exactly like PRUNE. Unset ignore SKIP-with-argument. */
6955    
6956      case MATCH_NOMATCH:      case MATCH_NOMATCH:
6957      case MATCH_PRUNE:      case MATCH_PRUNE:
6958      case MATCH_THEN:      case MATCH_THEN:
6959      md->ignore_skip_arg = FALSE;      md->ignore_skip_arg = 0;
6960      new_start_match = start_match + 1;      new_start_match = start_match + 1;
6961  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
6962      if (utf)      if (utf)
# Line 6942  if (rc == MATCH_MATCH || rc == MATCH_ACC Line 7049  if (rc == MATCH_MATCH || rc == MATCH_ACC
7049          (arg_offset_max - 2) * sizeof(int));          (arg_offset_max - 2) * sizeof(int));
7050        DPRINTF(("Copied offsets from temporary memory\n"));        DPRINTF(("Copied offsets from temporary memory\n"));
7051        }        }
7052      if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE;      if (md->end_offset_top > arg_offset_max) md->capture_last |= OVFLBIT;
7053      DPRINTF(("Freeing temporary memory\n"));      DPRINTF(("Freeing temporary memory\n"));
7054      (PUBL(free))(md->offset_vector);      (PUBL(free))(md->offset_vector);
7055      }      }
# Line 6950  if (rc == MATCH_MATCH || rc == MATCH_ACC Line 7057  if (rc == MATCH_MATCH || rc == MATCH_ACC
7057    /* 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
7058    too many to fit into the vector. */    too many to fit into the vector. */
7059    
7060    rc = (md->offset_overflow && md->end_offset_top >= arg_offset_max)?    rc = ((md->capture_last & OVFLBIT) != 0 &&
7061             md->end_offset_top >= arg_offset_max)?
7062      0 : md->end_offset_top/2;      0 : md->end_offset_top/2;
7063    
7064    /* 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 7023  if (start_partial != NULL) Line 7131  if (start_partial != NULL)
7131      {      {
7132      offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject);      offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject);
7133      offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);      offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);
7134        if (offsetcount > 2)
7135          offsets[2] = (int)(match_partial - (PCRE_PUCHAR)subject);
7136      }      }
7137    rc = PCRE_ERROR_PARTIAL;    rc = PCRE_ERROR_PARTIAL;
7138    }    }

Legend:
Removed from v.1187  
changed lines
  Added in v.1296

  ViewVC Help
Powered by ViewVC 1.1.5