/[pcre]/code/trunk/pcre_dfa_exec.c
ViewVC logotype

Diff of /code/trunk/pcre_dfa_exec.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 850 by zherczeg, Wed Jan 4 17:29:11 2012 UTC revision 1376 by ph10, Sat Oct 12 18:02:11 2013 UTC
# Line 7  and semantics are as close as possible t Line 7  and semantics are as close as possible t
7  below for why this module is different).  below for why this module is different).
8    
9                         Written by Philip Hazel                         Written by Philip Hazel
10             Copyright (c) 1997-2012 University of Cambridge             Copyright (c) 1997-2013 University of Cambridge
11    
12  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
13  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 38  POSSIBILITY OF SUCH DAMAGE. Line 38  POSSIBILITY OF SUCH DAMAGE.
38  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
39  */  */
40    
   
41  /* This module contains the external function pcre_dfa_exec(), which is an  /* This module contains the external function pcre_dfa_exec(), which is an
42  alternative matching function that uses a sort of DFA algorithm (not a true  alternative matching function that uses a sort of DFA algorithm (not a true
43  FSM). This is NOT Perl- compatible, but it has advantages in certain  FSM). This is NOT Perl-compatible, but it has advantages in certain
44  applications. */  applications. */
45    
46    
# Line 121  static const pcre_uint8 coptable[] = { Line 120  static const pcre_uint8 coptable[] = {
120    0, 0,                          /* \P, \p                                 */    0, 0,                          /* \P, \p                                 */
121    0, 0, 0, 0, 0,                 /* \R, \H, \h, \V, \v                     */    0, 0, 0, 0, 0,                 /* \R, \H, \h, \V, \v                     */
122    0,                             /* \X                                     */    0,                             /* \X                                     */
123    0, 0, 0, 0, 0, 0,              /* \Z, \z, ^, ^M, $, $M                   */    0, 0, 0, 0, 0, 0,              /* \Z, \z, $, $M, ^, ^M                   */
124    1,                             /* Char                                   */    1,                             /* Char                                   */
125    1,                             /* Chari                                  */    1,                             /* Chari                                  */
126    1,                             /* not                                    */    1,                             /* not                                    */
# Line 157  static const pcre_uint8 coptable[] = { Line 156  static const pcre_uint8 coptable[] = {
156    0,                             /* XCLASS - variable length               */    0,                             /* XCLASS - variable length               */
157    0,                             /* REF                                    */    0,                             /* REF                                    */
158    0,                             /* REFI                                   */    0,                             /* REFI                                   */
159      0,                             /* DNREF                                  */
160      0,                             /* DNREFI                                 */
161    0,                             /* RECURSE                                */    0,                             /* RECURSE                                */
162    0,                             /* CALLOUT                                */    0,                             /* CALLOUT                                */
163    0,                             /* Alt                                    */    0,                             /* Alt                                    */
# Line 172  static const pcre_uint8 coptable[] = { Line 173  static const pcre_uint8 coptable[] = {
173    0, 0,                          /* ONCE, ONCE_NC                          */    0, 0,                          /* ONCE, ONCE_NC                          */
174    0, 0, 0, 0, 0,                 /* BRA, BRAPOS, CBRA, CBRAPOS, COND       */    0, 0, 0, 0, 0,                 /* BRA, BRAPOS, CBRA, CBRAPOS, COND       */
175    0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */    0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */
176    0, 0,                          /* CREF, NCREF                            */    0, 0,                          /* CREF, DNCREF                           */
177    0, 0,                          /* RREF, NRREF                            */    0, 0,                          /* RREF, DNRREF                           */
178    0,                             /* DEF                                    */    0,                             /* DEF                                    */
179    0, 0, 0,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */    0, 0, 0,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */
180    0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG                 */    0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG                 */
# Line 195  static const pcre_uint8 poptable[] = { Line 196  static const pcre_uint8 poptable[] = {
196    1, 1,                          /* \P, \p                                 */    1, 1,                          /* \P, \p                                 */
197    1, 1, 1, 1, 1,                 /* \R, \H, \h, \V, \v                     */    1, 1, 1, 1, 1,                 /* \R, \H, \h, \V, \v                     */
198    1,                             /* \X                                     */    1,                             /* \X                                     */
199    0, 0, 0, 0, 0, 0,              /* \Z, \z, ^, ^M, $, $M                   */    0, 0, 0, 0, 0, 0,              /* \Z, \z, $, $M, ^, ^M                   */
200    1,                             /* Char                                   */    1,                             /* Char                                   */
201    1,                             /* Chari                                  */    1,                             /* Chari                                  */
202    1,                             /* not                                    */    1,                             /* not                                    */
# Line 226  static const pcre_uint8 poptable[] = { Line 227  static const pcre_uint8 poptable[] = {
227    1,                             /* XCLASS - variable length               */    1,                             /* XCLASS - variable length               */
228    0,                             /* REF                                    */    0,                             /* REF                                    */
229    0,                             /* REFI                                   */    0,                             /* REFI                                   */
230      0,                             /* DNREF                                  */
231      0,                             /* DNREFI                                 */
232    0,                             /* RECURSE                                */    0,                             /* RECURSE                                */
233    0,                             /* CALLOUT                                */    0,                             /* CALLOUT                                */
234    0,                             /* Alt                                    */    0,                             /* Alt                                    */
# Line 241  static const pcre_uint8 poptable[] = { Line 244  static const pcre_uint8 poptable[] = {
244    0, 0,                          /* ONCE, ONCE_NC                          */    0, 0,                          /* ONCE, ONCE_NC                          */
245    0, 0, 0, 0, 0,                 /* BRA, BRAPOS, CBRA, CBRAPOS, COND       */    0, 0, 0, 0, 0,                 /* BRA, BRAPOS, CBRA, CBRAPOS, COND       */
246    0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */    0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */
247    0, 0,                          /* CREF, NCREF                            */    0, 0,                          /* CREF, DNCREF                           */
248    0, 0,                          /* RREF, NRREF                            */    0, 0,                          /* RREF, DNRREF                           */
249    0,                             /* DEF                                    */    0,                             /* DEF                                    */
250    0, 0, 0,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */    0, 0, 0,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */
251    0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG                 */    0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG                 */
# Line 282  typedef struct stateblock { Line 285  typedef struct stateblock {
285    int data;                       /* Some use extra data */    int data;                       /* Some use extra data */
286  } stateblock;  } stateblock;
287    
288  #define INTS_PER_STATEBLOCK  (sizeof(stateblock)/sizeof(int))  #define INTS_PER_STATEBLOCK  (int)(sizeof(stateblock)/sizeof(int))
289    
290    
291  #ifdef PCRE_DEBUG  #ifdef PCRE_DEBUG
# Line 303  Returns:       nothing Line 306  Returns:       nothing
306  static void  static void
307  pchars(const pcre_uchar *p, int length, FILE *f)  pchars(const pcre_uchar *p, int length, FILE *f)
308  {  {
309  int c;  pcre_uint32 c;
310  while (length-- > 0)  while (length-- > 0)
311    {    {
312    if (isprint(c = *(p++)))    if (isprint(c = *(p++)))
313      fprintf(f, "%c", c);      fprintf(f, "%c", c);
314    else    else
315      fprintf(f, "\\x%02x", c);      fprintf(f, "\\x{%02x}", c);
316    }    }
317  }  }
318  #endif  #endif
# Line 382  for the current character, one for the f Line 385  for the current character, one for the f
385      next_new_state->count  = (y); \      next_new_state->count  = (y); \
386      next_new_state->data   = (z); \      next_new_state->data   = (z); \
387      next_new_state++; \      next_new_state++; \
388      DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \      DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d) line %d\n", rlevel*2-2, SP, \
389          (x), (y), (z), __LINE__)); \
390      } \      } \
391    else return PCRE_ERROR_DFA_WSSIZE    else return PCRE_ERROR_DFA_WSSIZE
392    
# Line 424  BOOL utf = (md->poptions & PCRE_UTF8) != Line 428  BOOL utf = (md->poptions & PCRE_UTF8) !=
428  BOOL utf = FALSE;  BOOL utf = FALSE;
429  #endif  #endif
430    
431    BOOL reset_could_continue = FALSE;
432    
433  rlevel++;  rlevel++;
434  offsetcount &= (-2);  offsetcount &= (-2);
435    
# Line 569  for (;;) Line 575  for (;;)
575    {    {
576    int i, j;    int i, j;
577    int clen, dlen;    int clen, dlen;
578    unsigned int c, d;    pcre_uint32 c, d;
579    int forced_fail = 0;    int forced_fail = 0;
580    BOOL could_continue = FALSE;    BOOL partial_newline = FALSE;
581      BOOL could_continue = reset_could_continue;
582      reset_could_continue = FALSE;
583    
584    /* Make the new state list into the active state list and empty the    /* Make the new state list into the active state list and empty the
585    new state list. */    new state list. */
# Line 607  for (;;) Line 615  for (;;)
615    
616    if (ptr < end_subject)    if (ptr < end_subject)
617      {      {
618      clen = 1;        /* Number of bytes in the character */      clen = 1;        /* Number of data items in the character */
619  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
620      if (utf) { GETCHARLEN(c, ptr, clen); } else      GETCHARLENTEST(c, ptr, clen);
621  #endif  /* SUPPORT_UTF */  #else
622      c = *ptr;      c = *ptr;
623    #endif  /* SUPPORT_UTF */
624      }      }
625    else    else
626      {      {
# Line 630  for (;;) Line 639  for (;;)
639      BOOL caseless = FALSE;      BOOL caseless = FALSE;
640      const pcre_uchar *code;      const pcre_uchar *code;
641      int state_offset = current_state->offset;      int state_offset = current_state->offset;
642      int count, codevalue, rrc;      int codevalue, rrc;
643        int count;
644    
645  #ifdef PCRE_DEBUG  #ifdef PCRE_DEBUG
646      printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset);      printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset);
# Line 641  for (;;) Line 651  for (;;)
651    
652      /* A negative offset is a special case meaning "hold off going to this      /* A negative offset is a special case meaning "hold off going to this
653      (negated) state until the number of characters in the data field have      (negated) state until the number of characters in the data field have
654      been skipped". */      been skipped". If the could_continue flag was passed over from a previous
655        state, arrange for it to passed on. */
656    
657      if (state_offset < 0)      if (state_offset < 0)
658        {        {
# Line 650  for (;;) Line 661  for (;;)
661          DPRINTF(("%.*sSkipping this character\n", rlevel*2-2, SP));          DPRINTF(("%.*sSkipping this character\n", rlevel*2-2, SP));
662          ADD_NEW_DATA(state_offset, current_state->count,          ADD_NEW_DATA(state_offset, current_state->count,
663            current_state->data - 1);            current_state->data - 1);
664            if (could_continue) reset_could_continue = TRUE;
665          continue;          continue;
666          }          }
667        else        else
# Line 689  for (;;) Line 701  for (;;)
701      permitted.      permitted.
702    
703      We also use this mechanism for opcodes such as OP_TYPEPLUS that take an      We also use this mechanism for opcodes such as OP_TYPEPLUS that take an
704      argument that is not a data character - but is always one byte long. We      argument that is not a data character - but is always one byte long because
705      have to take special action to deal with  \P, \p, \H, \h, \V, \v and \X in      the values are small. We have to take special action to deal with  \P, \p,
706      this case. To keep the other cases fast, convert these ones to new opcodes.      \H, \h, \V, \v and \X in this case. To keep the other cases fast, convert
707      */      these ones to new opcodes. */
708    
709      if (coptable[codevalue] > 0)      if (coptable[codevalue] > 0)
710        {        {
# Line 783  for (;;) Line 795  for (;;)
795              offsets[0] = (int)(current_subject - start_subject);              offsets[0] = (int)(current_subject - start_subject);
796              offsets[1] = (int)(ptr - start_subject);              offsets[1] = (int)(ptr - start_subject);
797              DPRINTF(("%.*sSet matched string = \"%.*s\"\n", rlevel*2-2, SP,              DPRINTF(("%.*sSet matched string = \"%.*s\"\n", rlevel*2-2, SP,
798                offsets[1] - offsets[0], current_subject));                offsets[1] - offsets[0], (char *)current_subject));
799              }              }
800            if ((md->moptions & PCRE_DFA_SHORTEST) != 0)            if ((md->moptions & PCRE_DFA_SHORTEST) != 0)
801              {              {
# Line 888  for (;;) Line 900  for (;;)
900        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
901        case OP_ANY:        case OP_ANY:
902        if (clen > 0 && !IS_NEWLINE(ptr))        if (clen > 0 && !IS_NEWLINE(ptr))
903          { ADD_NEW(state_offset + 1, 0); }          {
904            if (ptr + 1 >= md->end_subject &&
905                (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
906                NLBLOCK->nltype == NLTYPE_FIXED &&
907                NLBLOCK->nllen == 2 &&
908                c == NLBLOCK->nl[0])
909              {
910              could_continue = partial_newline = TRUE;
911              }
912            else
913              {
914              ADD_NEW(state_offset + 1, 0);
915              }
916            }
917        break;        break;
918    
919        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
# Line 916  for (;;) Line 941  for (;;)
941                 (ptr == end_subject - md->nllen)                 (ptr == end_subject - md->nllen)
942              ))              ))
943            { ADD_ACTIVE(state_offset + 1, 0); }            { ADD_ACTIVE(state_offset + 1, 0); }
944            else if (ptr + 1 >= md->end_subject &&
945                     (md->moptions & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) != 0 &&
946                     NLBLOCK->nltype == NLTYPE_FIXED &&
947                     NLBLOCK->nllen == 2 &&
948                     c == NLBLOCK->nl[0])
949              {
950              if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
951                {
952                reset_could_continue = TRUE;
953                ADD_NEW_DATA(-(state_offset + 1), 0, 1);
954                }
955              else could_continue = partial_newline = TRUE;
956              }
957          }          }
958        break;        break;
959    
# Line 928  for (;;) Line 966  for (;;)
966          else if (clen == 0 ||          else if (clen == 0 ||
967              ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr)))              ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr)))
968            { ADD_ACTIVE(state_offset + 1, 0); }            { ADD_ACTIVE(state_offset + 1, 0); }
969            else if (ptr + 1 >= md->end_subject &&
970                     (md->moptions & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) != 0 &&
971                     NLBLOCK->nltype == NLTYPE_FIXED &&
972                     NLBLOCK->nllen == 2 &&
973                     c == NLBLOCK->nl[0])
974              {
975              if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
976                {
977                reset_could_continue = TRUE;
978                ADD_NEW_DATA(-(state_offset + 1), 0, 1);
979                }
980              else could_continue = partial_newline = TRUE;
981              }
982          }          }
983        else if (IS_NEWLINE(ptr))        else if (IS_NEWLINE(ptr))
984          { ADD_ACTIVE(state_offset + 1, 0); }          { ADD_ACTIVE(state_offset + 1, 0); }
# Line 962  for (;;) Line 1013  for (;;)
1013            {            {
1014            const pcre_uchar *temp = ptr - 1;            const pcre_uchar *temp = ptr - 1;
1015            if (temp < md->start_used_ptr) md->start_used_ptr = temp;            if (temp < md->start_used_ptr) md->start_used_ptr = temp;
1016  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1017            if (utf) { BACKCHAR(temp); }            if (utf) { BACKCHAR(temp); }
1018  #endif  #endif
1019            GETCHARTEST(d, temp);            GETCHARTEST(d, temp);
# Line 1015  for (;;) Line 1066  for (;;)
1066        if (clen > 0)        if (clen > 0)
1067          {          {
1068          BOOL OK;          BOOL OK;
1069            const pcre_uint32 *cp;
1070          const ucd_record * prop = GET_UCD(c);          const ucd_record * prop = GET_UCD(c);
1071          switch(code[1])          switch(code[1])
1072            {            {
# Line 1046  for (;;) Line 1098  for (;;)
1098                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;
1099            break;            break;
1100    
1101              /* Perl space used to exclude VT, but from Perl 5.18 it is included,
1102              which means that Perl space and POSIX space are now identical. PCRE
1103              was changed at release 8.34. */
1104    
1105            case PT_SPACE:    /* Perl space */            case PT_SPACE:    /* Perl space */
           OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||  
                c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;  
           break;  
   
1106            case PT_PXSPACE:  /* POSIX space */            case PT_PXSPACE:  /* POSIX space */
1107            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            switch(c)
1108                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||              {
1109                 c == CHAR_FF || c == CHAR_CR;              HSPACE_CASES:
1110                VSPACE_CASES:
1111                OK = TRUE;
1112                break;
1113    
1114                default:
1115                OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
1116                break;
1117                }
1118            break;            break;
1119    
1120            case PT_WORD:            case PT_WORD:
# Line 1063  for (;;) Line 1123  for (;;)
1123                 c == CHAR_UNDERSCORE;                 c == CHAR_UNDERSCORE;
1124            break;            break;
1125    
1126              case PT_CLIST:
1127              cp = PRIV(ucd_caseless_sets) + code[2];
1128              for (;;)
1129                {
1130                if (c < *cp) { OK = FALSE; break; }
1131                if (c == *cp++) { OK = TRUE; break; }
1132                }
1133              break;
1134    
1135              case PT_UCNC:
1136              OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
1137                   c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
1138                   c >= 0xe000;
1139              break;
1140    
1141            /* Should never occur, but keep compilers from grumbling. */            /* Should never occur, but keep compilers from grumbling. */
1142    
1143            default:            default:
# Line 1090  for (;;) Line 1165  for (;;)
1165        if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }        if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
1166        if (clen > 0)        if (clen > 0)
1167          {          {
1168          if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||          if (d == OP_ANY && ptr + 1 >= md->end_subject &&
1169                (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
1170                NLBLOCK->nltype == NLTYPE_FIXED &&
1171                NLBLOCK->nllen == 2 &&
1172                c == NLBLOCK->nl[0])
1173              {
1174              could_continue = partial_newline = TRUE;
1175              }
1176            else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
1177              (c < 256 &&              (c < 256 &&
1178                (d != OP_ANY || !IS_NEWLINE(ptr)) &&                (d != OP_ANY || !IS_NEWLINE(ptr)) &&
1179                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
# Line 1113  for (;;) Line 1196  for (;;)
1196        ADD_ACTIVE(state_offset + 2, 0);        ADD_ACTIVE(state_offset + 2, 0);
1197        if (clen > 0)        if (clen > 0)
1198          {          {
1199          if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||          if (d == OP_ANY && ptr + 1 >= md->end_subject &&
1200                (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
1201                NLBLOCK->nltype == NLTYPE_FIXED &&
1202                NLBLOCK->nllen == 2 &&
1203                c == NLBLOCK->nl[0])
1204              {
1205              could_continue = partial_newline = TRUE;
1206              }
1207            else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
1208              (c < 256 &&              (c < 256 &&
1209                (d != OP_ANY || !IS_NEWLINE(ptr)) &&                (d != OP_ANY || !IS_NEWLINE(ptr)) &&
1210                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
# Line 1135  for (;;) Line 1226  for (;;)
1226        ADD_ACTIVE(state_offset + 2, 0);        ADD_ACTIVE(state_offset + 2, 0);
1227        if (clen > 0)        if (clen > 0)
1228          {          {
1229          if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||          if (d == OP_ANY && ptr + 1 >= md->end_subject &&
1230                (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
1231                NLBLOCK->nltype == NLTYPE_FIXED &&
1232                NLBLOCK->nllen == 2 &&
1233                c == NLBLOCK->nl[0])
1234              {
1235              could_continue = partial_newline = TRUE;
1236              }
1237            else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
1238              (c < 256 &&              (c < 256 &&
1239                (d != OP_ANY || !IS_NEWLINE(ptr)) &&                (d != OP_ANY || !IS_NEWLINE(ptr)) &&
1240                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
# Line 1155  for (;;) Line 1254  for (;;)
1254        count = current_state->count;  /* Number already matched */        count = current_state->count;  /* Number already matched */
1255        if (clen > 0)        if (clen > 0)
1256          {          {
1257          if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||          if (d == OP_ANY && ptr + 1 >= md->end_subject &&
1258                (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
1259                NLBLOCK->nltype == NLTYPE_FIXED &&
1260                NLBLOCK->nllen == 2 &&
1261                c == NLBLOCK->nl[0])
1262              {
1263              could_continue = partial_newline = TRUE;
1264              }
1265            else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
1266              (c < 256 &&              (c < 256 &&
1267                (d != OP_ANY || !IS_NEWLINE(ptr)) &&                (d != OP_ANY || !IS_NEWLINE(ptr)) &&
1268                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
1269            {            {
1270            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
1271              { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); }              { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); }
1272            else            else
1273              { ADD_NEW(state_offset, count); }              { ADD_NEW(state_offset, count); }
# Line 1176  for (;;) Line 1283  for (;;)
1283        count = current_state->count;  /* Number already matched */        count = current_state->count;  /* Number already matched */
1284        if (clen > 0)        if (clen > 0)
1285          {          {
1286          if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||          if (d == OP_ANY && ptr + 1 >= md->end_subject &&
1287                (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
1288                NLBLOCK->nltype == NLTYPE_FIXED &&
1289                NLBLOCK->nllen == 2 &&
1290                c == NLBLOCK->nl[0])
1291              {
1292              could_continue = partial_newline = TRUE;
1293              }
1294            else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
1295              (c < 256 &&              (c < 256 &&
1296                (d != OP_ANY || !IS_NEWLINE(ptr)) &&                (d != OP_ANY || !IS_NEWLINE(ptr)) &&
1297                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
# Line 1186  for (;;) Line 1301  for (;;)
1301              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
1302              next_active_state--;              next_active_state--;
1303              }              }
1304            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
1305              { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); }              { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); }
1306            else            else
1307              { ADD_NEW(state_offset, count); }              { ADD_NEW(state_offset, count); }
# Line 1209  for (;;) Line 1324  for (;;)
1324        if (clen > 0)        if (clen > 0)
1325          {          {
1326          BOOL OK;          BOOL OK;
1327            const pcre_uint32 *cp;
1328          const ucd_record * prop = GET_UCD(c);          const ucd_record * prop = GET_UCD(c);
1329          switch(code[2])          switch(code[2])
1330            {            {
# Line 1240  for (;;) Line 1356  for (;;)
1356                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;
1357            break;            break;
1358    
1359              /* Perl space used to exclude VT, but from Perl 5.18 it is included,
1360              which means that Perl space and POSIX space are now identical. PCRE
1361              was changed at release 8.34. */
1362    
1363            case PT_SPACE:    /* Perl space */            case PT_SPACE:    /* Perl space */
           OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||  
                c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;  
           break;  
   
1364            case PT_PXSPACE:  /* POSIX space */            case PT_PXSPACE:  /* POSIX space */
1365            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            switch(c)
1366                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||              {
1367                 c == CHAR_FF || c == CHAR_CR;              HSPACE_CASES:
1368                VSPACE_CASES:
1369                OK = TRUE;
1370                break;
1371    
1372                default:
1373                OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
1374                break;
1375                }
1376            break;            break;
1377    
1378            case PT_WORD:            case PT_WORD:
# Line 1257  for (;;) Line 1381  for (;;)
1381                 c == CHAR_UNDERSCORE;                 c == CHAR_UNDERSCORE;
1382            break;            break;
1383    
1384              case PT_CLIST:
1385              cp = PRIV(ucd_caseless_sets) + code[3];
1386              for (;;)
1387                {
1388                if (c < *cp) { OK = FALSE; break; }
1389                if (c == *cp++) { OK = TRUE; break; }
1390                }
1391              break;
1392    
1393              case PT_UCNC:
1394              OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
1395                   c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
1396                   c >= 0xe000;
1397              break;
1398    
1399            /* Should never occur, but keep compilers from grumbling. */            /* Should never occur, but keep compilers from grumbling. */
1400    
1401            default:            default:
# Line 1283  for (;;) Line 1422  for (;;)
1422        case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS:        case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS:
1423        count = current_state->count;  /* Already matched */        count = current_state->count;  /* Already matched */
1424        if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }        if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
1425        if (clen > 0 && UCD_CATEGORY(c) != ucp_M)        if (clen > 0)
1426          {          {
1427            int lgb, rgb;
1428          const pcre_uchar *nptr = ptr + clen;          const pcre_uchar *nptr = ptr + clen;
1429          int ncount = 0;          int ncount = 0;
1430          if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)          if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)
# Line 1292  for (;;) Line 1432  for (;;)
1432            active_count--;           /* Remove non-match possibility */            active_count--;           /* Remove non-match possibility */
1433            next_active_state--;            next_active_state--;
1434            }            }
1435            lgb = UCD_GRAPHBREAK(c);
1436          while (nptr < end_subject)          while (nptr < end_subject)
1437            {            {
1438            int nd;            dlen = 1;
1439            int ndlen = 1;            if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
1440            GETCHARLEN(nd, nptr, ndlen);            rgb = UCD_GRAPHBREAK(d);
1441            if (UCD_CATEGORY(nd) != ucp_M) break;            if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
1442            ncount++;            ncount++;
1443            nptr += ndlen;            lgb = rgb;
1444              nptr += dlen;
1445            }            }
1446          count++;          count++;
1447          ADD_NEW_DATA(-state_offset, count, ncount);          ADD_NEW_DATA(-state_offset, count, ncount);
# Line 1318  for (;;) Line 1460  for (;;)
1460          int ncount = 0;          int ncount = 0;
1461          switch (c)          switch (c)
1462            {            {
1463            case 0x000b:            case CHAR_VT:
1464            case 0x000c:            case CHAR_FF:
1465            case 0x0085:            case CHAR_NEL:
1466    #ifndef EBCDIC
1467            case 0x2028:            case 0x2028:
1468            case 0x2029:            case 0x2029:
1469    #endif  /* Not EBCDIC */
1470            if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;            if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
1471            goto ANYNL01;            goto ANYNL01;
1472    
1473            case 0x000d:            case CHAR_CR:
1474            if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;            if (ptr + 1 < end_subject && RAWUCHARTEST(ptr + 1) == CHAR_LF) ncount = 1;
1475            /* Fall through */            /* Fall through */
1476    
1477            ANYNL01:            ANYNL01:
1478            case 0x000a:            case CHAR_LF:
1479            if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS)            if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS)
1480              {              {
1481              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
# Line 1358  for (;;) Line 1502  for (;;)
1502          BOOL OK;          BOOL OK;
1503          switch (c)          switch (c)
1504            {            {
1505            case 0x000a:            VSPACE_CASES:
           case 0x000b:  
           case 0x000c:  
           case 0x000d:  
           case 0x0085:  
           case 0x2028:  
           case 0x2029:  
1506            OK = TRUE;            OK = TRUE;
1507            break;            break;
1508    
# Line 1397  for (;;) Line 1535  for (;;)
1535          BOOL OK;          BOOL OK;
1536          switch (c)          switch (c)
1537            {            {
1538            case 0x09:      /* HT */            HSPACE_CASES:
           case 0x20:      /* SPACE */  
           case 0xa0:      /* NBSP */  
           case 0x1680:    /* OGHAM SPACE MARK */  
           case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */  
           case 0x2000:    /* EN QUAD */  
           case 0x2001:    /* EM QUAD */  
           case 0x2002:    /* EN SPACE */  
           case 0x2003:    /* EM SPACE */  
           case 0x2004:    /* THREE-PER-EM SPACE */  
           case 0x2005:    /* FOUR-PER-EM SPACE */  
           case 0x2006:    /* SIX-PER-EM SPACE */  
           case 0x2007:    /* FIGURE SPACE */  
           case 0x2008:    /* PUNCTUATION SPACE */  
           case 0x2009:    /* THIN SPACE */  
           case 0x200A:    /* HAIR SPACE */  
           case 0x202f:    /* NARROW NO-BREAK SPACE */  
           case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */  
           case 0x3000:    /* IDEOGRAPHIC SPACE */  
1539            OK = TRUE;            OK = TRUE;
1540            break;            break;
1541    
# Line 1456  for (;;) Line 1576  for (;;)
1576        if (clen > 0)        if (clen > 0)
1577          {          {
1578          BOOL OK;          BOOL OK;
1579            const pcre_uint32 *cp;
1580          const ucd_record * prop = GET_UCD(c);          const ucd_record * prop = GET_UCD(c);
1581          switch(code[2])          switch(code[2])
1582            {            {
# Line 1487  for (;;) Line 1608  for (;;)
1608                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;
1609            break;            break;
1610    
1611              /* Perl space used to exclude VT, but from Perl 5.18 it is included,
1612              which means that Perl space and POSIX space are now identical. PCRE
1613              was changed at release 8.34. */
1614    
1615            case PT_SPACE:    /* Perl space */            case PT_SPACE:    /* Perl space */
           OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||  
                c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;  
           break;  
   
1616            case PT_PXSPACE:  /* POSIX space */            case PT_PXSPACE:  /* POSIX space */
1617            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            switch(c)
1618                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||              {
1619                 c == CHAR_FF || c == CHAR_CR;              HSPACE_CASES:
1620                VSPACE_CASES:
1621                OK = TRUE;
1622                break;
1623    
1624                default:
1625                OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
1626                break;
1627                }
1628            break;            break;
1629    
1630            case PT_WORD:            case PT_WORD:
# Line 1504  for (;;) Line 1633  for (;;)
1633                 c == CHAR_UNDERSCORE;                 c == CHAR_UNDERSCORE;
1634            break;            break;
1635    
1636              case PT_CLIST:
1637              cp = PRIV(ucd_caseless_sets) + code[3];
1638              for (;;)
1639                {
1640                if (c < *cp) { OK = FALSE; break; }
1641                if (c == *cp++) { OK = TRUE; break; }
1642                }
1643              break;
1644    
1645              case PT_UCNC:
1646              OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
1647                   c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
1648                   c >= 0xe000;
1649              break;
1650    
1651            /* Should never occur, but keep compilers from grumbling. */            /* Should never occur, but keep compilers from grumbling. */
1652    
1653            default:            default:
# Line 1539  for (;;) Line 1683  for (;;)
1683        QS2:        QS2:
1684    
1685        ADD_ACTIVE(state_offset + 2, 0);        ADD_ACTIVE(state_offset + 2, 0);
1686        if (clen > 0 && UCD_CATEGORY(c) != ucp_M)        if (clen > 0)
1687          {          {
1688            int lgb, rgb;
1689          const pcre_uchar *nptr = ptr + clen;          const pcre_uchar *nptr = ptr + clen;
1690          int ncount = 0;          int ncount = 0;
1691          if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||          if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||
# Line 1549  for (;;) Line 1694  for (;;)
1694            active_count--;           /* Remove non-match possibility */            active_count--;           /* Remove non-match possibility */
1695            next_active_state--;            next_active_state--;
1696            }            }
1697            lgb = UCD_GRAPHBREAK(c);
1698          while (nptr < end_subject)          while (nptr < end_subject)
1699            {            {
1700            int nd;            dlen = 1;
1701            int ndlen = 1;            if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
1702            GETCHARLEN(nd, nptr, ndlen);            rgb = UCD_GRAPHBREAK(d);
1703            if (UCD_CATEGORY(nd) != ucp_M) break;            if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
1704            ncount++;            ncount++;
1705            nptr += ndlen;            lgb = rgb;
1706              nptr += dlen;
1707            }            }
1708          ADD_NEW_DATA(-(state_offset + count), 0, ncount);          ADD_NEW_DATA(-(state_offset + count), 0, ncount);
1709          }          }
# Line 1582  for (;;) Line 1729  for (;;)
1729          int ncount = 0;          int ncount = 0;
1730          switch (c)          switch (c)
1731            {            {
1732            case 0x000b:            case CHAR_VT:
1733            case 0x000c:            case CHAR_FF:
1734            case 0x0085:            case CHAR_NEL:
1735    #ifndef EBCDIC
1736            case 0x2028:            case 0x2028:
1737            case 0x2029:            case 0x2029:
1738    #endif  /* Not EBCDIC */
1739            if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;            if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
1740            goto ANYNL02;            goto ANYNL02;
1741    
1742            case 0x000d:            case CHAR_CR:
1743            if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;            if (ptr + 1 < end_subject && RAWUCHARTEST(ptr + 1) == CHAR_LF) ncount = 1;
1744            /* Fall through */            /* Fall through */
1745    
1746            ANYNL02:            ANYNL02:
1747            case 0x000a:            case CHAR_LF:
1748            if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR ||            if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR ||
1749                codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY)                codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY)
1750              {              {
1751              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
1752              next_active_state--;              next_active_state--;
1753              }              }
1754            ADD_NEW_DATA(-(state_offset + count), 0, ncount);            ADD_NEW_DATA(-(state_offset + (int)count), 0, ncount);
1755            break;            break;
1756    
1757            default:            default:
# Line 1630  for (;;) Line 1779  for (;;)
1779          BOOL OK;          BOOL OK;
1780          switch (c)          switch (c)
1781            {            {
1782            case 0x000a:            VSPACE_CASES:
           case 0x000b:  
           case 0x000c:  
           case 0x000d:  
           case 0x0085:  
           case 0x2028:  
           case 0x2029:  
1783            OK = TRUE;            OK = TRUE;
1784            break;            break;
1785    
# Line 1652  for (;;) Line 1795  for (;;)
1795              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
1796              next_active_state--;              next_active_state--;
1797              }              }
1798            ADD_NEW_DATA(-(state_offset + count), 0, 0);            ADD_NEW_DATA(-(state_offset + (int)count), 0, 0);
1799            }            }
1800          }          }
1801        break;        break;
# Line 1676  for (;;) Line 1819  for (;;)
1819          BOOL OK;          BOOL OK;
1820          switch (c)          switch (c)
1821            {            {
1822            case 0x09:      /* HT */            HSPACE_CASES:
           case 0x20:      /* SPACE */  
           case 0xa0:      /* NBSP */  
           case 0x1680:    /* OGHAM SPACE MARK */  
           case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */  
           case 0x2000:    /* EN QUAD */  
           case 0x2001:    /* EM QUAD */  
           case 0x2002:    /* EN SPACE */  
           case 0x2003:    /* EM SPACE */  
           case 0x2004:    /* THREE-PER-EM SPACE */  
           case 0x2005:    /* FOUR-PER-EM SPACE */  
           case 0x2006:    /* SIX-PER-EM SPACE */  
           case 0x2007:    /* FIGURE SPACE */  
           case 0x2008:    /* PUNCTUATION SPACE */  
           case 0x2009:    /* THIN SPACE */  
           case 0x200A:    /* HAIR SPACE */  
           case 0x202f:    /* NARROW NO-BREAK SPACE */  
           case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */  
           case 0x3000:    /* IDEOGRAPHIC SPACE */  
1823            OK = TRUE;            OK = TRUE;
1824            break;            break;
1825    
# Line 1711  for (;;) Line 1836  for (;;)
1836              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
1837              next_active_state--;              next_active_state--;
1838              }              }
1839            ADD_NEW_DATA(-(state_offset + count), 0, 0);            ADD_NEW_DATA(-(state_offset + (int)count), 0, 0);
1840            }            }
1841          }          }
1842        break;        break;
# Line 1728  for (;;) Line 1853  for (;;)
1853        if (clen > 0)        if (clen > 0)
1854          {          {
1855          BOOL OK;          BOOL OK;
1856            const pcre_uint32 *cp;
1857          const ucd_record * prop = GET_UCD(c);          const ucd_record * prop = GET_UCD(c);
1858          switch(code[1 + IMM2_SIZE + 1])          switch(code[1 + IMM2_SIZE + 1])
1859            {            {
# Line 1759  for (;;) Line 1885  for (;;)
1885                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;
1886            break;            break;
1887    
1888              /* Perl space used to exclude VT, but from Perl 5.18 it is included,
1889              which means that Perl space and POSIX space are now identical. PCRE
1890              was changed at release 8.34. */
1891    
1892            case PT_SPACE:    /* Perl space */            case PT_SPACE:    /* Perl space */
           OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||  
                c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;  
           break;  
   
1893            case PT_PXSPACE:  /* POSIX space */            case PT_PXSPACE:  /* POSIX space */
1894            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            switch(c)
1895                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||              {
1896                 c == CHAR_FF || c == CHAR_CR;              HSPACE_CASES:
1897                VSPACE_CASES:
1898                OK = TRUE;
1899                break;
1900    
1901                default:
1902                OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
1903                break;
1904                }
1905            break;            break;
1906    
1907            case PT_WORD:            case PT_WORD:
# Line 1776  for (;;) Line 1910  for (;;)
1910                 c == CHAR_UNDERSCORE;                 c == CHAR_UNDERSCORE;
1911            break;            break;
1912    
1913              case PT_CLIST:
1914              cp = PRIV(ucd_caseless_sets) + code[1 + IMM2_SIZE + 2];
1915              for (;;)
1916                {
1917                if (c < *cp) { OK = FALSE; break; }
1918                if (c == *cp++) { OK = TRUE; break; }
1919                }
1920              break;
1921    
1922              case PT_UCNC:
1923              OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
1924                   c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
1925                   c >= 0xe000;
1926              break;
1927    
1928            /* Should never occur, but keep compilers from grumbling. */            /* Should never occur, but keep compilers from grumbling. */
1929    
1930            default:            default:
# Line 1790  for (;;) Line 1939  for (;;)
1939              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
1940              next_active_state--;              next_active_state--;
1941              }              }
1942            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
1943              { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); }              { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); }
1944            else            else
1945              { ADD_NEW(state_offset, count); }              { ADD_NEW(state_offset, count); }
# Line 1806  for (;;) Line 1955  for (;;)
1955        if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT)        if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT)
1956          { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }          { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
1957        count = current_state->count;  /* Number already matched */        count = current_state->count;  /* Number already matched */
1958        if (clen > 0 && UCD_CATEGORY(c) != ucp_M)        if (clen > 0)
1959          {          {
1960            int lgb, rgb;
1961          const pcre_uchar *nptr = ptr + clen;          const pcre_uchar *nptr = ptr + clen;
1962          int ncount = 0;          int ncount = 0;
1963          if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)          if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)
# Line 1815  for (;;) Line 1965  for (;;)
1965            active_count--;           /* Remove non-match possibility */            active_count--;           /* Remove non-match possibility */
1966            next_active_state--;            next_active_state--;
1967            }            }
1968            lgb = UCD_GRAPHBREAK(c);
1969          while (nptr < end_subject)          while (nptr < end_subject)
1970            {            {
1971            int nd;            dlen = 1;
1972            int ndlen = 1;            if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
1973            GETCHARLEN(nd, nptr, ndlen);            rgb = UCD_GRAPHBREAK(d);
1974            if (UCD_CATEGORY(nd) != ucp_M) break;            if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
1975            ncount++;            ncount++;
1976            nptr += ndlen;            lgb = rgb;
1977              nptr += dlen;
1978            }            }
1979          if (++count >= GET2(code, 1))          if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0)
1980                reset_could_continue = TRUE;
1981            if (++count >= (int)GET2(code, 1))
1982            { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }            { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
1983          else          else
1984            { ADD_NEW_DATA(-state_offset, count, ncount); }            { ADD_NEW_DATA(-state_offset, count, ncount); }
# Line 1845  for (;;) Line 1999  for (;;)
1999          int ncount = 0;          int ncount = 0;
2000          switch (c)          switch (c)
2001            {            {
2002            case 0x000b:            case CHAR_VT:
2003            case 0x000c:            case CHAR_FF:
2004            case 0x0085:            case CHAR_NEL:
2005    #ifndef EBCDIC
2006            case 0x2028:            case 0x2028:
2007            case 0x2029:            case 0x2029:
2008    #endif  /* Not EBCDIC */
2009            if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;            if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
2010            goto ANYNL03;            goto ANYNL03;
2011    
2012            case 0x000d:            case CHAR_CR:
2013            if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;            if (ptr + 1 < end_subject && RAWUCHARTEST(ptr + 1) == CHAR_LF) ncount = 1;
2014            /* Fall through */            /* Fall through */
2015    
2016            ANYNL03:            ANYNL03:
2017            case 0x000a:            case CHAR_LF:
2018            if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO)            if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO)
2019              {              {
2020              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
2021              next_active_state--;              next_active_state--;
2022              }              }
2023            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
2024              { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }              { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
2025            else            else
2026              { ADD_NEW_DATA(-state_offset, count, ncount); }              { ADD_NEW_DATA(-state_offset, count, ncount); }
# Line 1889  for (;;) Line 2045  for (;;)
2045          BOOL OK;          BOOL OK;
2046          switch (c)          switch (c)
2047            {            {
2048            case 0x000a:            VSPACE_CASES:
           case 0x000b:  
           case 0x000c:  
           case 0x000d:  
           case 0x0085:  
           case 0x2028:  
           case 0x2029:  
2049            OK = TRUE;            OK = TRUE;
2050            break;            break;
2051    
# Line 1910  for (;;) Line 2060  for (;;)
2060              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
2061              next_active_state--;              next_active_state--;
2062              }              }
2063            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
2064              { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }              { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
2065            else            else
2066              { ADD_NEW_DATA(-state_offset, count, 0); }              { ADD_NEW_DATA(-state_offset, count, 0); }
# Line 1931  for (;;) Line 2081  for (;;)
2081          BOOL OK;          BOOL OK;
2082          switch (c)          switch (c)
2083            {            {
2084            case 0x09:      /* HT */            HSPACE_CASES:
           case 0x20:      /* SPACE */  
           case 0xa0:      /* NBSP */  
           case 0x1680:    /* OGHAM SPACE MARK */  
           case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */  
           case 0x2000:    /* EN QUAD */  
           case 0x2001:    /* EM QUAD */  
           case 0x2002:    /* EN SPACE */  
           case 0x2003:    /* EM SPACE */  
           case 0x2004:    /* THREE-PER-EM SPACE */  
           case 0x2005:    /* FOUR-PER-EM SPACE */  
           case 0x2006:    /* SIX-PER-EM SPACE */  
           case 0x2007:    /* FIGURE SPACE */  
           case 0x2008:    /* PUNCTUATION SPACE */  
           case 0x2009:    /* THIN SPACE */  
           case 0x200A:    /* HAIR SPACE */  
           case 0x202f:    /* NARROW NO-BREAK SPACE */  
           case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */  
           case 0x3000:    /* IDEOGRAPHIC SPACE */  
2085            OK = TRUE;            OK = TRUE;
2086            break;            break;
2087    
# Line 1965  for (;;) Line 2097  for (;;)
2097              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
2098              next_active_state--;              next_active_state--;
2099              }              }
2100            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
2101              { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }              { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
2102            else            else
2103              { ADD_NEW_DATA(-state_offset, count, 0); }              { ADD_NEW_DATA(-state_offset, count, 0); }
# Line 2025  for (;;) Line 2157  for (;;)
2157        to wait for them to pass before continuing. */        to wait for them to pass before continuing. */
2158    
2159        case OP_EXTUNI:        case OP_EXTUNI:
2160        if (clen > 0 && UCD_CATEGORY(c) != ucp_M)        if (clen > 0)
2161          {          {
2162            int lgb, rgb;
2163          const pcre_uchar *nptr = ptr + clen;          const pcre_uchar *nptr = ptr + clen;
2164          int ncount = 0;          int ncount = 0;
2165            lgb = UCD_GRAPHBREAK(c);
2166          while (nptr < end_subject)          while (nptr < end_subject)
2167            {            {
2168            int nclen = 1;            dlen = 1;
2169            GETCHARLEN(c, nptr, nclen);            if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
2170            if (UCD_CATEGORY(c) != ucp_M) break;            rgb = UCD_GRAPHBREAK(d);
2171              if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
2172            ncount++;            ncount++;
2173            nptr += nclen;            lgb = rgb;
2174              nptr += dlen;
2175            }            }
2176            if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0)
2177                reset_could_continue = TRUE;
2178          ADD_NEW_DATA(-(state_offset + 1), 0, ncount);          ADD_NEW_DATA(-(state_offset + 1), 0, ncount);
2179          }          }
2180        break;        break;
# Line 2050  for (;;) Line 2188  for (;;)
2188        case OP_ANYNL:        case OP_ANYNL:
2189        if (clen > 0) switch(c)        if (clen > 0) switch(c)
2190          {          {
2191          case 0x000b:          case CHAR_VT:
2192          case 0x000c:          case CHAR_FF:
2193          case 0x0085:          case CHAR_NEL:
2194    #ifndef EBCDIC
2195          case 0x2028:          case 0x2028:
2196          case 0x2029:          case 0x2029:
2197    #endif  /* Not EBCDIC */
2198          if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;          if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
2199    
2200          case 0x000a:          case CHAR_LF:
2201          ADD_NEW(state_offset + 1, 0);          ADD_NEW(state_offset + 1, 0);
2202          break;          break;
2203    
2204          case 0x000d:          case CHAR_CR:
2205          if (ptr + 1 < end_subject && ptr[1] == 0x0a)          if (ptr + 1 >= end_subject)
2206              {
2207              ADD_NEW(state_offset + 1, 0);
2208              if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
2209                reset_could_continue = TRUE;
2210              }
2211            else if (RAWUCHARTEST(ptr + 1) == CHAR_LF)
2212            {            {
2213            ADD_NEW_DATA(-(state_offset + 1), 0, 1);            ADD_NEW_DATA(-(state_offset + 1), 0, 1);
2214            }            }
# Line 2078  for (;;) Line 2224  for (;;)
2224        case OP_NOT_VSPACE:        case OP_NOT_VSPACE:
2225        if (clen > 0) switch(c)        if (clen > 0) switch(c)
2226          {          {
2227          case 0x000a:          VSPACE_CASES:
         case 0x000b:  
         case 0x000c:  
         case 0x000d:  
         case 0x0085:  
         case 0x2028:  
         case 0x2029:  
2228          break;          break;
2229    
2230          default:          default:
# Line 2097  for (;;) Line 2237  for (;;)
2237        case OP_VSPACE:        case OP_VSPACE:
2238        if (clen > 0) switch(c)        if (clen > 0) switch(c)
2239          {          {
2240          case 0x000a:          VSPACE_CASES:
         case 0x000b:  
         case 0x000c:  
         case 0x000d:  
         case 0x0085:  
         case 0x2028:  
         case 0x2029:  
2241          ADD_NEW(state_offset + 1, 0);          ADD_NEW(state_offset + 1, 0);
2242          break;          break;
2243    
2244          default: break;          default:
2245            break;
2246          }          }
2247        break;        break;
2248    
# Line 2115  for (;;) Line 2250  for (;;)
2250        case OP_NOT_HSPACE:        case OP_NOT_HSPACE:
2251        if (clen > 0) switch(c)        if (clen > 0) switch(c)
2252          {          {
2253          case 0x09:      /* HT */          HSPACE_CASES:
         case 0x20:      /* SPACE */  
         case 0xa0:      /* NBSP */  
         case 0x1680:    /* OGHAM SPACE MARK */  
         case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */  
         case 0x2000:    /* EN QUAD */  
         case 0x2001:    /* EM QUAD */  
         case 0x2002:    /* EN SPACE */  
         case 0x2003:    /* EM SPACE */  
         case 0x2004:    /* THREE-PER-EM SPACE */  
         case 0x2005:    /* FOUR-PER-EM SPACE */  
         case 0x2006:    /* SIX-PER-EM SPACE */  
         case 0x2007:    /* FIGURE SPACE */  
         case 0x2008:    /* PUNCTUATION SPACE */  
         case 0x2009:    /* THIN SPACE */  
         case 0x200A:    /* HAIR SPACE */  
         case 0x202f:    /* NARROW NO-BREAK SPACE */  
         case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */  
         case 0x3000:    /* IDEOGRAPHIC SPACE */  
2254          break;          break;
2255    
2256          default:          default:
# Line 2146  for (;;) Line 2263  for (;;)
2263        case OP_HSPACE:        case OP_HSPACE:
2264        if (clen > 0) switch(c)        if (clen > 0) switch(c)
2265          {          {
2266          case 0x09:      /* HT */          HSPACE_CASES:
         case 0x20:      /* SPACE */  
         case 0xa0:      /* NBSP */  
         case 0x1680:    /* OGHAM SPACE MARK */  
         case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */  
         case 0x2000:    /* EN QUAD */  
         case 0x2001:    /* EM QUAD */  
         case 0x2002:    /* EN SPACE */  
         case 0x2003:    /* EM SPACE */  
         case 0x2004:    /* THREE-PER-EM SPACE */  
         case 0x2005:    /* FOUR-PER-EM SPACE */  
         case 0x2006:    /* SIX-PER-EM SPACE */  
         case 0x2007:    /* FIGURE SPACE */  
         case 0x2008:    /* PUNCTUATION SPACE */  
         case 0x2009:    /* THIN SPACE */  
         case 0x200A:    /* HAIR SPACE */  
         case 0x202f:    /* NARROW NO-BREAK SPACE */  
         case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */  
         case 0x3000:    /* IDEOGRAPHIC SPACE */  
2267          ADD_NEW(state_offset + 1, 0);          ADD_NEW(state_offset + 1, 0);
2268          break;          break;
2269    
2270            default:
2271            break;
2272          }          }
2273        break;        break;
2274    
2275        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
2276        /* Match a negated single character casefully. This is only used for        /* Match a negated single character casefully. */
       one-byte characters, that is, we know that d < 256. The character we are  
       checking (c) can be multibyte. */  
2277    
2278        case OP_NOT:        case OP_NOT:
2279        if (clen > 0 && c != d) { ADD_NEW(state_offset + dlen + 1, 0); }        if (clen > 0 && c != d) { ADD_NEW(state_offset + dlen + 1, 0); }
2280        break;        break;
2281    
2282        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
2283        /* Match a negated single character caselessly. This is only used for        /* Match a negated single character caselessly. */
       one-byte characters, that is, we know that d < 256. The character we are  
       checking (c) can be multibyte. */  
2284    
2285        case OP_NOTI:        case OP_NOTI:
2286        if (clen > 0 && c != d && c != fcc[d])        if (clen > 0)
2287          { ADD_NEW(state_offset + dlen + 1, 0); }          {
2288            unsigned int otherd;
2289    #ifdef SUPPORT_UTF
2290            if (utf && d >= 128)
2291              {
2292    #ifdef SUPPORT_UCP
2293              otherd = UCD_OTHERCASE(d);
2294    #endif  /* SUPPORT_UCP */
2295              }
2296            else
2297    #endif  /* SUPPORT_UTF */
2298            otherd = TABLE_GET(d, fcc, d);
2299            if (c != d && c != otherd)
2300              { ADD_NEW(state_offset + dlen + 1, 0); }
2301            }
2302        break;        break;
2303    
2304        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
# Line 2210  for (;;) Line 2322  for (;;)
2322        if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); }        if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); }
2323        if (clen > 0)        if (clen > 0)
2324          {          {
2325          unsigned int otherd = NOTACHAR;          pcre_uint32 otherd = NOTACHAR;
2326          if (caseless)          if (caseless)
2327            {            {
2328  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 2257  for (;;) Line 2369  for (;;)
2369        ADD_ACTIVE(state_offset + dlen + 1, 0);        ADD_ACTIVE(state_offset + dlen + 1, 0);
2370        if (clen > 0)        if (clen > 0)
2371          {          {
2372          unsigned int otherd = NOTACHAR;          pcre_uint32 otherd = NOTACHAR;
2373          if (caseless)          if (caseless)
2374            {            {
2375  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 2302  for (;;) Line 2414  for (;;)
2414        ADD_ACTIVE(state_offset + dlen + 1, 0);        ADD_ACTIVE(state_offset + dlen + 1, 0);
2415        if (clen > 0)        if (clen > 0)
2416          {          {
2417          unsigned int otherd = NOTACHAR;          pcre_uint32 otherd = NOTACHAR;
2418          if (caseless)          if (caseless)
2419            {            {
2420  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 2339  for (;;) Line 2451  for (;;)
2451        count = current_state->count;  /* Number already matched */        count = current_state->count;  /* Number already matched */
2452        if (clen > 0)        if (clen > 0)
2453          {          {
2454          unsigned int otherd = NOTACHAR;          pcre_uint32 otherd = NOTACHAR;
2455          if (caseless)          if (caseless)
2456            {            {
2457  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 2355  for (;;) Line 2467  for (;;)
2467            }            }
2468          if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))          if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
2469            {            {
2470            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
2471              { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }              { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
2472            else            else
2473              { ADD_NEW(state_offset, count); }              { ADD_NEW(state_offset, count); }
# Line 2383  for (;;) Line 2495  for (;;)
2495        count = current_state->count;  /* Number already matched */        count = current_state->count;  /* Number already matched */
2496        if (clen > 0)        if (clen > 0)
2497          {          {
2498          unsigned int otherd = NOTACHAR;          pcre_uint32 otherd = NOTACHAR;
2499          if (caseless)          if (caseless)
2500            {            {
2501  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 2404  for (;;) Line 2516  for (;;)
2516              active_count--;             /* Remove non-match possibility */              active_count--;             /* Remove non-match possibility */
2517              next_active_state--;              next_active_state--;
2518              }              }
2519            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
2520              { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }              { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
2521            else            else
2522              { ADD_NEW(state_offset, count); }              { ADD_NEW(state_offset, count); }
# Line 2477  for (;;) Line 2589  for (;;)
2589            case OP_CRRANGE:            case OP_CRRANGE:
2590            case OP_CRMINRANGE:            case OP_CRMINRANGE:
2591            count = current_state->count;  /* Already matched */            count = current_state->count;  /* Already matched */
2592            if (count >= GET2(ecode, 1))            if (count >= (int)GET2(ecode, 1))
2593              { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }              { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
2594            if (isinclass)            if (isinclass)
2595              {              {
2596              int max = GET2(ecode, 1 + IMM2_SIZE);              int max = (int)GET2(ecode, 1 + IMM2_SIZE);
2597              if (++count >= max && max != 0)   /* Max 0 => no limit */              if (++count >= max && max != 0)   /* Max 0 => no limit */
2598                { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }                { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
2599              else              else
# Line 2557  for (;;) Line 2669  for (;;)
2669              cb.version          = 1;   /* Version 1 of the callout block */              cb.version          = 1;   /* Version 1 of the callout block */
2670              cb.callout_number   = code[LINK_SIZE+2];              cb.callout_number   = code[LINK_SIZE+2];
2671              cb.offset_vector    = offsets;              cb.offset_vector    = offsets;
2672    #if defined COMPILE_PCRE8
2673              cb.subject          = (PCRE_SPTR)start_subject;              cb.subject          = (PCRE_SPTR)start_subject;
2674    #elif defined COMPILE_PCRE16
2675                cb.subject          = (PCRE_SPTR16)start_subject;
2676    #elif defined COMPILE_PCRE32
2677                cb.subject          = (PCRE_SPTR32)start_subject;
2678    #endif
2679              cb.subject_length   = (int)(end_subject - start_subject);              cb.subject_length   = (int)(end_subject - start_subject);
2680              cb.start_match      = (int)(current_subject - start_subject);              cb.start_match      = (int)(current_subject - start_subject);
2681              cb.current_position = (int)(ptr - start_subject);              cb.current_position = (int)(ptr - start_subject);
# Line 2575  for (;;) Line 2693  for (;;)
2693    
2694          condcode = code[LINK_SIZE+1];          condcode = code[LINK_SIZE+1];
2695    
2696          /* Back reference conditions are not supported */          /* Back reference conditions and duplicate named recursion conditions
2697            are not supported */
2698    
2699          if (condcode == OP_CREF || condcode == OP_NCREF)          if (condcode == OP_CREF || condcode == OP_DNCREF ||
2700                condcode == OP_DNRREF)
2701            return PCRE_ERROR_DFA_UCOND;            return PCRE_ERROR_DFA_UCOND;
2702    
2703          /* The DEFINE condition is always false */          /* The DEFINE condition is always false */
# Line 2589  for (;;) Line 2709  for (;;)
2709          which means "test if in any recursion". We can't test for specifically          which means "test if in any recursion". We can't test for specifically
2710          recursed groups. */          recursed groups. */
2711    
2712          else if (condcode == OP_RREF || condcode == OP_NRREF)          else if (condcode == OP_RREF)
2713            {            {
2714            int value = GET2(code, LINK_SIZE + 2);            int value = GET2(code, LINK_SIZE + 2);
2715            if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND;            if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND;
# Line 2686  for (;;) Line 2806  for (;;)
2806            {            {
2807            for (rc = rc*2 - 2; rc >= 0; rc -= 2)            for (rc = rc*2 - 2; rc >= 0; rc -= 2)
2808              {              {
             const pcre_uchar *p = start_subject + local_offsets[rc];  
             const pcre_uchar *pp = start_subject + local_offsets[rc+1];  
2809              int charcount = local_offsets[rc+1] - local_offsets[rc];              int charcount = local_offsets[rc+1] - local_offsets[rc];
2810  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2811              while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;              if (utf)
2812                  {
2813                  const pcre_uchar *p = start_subject + local_offsets[rc];
2814                  const pcre_uchar *pp = start_subject + local_offsets[rc+1];
2815                  while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
2816                  }
2817  #endif  #endif
2818              if (charcount > 0)              if (charcount > 0)
2819                {                {
# Line 2788  for (;;) Line 2911  for (;;)
2911              const pcre_uchar *p = ptr;              const pcre_uchar *p = ptr;
2912              const pcre_uchar *pp = local_ptr;              const pcre_uchar *pp = local_ptr;
2913              charcount = (int)(pp - p);              charcount = (int)(pp - p);
2914  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2915              while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;              if (utf) while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
2916  #endif  #endif
2917              ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1));              ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1));
2918              }              }
# Line 2870  for (;;) Line 2993  for (;;)
2993              }              }
2994            else            else
2995              {              {
2996  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2997              const pcre_uchar *p = start_subject + local_offsets[0];              if (utf)
2998              const pcre_uchar *pp = start_subject + local_offsets[1];                {
2999              while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;                const pcre_uchar *p = start_subject + local_offsets[0];
3000                  const pcre_uchar *pp = start_subject + local_offsets[1];
3001                  while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
3002                  }
3003  #endif  #endif
3004              ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1));              ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1));
3005              if (repeat_state_offset >= 0)              if (repeat_state_offset >= 0)
# Line 2896  for (;;) Line 3022  for (;;)
3022          cb.version          = 1;   /* Version 1 of the callout block */          cb.version          = 1;   /* Version 1 of the callout block */
3023          cb.callout_number   = code[1];          cb.callout_number   = code[1];
3024          cb.offset_vector    = offsets;          cb.offset_vector    = offsets;
3025    #if defined COMPILE_PCRE8
3026          cb.subject          = (PCRE_SPTR)start_subject;          cb.subject          = (PCRE_SPTR)start_subject;
3027    #elif defined COMPILE_PCRE16
3028            cb.subject          = (PCRE_SPTR16)start_subject;
3029    #elif defined COMPILE_PCRE32
3030            cb.subject          = (PCRE_SPTR32)start_subject;
3031    #endif
3032          cb.subject_length   = (int)(end_subject - start_subject);          cb.subject_length   = (int)(end_subject - start_subject);
3033          cb.start_match      = (int)(current_subject - start_subject);          cb.start_match      = (int)(current_subject - start_subject);
3034          cb.current_position = (int)(ptr - start_subject);          cb.current_position = (int)(ptr - start_subject);
# Line 2938  for (;;) Line 3070  for (;;)
3070    if (new_count <= 0)    if (new_count <= 0)
3071      {      {
3072      if (rlevel == 1 &&                               /* Top level, and */      if (rlevel == 1 &&                               /* Top level, and */
3073          could_continue &&                            /* Some could go on */          could_continue &&                            /* Some could go on, and */
3074          forced_fail != workspace[1] &&               /* Not all forced fail & */          forced_fail != workspace[1] &&               /* Not all forced fail & */
3075          (                                            /* either... */          (                                            /* either... */
3076          (md->moptions & PCRE_PARTIAL_HARD) != 0      /* Hard partial */          (md->moptions & PCRE_PARTIAL_HARD) != 0      /* Hard partial */
# Line 2946  for (;;) Line 3078  for (;;)
3078          ((md->moptions & PCRE_PARTIAL_SOFT) != 0 &&  /* Soft partial and */          ((md->moptions & PCRE_PARTIAL_SOFT) != 0 &&  /* Soft partial and */
3079           match_count < 0)                            /* no matches */           match_count < 0)                            /* no matches */
3080          ) &&                                         /* And... */          ) &&                                         /* And... */
3081          ptr >= end_subject &&                  /* Reached end of subject */          (
3082          ptr > md->start_used_ptr)              /* Inspected non-empty string */          partial_newline ||                           /* Either partial NL */
3083        {            (                                          /* or ... */
3084        if (offsetcount >= 2)            ptr >= end_subject &&                /* End of subject and */
3085          {            ptr > md->start_used_ptr)            /* Inspected non-empty string */
3086          offsets[0] = (int)(md->start_used_ptr - start_subject);            )
3087          offsets[1] = (int)(end_subject - start_subject);          )
         }  
3088        match_count = PCRE_ERROR_PARTIAL;        match_count = PCRE_ERROR_PARTIAL;
       }  
   
3089      DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n"      DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n"
3090        "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, match_count,        "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, match_count,
3091        rlevel*2-2, SP));        rlevel*2-2, SP));
# Line 3006  Returns:          > 0 => number of match Line 3135  Returns:          > 0 => number of match
3135                   < -1 => some kind of unexpected problem                   < -1 => some kind of unexpected problem
3136  */  */
3137    
3138  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3139  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
3140  pcre_dfa_exec(const pcre *argument_re, const pcre_extra *extra_data,  pcre_dfa_exec(const pcre *argument_re, const pcre_extra *extra_data,
3141    const char *subject, int length, int start_offset, int options, int *offsets,    const char *subject, int length, int start_offset, int options, int *offsets,
3142    int offsetcount, int *workspace, int wscount)    int offsetcount, int *workspace, int wscount)
3143  #else  #elif defined COMPILE_PCRE16
3144  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
3145  pcre16_dfa_exec(const pcre *argument_re, const pcre16_extra *extra_data,  pcre16_dfa_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
3146    PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,    PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,
3147    int offsetcount, int *workspace, int wscount)    int offsetcount, int *workspace, int wscount)
3148    #elif defined COMPILE_PCRE32
3149    PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
3150    pcre32_dfa_exec(const pcre32 *argument_re, const pcre32_extra *extra_data,
3151      PCRE_SPTR32 subject, int length, int start_offset, int options, int *offsets,
3152      int offsetcount, int *workspace, int wscount)
3153  #endif  #endif
3154  {  {
3155  real_pcre *re = (real_pcre *)argument_re;  REAL_PCRE *re = (REAL_PCRE *)argument_re;
3156  dfa_match_data match_block;  dfa_match_data match_block;
3157  dfa_match_data *md = &match_block;  dfa_match_data *md = &match_block;
3158  BOOL utf, anchored, startline, firstline;  BOOL utf, anchored, startline, firstline;
3159  const pcre_uchar *current_subject, *end_subject;  const pcre_uchar *current_subject, *end_subject;
 const pcre_uint8 *lcc;  
   
3160  const pcre_study_data *study = NULL;  const pcre_study_data *study = NULL;
3161    
3162  const pcre_uchar *req_char_ptr;  const pcre_uchar *req_char_ptr;
# Line 3044  if (re == NULL || subject == NULL || wor Line 3176  if (re == NULL || subject == NULL || wor
3176     (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;     (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
3177  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
3178  if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE;  if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE;
3179    if (length < 0) return PCRE_ERROR_BADLENGTH;
3180  if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;  if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
3181    
3182  /* We need to find the pointer to any study data before we test for byte  /* Check that the first field in the block is the magic number. If it is not,
3183  flipping, so we scan the extra_data block first. This may set two fields in the  return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
3184  match block, so we must initialize them beforehand. However, the other fields  REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
3185  in the match block must not be set until after the byte flipping. */  means that the pattern is likely compiled with different endianness. */
3186    
3187    if (re->magic_number != MAGIC_NUMBER)
3188      return re->magic_number == REVERSED_MAGIC_NUMBER?
3189        PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
3190    if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
3191    
3192    /* If restarting after a partial match, do some sanity checks on the contents
3193    of the workspace. */
3194    
3195    if ((options & PCRE_DFA_RESTART) != 0)
3196      {
3197      if ((workspace[0] & (-2)) != 0 || workspace[1] < 1 ||
3198        workspace[1] > (wscount - 2)/INTS_PER_STATEBLOCK)
3199          return PCRE_ERROR_DFA_BADRESTART;
3200      }
3201    
3202    /* Set up study, callout, and table data */
3203    
3204  md->tables = re->tables;  md->tables = re->tables;
3205  md->callout_data = NULL;  md->callout_data = NULL;
# Line 3068  if (extra_data != NULL) Line 3218  if (extra_data != NULL)
3218      md->tables = extra_data->tables;      md->tables = extra_data->tables;
3219    }    }
3220    
 /* Check that the first field in the block is the magic number. If it is not,  
 return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to  
 REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which  
 means that the pattern is likely compiled with different endianness. */  
   
 if (re->magic_number != MAGIC_NUMBER)  
   return re->magic_number == REVERSED_MAGIC_NUMBER?  
     PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;  
 if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;  
   
3221  /* Set some local values */  /* Set some local values */
3222    
3223  current_subject = (const pcre_uchar *)subject + start_offset;  current_subject = (const pcre_uchar *)subject + start_offset;
# Line 3085  end_subject = (const pcre_uchar *)subjec Line 3225  end_subject = (const pcre_uchar *)subjec
3225  req_char_ptr = current_subject - 1;  req_char_ptr = current_subject - 1;
3226    
3227  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3228  /* PCRE_UTF16 has the same value as PCRE_UTF8. */  /* PCRE_UTF(16|32) have the same value as PCRE_UTF8. */
3229  utf = (re->options & PCRE_UTF8) != 0;  utf = (re->options & PCRE_UTF8) != 0;
3230  #else  #else
3231  utf = FALSE;  utf = FALSE;
# Line 3171  if (utf && (options & PCRE_NO_UTF8_CHECK Line 3311  if (utf && (options & PCRE_NO_UTF8_CHECK
3311        offsets[0] = erroroffset;        offsets[0] = erroroffset;
3312        offsets[1] = errorcode;        offsets[1] = errorcode;
3313        }        }
3314      return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0)?  #if defined COMPILE_PCRE8
3315        return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0) ?
3316        PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;        PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
3317    #elif defined COMPILE_PCRE16
3318        return (errorcode <= PCRE_UTF16_ERR1 && (options & PCRE_PARTIAL_HARD) != 0) ?
3319          PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16;
3320    #elif defined COMPILE_PCRE32
3321        return PCRE_ERROR_BADUTF32;
3322    #endif
3323      }      }
3324    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3325    if (start_offset > 0 && start_offset < length &&    if (start_offset > 0 && start_offset < length &&
3326          NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))          NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))
3327      return PCRE_ERROR_BADUTF8_OFFSET;      return PCRE_ERROR_BADUTF8_OFFSET;
3328    #endif
3329    }    }
3330  #endif  #endif
3331    
# Line 3186  in other programs later. */ Line 3335  in other programs later. */
3335    
3336  if (md->tables == NULL) md->tables = PRIV(default_tables);  if (md->tables == NULL) md->tables = PRIV(default_tables);
3337    
3338  /* The lower casing table and the "must be at the start of a line" flag are  /* The "must be at the start of a line" flags are used in a loop when finding
3339  used in a loop when finding where to start. */  where to start. */
3340    
 lcc = md->tables + lcc_offset;  
3341  startline = (re->flags & PCRE_STARTLINE) != 0;  startline = (re->flags & PCRE_STARTLINE) != 0;
3342  firstline = (re->options & PCRE_FIRSTLINE) != 0;  firstline = (re->options & PCRE_FIRSTLINE) != 0;
3343    
# Line 3204  if (!anchored) Line 3352  if (!anchored)
3352    if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->flags & PCRE_FIRSTSET) != 0)
3353      {      {
3354      has_first_char = TRUE;      has_first_char = TRUE;
3355      first_char = first_char2 = re->first_char;      first_char = first_char2 = (pcre_uchar)(re->first_char);
3356      if ((re->flags & PCRE_FCH_CASELESS) != 0)      if ((re->flags & PCRE_FCH_CASELESS) != 0)
3357        {        {
3358        first_char2 = TABLE_GET(first_char, md->tables + fcc_offset, first_char);        first_char2 = TABLE_GET(first_char, md->tables + fcc_offset, first_char);
# Line 3228  character" set. */ Line 3376  character" set. */
3376  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
3377    {    {
3378    has_req_char = TRUE;    has_req_char = TRUE;
3379    req_char = req_char2 = re->req_char;    req_char = req_char2 = (pcre_uchar)(re->req_char);
3380    if ((re->flags & PCRE_RCH_CASELESS) != 0)    if ((re->flags & PCRE_RCH_CASELESS) != 0)
3381      {      {
3382      req_char2 = TABLE_GET(req_char, md->tables + fcc_offset, req_char);      req_char2 = TABLE_GET(req_char, md->tables + fcc_offset, req_char);
# Line 3287  for (;;) Line 3435  for (;;)
3435        if (has_first_char)        if (has_first_char)
3436          {          {
3437          if (first_char != first_char2)          if (first_char != first_char2)
3438              {
3439              pcre_uchar csc;
3440            while (current_subject < end_subject &&            while (current_subject < end_subject &&
3441                *current_subject != first_char && *current_subject != first_char2)                   (csc = RAWUCHARTEST(current_subject)) != first_char && csc != first_char2)
3442              current_subject++;              current_subject++;
3443              }
3444          else          else
3445            while (current_subject < end_subject &&            while (current_subject < end_subject &&
3446                   *current_subject != first_char)                   RAWUCHARTEST(current_subject) != first_char)
3447              current_subject++;              current_subject++;
3448          }          }
3449    
# Line 3322  for (;;) Line 3473  for (;;)
3473            ANYCRLF, and we are now at a LF, advance the match position by one            ANYCRLF, and we are now at a LF, advance the match position by one
3474            more character. */            more character. */
3475    
3476            if (current_subject[-1] == CHAR_CR &&            if (RAWUCHARTEST(current_subject - 1) == CHAR_CR &&
3477                 (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&                 (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
3478                 current_subject < end_subject &&                 current_subject < end_subject &&
3479                 *current_subject == CHAR_NL)                 RAWUCHARTEST(current_subject) == CHAR_NL)
3480              current_subject++;              current_subject++;
3481            }            }
3482          }          }
# Line 3336  for (;;) Line 3487  for (;;)
3487          {          {
3488          while (current_subject < end_subject)          while (current_subject < end_subject)
3489            {            {
3490            register unsigned int c = *current_subject;            register pcre_uint32 c = RAWUCHARTEST(current_subject);
3491  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3492            if (c > 255) c = 255;            if (c > 255) c = 255;
3493  #endif  #endif
# Line 3402  for (;;) Line 3553  for (;;)
3553              {              {
3554              while (p < end_subject)              while (p < end_subject)
3555                {                {
3556                register int pp = *p++;                register pcre_uint32 pp = RAWUCHARINCTEST(p);
3557                if (pp == req_char || pp == req_char2) { p--; break; }                if (pp == req_char || pp == req_char2) { p--; break; }
3558                }                }
3559              }              }
# Line 3410  for (;;) Line 3561  for (;;)
3561              {              {
3562              while (p < end_subject)              while (p < end_subject)
3563                {                {
3564                if (*p++ == req_char) { p--; break; }                if (RAWUCHARINCTEST(p) == req_char) { p--; break; }
3565                }                }
3566              }              }
3567    
# Line 3448  for (;;) Line 3599  for (;;)
3599    /* Anything other than "no match" means we are done, always; otherwise, carry    /* Anything other than "no match" means we are done, always; otherwise, carry
3600    on only if not anchored. */    on only if not anchored. */
3601    
3602    if (rc != PCRE_ERROR_NOMATCH || anchored) return rc;    if (rc != PCRE_ERROR_NOMATCH || anchored)
3603        {
3604        if (rc == PCRE_ERROR_PARTIAL && offsetcount >= 2)
3605          {
3606          offsets[0] = (int)(md->start_used_ptr - (PCRE_PUCHAR)subject);
3607          offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);
3608          if (offsetcount > 2)
3609            offsets[2] = (int)(current_subject - (PCRE_PUCHAR)subject);
3610          }
3611        return rc;
3612        }
3613    
3614    /* Advance to the next subject character unless we are at the end of a line    /* Advance to the next subject character unless we are at the end of a line
3615    and firstline is set. */    and firstline is set. */
# Line 3468  for (;;) Line 3629  for (;;)
3629    not contain any explicit matches for \r or \n, and the newline option is CRLF    not contain any explicit matches for \r or \n, and the newline option is CRLF
3630    or ANY or ANYCRLF, advance the match position by one more character. */    or ANY or ANYCRLF, advance the match position by one more character. */
3631    
3632    if (current_subject[-1] == CHAR_CR &&    if (RAWUCHARTEST(current_subject - 1) == CHAR_CR &&
3633        current_subject < end_subject &&        current_subject < end_subject &&
3634        *current_subject == CHAR_NL &&        RAWUCHARTEST(current_subject) == CHAR_NL &&
3635        (re->flags & PCRE_HASCRORLF) == 0 &&        (re->flags & PCRE_HASCRORLF) == 0 &&
3636          (md->nltype == NLTYPE_ANY ||          (md->nltype == NLTYPE_ANY ||
3637           md->nltype == NLTYPE_ANYCRLF ||           md->nltype == NLTYPE_ANYCRLF ||

Legend:
Removed from v.850  
changed lines
  Added in v.1376

  ViewVC Help
Powered by ViewVC 1.1.5