# Diff of /code/trunk/pcre_dfa_exec.c

revision 975 by ph10, Sat Jun 2 11:03:06 2012 UTC revision 1425 by ph10, Tue Dec 31 17:44:40 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
# 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 152  static const pcre_uint8 coptable[] = { Line 151  static const pcre_uint8 coptable[] = {
151    /* Character class & ref repeats                                         */    /* Character class & ref repeats                                         */
152    0, 0, 0, 0, 0, 0,              /* *, *?, +, +?, ?, ??                    */    0, 0, 0, 0, 0, 0,              /* *, *?, +, +?, ?, ??                    */
153    0, 0,                          /* CRRANGE, CRMINRANGE                    */    0, 0,                          /* CRRANGE, CRMINRANGE                    */
154      0, 0, 0, 0,                    /* Possessive *+, ++, ?+, CRPOSRANGE      */
155    0,                             /* CLASS                                  */    0,                             /* CLASS                                  */
156    0,                             /* NCLASS                                 */    0,                             /* NCLASS                                 */
157    0,                             /* XCLASS - variable length               */    0,                             /* XCLASS - variable length               */
158    0,                             /* REF                                    */    0,                             /* REF                                    */
159    0,                             /* REFI                                   */    0,                             /* REFI                                   */
160      0,                             /* DNREF                                  */
161      0,                             /* DNREFI                                 */
162    0,                             /* RECURSE                                */    0,                             /* RECURSE                                */
163    0,                             /* CALLOUT                                */    0,                             /* CALLOUT                                */
164    0,                             /* Alt                                    */    0,                             /* Alt                                    */
# Line 172  static const pcre_uint8 coptable[] = { Line 174  static const pcre_uint8 coptable[] = {
174    0, 0,                          /* ONCE, ONCE_NC                          */    0, 0,                          /* ONCE, ONCE_NC                          */
175    0, 0, 0, 0, 0,                 /* BRA, BRAPOS, CBRA, CBRAPOS, COND       */    0, 0, 0, 0, 0,                 /* BRA, BRAPOS, CBRA, CBRAPOS, COND       */
176    0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */    0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */
177    0, 0,                          /* CREF, NCREF                            */    0, 0,                          /* CREF, DNCREF                           */
178    0, 0,                          /* RREF, NRREF                            */    0, 0,                          /* RREF, DNRREF                           */
179    0,                             /* DEF                                    */    0,                             /* DEF                                    */
180    0, 0, 0,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */    0, 0, 0,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */
181    0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG                 */    0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG                 */
# Line 195  static const pcre_uint8 poptable[] = { Line 197  static const pcre_uint8 poptable[] = {
197    1, 1,                          /* \P, \p                                 */    1, 1,                          /* \P, \p                                 */
198    1, 1, 1, 1, 1,                 /* \R, \H, \h, \V, \v                     */    1, 1, 1, 1, 1,                 /* \R, \H, \h, \V, \v                     */
199    1,                             /* \X                                     */    1,                             /* \X                                     */
200    0, 0, 0, 0, 0, 0,              /* \Z, \z, ^, ^M, \$, \$M                   */    0, 0, 0, 0, 0, 0,              /* \Z, \z, \$, \$M, ^, ^M                   */
201    1,                             /* Char                                   */    1,                             /* Char                                   */
202    1,                             /* Chari                                  */    1,                             /* Chari                                  */
203    1,                             /* not                                    */    1,                             /* not                                    */
# Line 221  static const pcre_uint8 poptable[] = { Line 223  static const pcre_uint8 poptable[] = {
223    /* Character class & ref repeats                                         */    /* Character class & ref repeats                                         */
224    1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */    1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */
225    1, 1,                          /* CRRANGE, CRMINRANGE                    */    1, 1,                          /* CRRANGE, CRMINRANGE                    */
226      1, 1, 1, 1,                    /* Possessive *+, ++, ?+, CRPOSRANGE      */
227    1,                             /* CLASS                                  */    1,                             /* CLASS                                  */
228    1,                             /* NCLASS                                 */    1,                             /* NCLASS                                 */
229    1,                             /* XCLASS - variable length               */    1,                             /* XCLASS - variable length               */
230    0,                             /* REF                                    */    0,                             /* REF                                    */
231    0,                             /* REFI                                   */    0,                             /* REFI                                   */
232      0,                             /* DNREF                                  */
233      0,                             /* DNREFI                                 */
234    0,                             /* RECURSE                                */    0,                             /* RECURSE                                */
235    0,                             /* CALLOUT                                */    0,                             /* CALLOUT                                */
236    0,                             /* Alt                                    */    0,                             /* Alt                                    */
# Line 241  static const pcre_uint8 poptable[] = { Line 246  static const pcre_uint8 poptable[] = {
246    0, 0,                          /* ONCE, ONCE_NC                          */    0, 0,                          /* ONCE, ONCE_NC                          */
247    0, 0, 0, 0, 0,                 /* BRA, BRAPOS, CBRA, CBRAPOS, COND       */    0, 0, 0, 0, 0,                 /* BRA, BRAPOS, CBRA, CBRAPOS, COND       */
248    0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */    0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */
249    0, 0,                          /* CREF, NCREF                            */    0, 0,                          /* CREF, DNCREF                           */
250    0, 0,                          /* RREF, NRREF                            */    0, 0,                          /* RREF, DNRREF                           */
251    0,                             /* DEF                                    */    0,                             /* DEF                                    */
252    0, 0, 0,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */    0, 0, 0,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */
253    0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG                 */    0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG                 */
# Line 303  Returns:       nothing Line 308  Returns:       nothing
308  static void  static void
309  pchars(const pcre_uchar *p, int length, FILE *f)  pchars(const pcre_uchar *p, int length, FILE *f)
310  {  {
311  int c;  pcre_uint32 c;
312  while (length-- > 0)  while (length-- > 0)
313    {    {
314    if (isprint(c = *(p++)))    if (isprint(c = *(p++)))
315      fprintf(f, "%c", c);      fprintf(f, "%c", c);
316    else    else
317      fprintf(f, "\\x%02x", c);      fprintf(f, "\\x{%02x}", c);
318    }    }
319  }  }
320  #endif  #endif
# Line 382  for the current character, one for the f Line 387  for the current character, one for the f
387      next_new_state->count  = (y); \      next_new_state->count  = (y); \
388      next_new_state->data   = (z); \      next_new_state->data   = (z); \
389      next_new_state++; \      next_new_state++; \
390      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, \
391          (x), (y), (z), __LINE__)); \
392      } \      } \
393    else return PCRE_ERROR_DFA_WSSIZE    else return PCRE_ERROR_DFA_WSSIZE
394
# Line 571  for (;;) Line 577  for (;;)
577    {    {
578    int i, j;    int i, j;
579    int clen, dlen;    int clen, dlen;
580    unsigned int c, d;    pcre_uint32 c, d;
581    int forced_fail = 0;    int forced_fail = 0;
582    BOOL partial_newline = FALSE;    BOOL partial_newline = FALSE;
583    BOOL could_continue = reset_could_continue;    BOOL could_continue = reset_could_continue;
# Line 611  for (;;) Line 617  for (;;)
617
618    if (ptr < end_subject)    if (ptr < end_subject)
619      {      {
620      clen = 1;        /* Number of bytes in the character */      clen = 1;        /* Number of data items in the character */
621  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
622      if (utf) { GETCHARLEN(c, ptr, clen); } else      GETCHARLENTEST(c, ptr, clen);
623  #endif  /* SUPPORT_UTF */  #else
624      c = *ptr;      c = *ptr;
625    #endif  /* SUPPORT_UTF */
626      }      }
627    else    else
628      {      {
# Line 634  for (;;) Line 641  for (;;)
641      BOOL caseless = FALSE;      BOOL caseless = FALSE;
642      const pcre_uchar *code;      const pcre_uchar *code;
643      int state_offset = current_state->offset;      int state_offset = current_state->offset;
644      int count, codevalue, rrc;      int codevalue, rrc;
645        int count;
646
647  #ifdef PCRE_DEBUG  #ifdef PCRE_DEBUG
648      printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset);      printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset);
# Line 789  for (;;) Line 797  for (;;)
797              offsets[0] = (int)(current_subject - start_subject);              offsets[0] = (int)(current_subject - start_subject);
798              offsets[1] = (int)(ptr - start_subject);              offsets[1] = (int)(ptr - start_subject);
799              DPRINTF(("%.*sSet matched string = \"%.*s\"\n", rlevel*2-2, SP,              DPRINTF(("%.*sSet matched string = \"%.*s\"\n", rlevel*2-2, SP,
800                offsets[1] - offsets[0], current_subject));                offsets[1] - offsets[0], (char *)current_subject));
801              }              }
802            if ((md->moptions & PCRE_DFA_SHORTEST) != 0)            if ((md->moptions & PCRE_DFA_SHORTEST) != 0)
803              {              {
# Line 1007  for (;;) Line 1015  for (;;)
1015            {            {
1016            const pcre_uchar *temp = ptr - 1;            const pcre_uchar *temp = ptr - 1;
1017            if (temp < md->start_used_ptr) md->start_used_ptr = temp;            if (temp < md->start_used_ptr) md->start_used_ptr = temp;
1018  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1019            if (utf) { BACKCHAR(temp); }            if (utf) { BACKCHAR(temp); }
1020  #endif  #endif
1021            GETCHARTEST(d, temp);            GETCHARTEST(d, temp);
# Line 1060  for (;;) Line 1068  for (;;)
1068        if (clen > 0)        if (clen > 0)
1069          {          {
1070          BOOL OK;          BOOL OK;
1071            const pcre_uint32 *cp;
1072          const ucd_record * prop = GET_UCD(c);          const ucd_record * prop = GET_UCD(c);
1073          switch(code[1])          switch(code[1])
1074            {            {
# Line 1091  for (;;) Line 1100  for (;;)
1100                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;
1101            break;            break;
1102
1103            case PT_SPACE:    /* Perl space */            /* Perl space used to exclude VT, but from Perl 5.18 it is included,
1104            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            which means that Perl space and POSIX space are now identical. PCRE
1105                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;            was changed at release 8.34. */
break;
1106
1107              case PT_SPACE:    /* Perl space */
1108            case PT_PXSPACE:  /* POSIX space */            case PT_PXSPACE:  /* POSIX space */
1109            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            switch(c)
1110                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||              {
1111                 c == CHAR_FF || c == CHAR_CR;              HSPACE_CASES:
1112                VSPACE_CASES:
1113                OK = TRUE;
1114                break;
1115
1116                default:
1117                OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
1118                break;
1119                }
1120            break;            break;
1121
1122            case PT_WORD:            case PT_WORD:
# Line 1108  for (;;) Line 1125  for (;;)
1125                 c == CHAR_UNDERSCORE;                 c == CHAR_UNDERSCORE;
1126            break;            break;
1127
1128              case PT_CLIST:
1129              cp = PRIV(ucd_caseless_sets) + code[2];
1130              for (;;)
1131                {
1132                if (c < *cp) { OK = FALSE; break; }
1133                if (c == *cp++) { OK = TRUE; break; }
1134                }
1135              break;
1136
1137              case PT_UCNC:
1138              OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
1139                   c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
1140                   c >= 0xe000;
1141              break;
1142
1143            /* Should never occur, but keep compilers from grumbling. */            /* Should never occur, but keep compilers from grumbling. */
1144
1145            default:            default:
# Line 1237  for (;;) Line 1269  for (;;)
1269                (d != OP_ANY || !IS_NEWLINE(ptr)) &&                (d != OP_ANY || !IS_NEWLINE(ptr)) &&
1270                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
1271            {            {
1272            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
1273              { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); }              { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); }
1274            else            else
# Line 1271  for (;;) Line 1303  for (;;)
1303              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
1304              next_active_state--;              next_active_state--;
1305              }              }
1306            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
1307              { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); }              { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); }
1308            else            else
# Line 1294  for (;;) Line 1326  for (;;)
1326        if (clen > 0)        if (clen > 0)
1327          {          {
1328          BOOL OK;          BOOL OK;
1329            const pcre_uint32 *cp;
1330          const ucd_record * prop = GET_UCD(c);          const ucd_record * prop = GET_UCD(c);
1331          switch(code[2])          switch(code[2])
1332            {            {
# Line 1325  for (;;) Line 1358  for (;;)
1358                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;
1359            break;            break;
1360
1361            case PT_SPACE:    /* Perl space */            /* Perl space used to exclude VT, but from Perl 5.18 it is included,
1362            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            which means that Perl space and POSIX space are now identical. PCRE
1363                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;            was changed at release 8.34. */
break;
1364
1365              case PT_SPACE:    /* Perl space */
1366            case PT_PXSPACE:  /* POSIX space */            case PT_PXSPACE:  /* POSIX space */
1367            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            switch(c)
1368                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||              {
1369                 c == CHAR_FF || c == CHAR_CR;              HSPACE_CASES:
1370                VSPACE_CASES:
1371                OK = TRUE;
1372                break;
1373
1374                default:
1375                OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
1376                break;
1377                }
1378            break;            break;
1379
1380            case PT_WORD:            case PT_WORD:
# Line 1342  for (;;) Line 1383  for (;;)
1383                 c == CHAR_UNDERSCORE;                 c == CHAR_UNDERSCORE;
1384            break;            break;
1385
1386              case PT_CLIST:
1387              cp = PRIV(ucd_caseless_sets) + code[3];
1388              for (;;)
1389                {
1390                if (c < *cp) { OK = FALSE; break; }
1391                if (c == *cp++) { OK = TRUE; break; }
1392                }
1393              break;
1394
1395              case PT_UCNC:
1396              OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
1397                   c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
1398                   c >= 0xe000;
1399              break;
1400
1401            /* Should never occur, but keep compilers from grumbling. */            /* Should never occur, but keep compilers from grumbling. */
1402
1403            default:            default:
# Line 1368  for (;;) Line 1424  for (;;)
1424        case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS:        case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS:
1425        count = current_state->count;  /* Already matched */        count = current_state->count;  /* Already matched */
1426        if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }        if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
1427        if (clen > 0 && UCD_CATEGORY(c) != ucp_M)        if (clen > 0)
1428          {          {
1429            int lgb, rgb;
1430          const pcre_uchar *nptr = ptr + clen;          const pcre_uchar *nptr = ptr + clen;
1431          int ncount = 0;          int ncount = 0;
1432          if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)          if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)
# Line 1377  for (;;) Line 1434  for (;;)
1434            active_count--;           /* Remove non-match possibility */            active_count--;           /* Remove non-match possibility */
1435            next_active_state--;            next_active_state--;
1436            }            }
1437            lgb = UCD_GRAPHBREAK(c);
1438          while (nptr < end_subject)          while (nptr < end_subject)
1439            {            {
1440            int nd;            dlen = 1;
1441            int ndlen = 1;            if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
1442            GETCHARLEN(nd, nptr, ndlen);            rgb = UCD_GRAPHBREAK(d);
1443            if (UCD_CATEGORY(nd) != ucp_M) break;            if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
1444            ncount++;            ncount++;
1445            nptr += ndlen;            lgb = rgb;
1446              nptr += dlen;
1447            }            }
1448          count++;          count++;
# Line 1403  for (;;) Line 1462  for (;;)
1462          int ncount = 0;          int ncount = 0;
1463          switch (c)          switch (c)
1464            {            {
1465            case 0x000b:            case CHAR_VT:
1466            case 0x000c:            case CHAR_FF:
1467            case 0x0085:            case CHAR_NEL:
1468    #ifndef EBCDIC
1469            case 0x2028:            case 0x2028:
1470            case 0x2029:            case 0x2029:
1471    #endif  /* Not EBCDIC */
1472            if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;            if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
1473            goto ANYNL01;            goto ANYNL01;
1474
1475            case 0x000d:            case CHAR_CR:
1476            if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;            if (ptr + 1 < end_subject && ptr[1] == CHAR_LF) ncount = 1;
1477            /* Fall through */            /* Fall through */
1478
1479            ANYNL01:            ANYNL01:
1480            case 0x000a:            case CHAR_LF:
1481            if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS)            if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS)
1482              {              {
1483              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
# Line 1443  for (;;) Line 1504  for (;;)
1504          BOOL OK;          BOOL OK;
1505          switch (c)          switch (c)
1506            {            {
1507            case 0x000a:            VSPACE_CASES:
case 0x000b:
case 0x000c:
case 0x000d:
case 0x0085:
case 0x2028:
case 0x2029:
1508            OK = TRUE;            OK = TRUE;
1509            break;            break;
1510
# Line 1482  for (;;) Line 1537  for (;;)
1537          BOOL OK;          BOOL OK;
1538          switch (c)          switch (c)
1539            {            {
1540            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 */
1541            OK = TRUE;            OK = TRUE;
1542            break;            break;
1543
# Line 1541  for (;;) Line 1578  for (;;)
1578        if (clen > 0)        if (clen > 0)
1579          {          {
1580          BOOL OK;          BOOL OK;
1581            const pcre_uint32 *cp;
1582          const ucd_record * prop = GET_UCD(c);          const ucd_record * prop = GET_UCD(c);
1583          switch(code[2])          switch(code[2])
1584            {            {
# Line 1572  for (;;) Line 1610  for (;;)
1610                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;
1611            break;            break;
1612
1613            case PT_SPACE:    /* Perl space */            /* Perl space used to exclude VT, but from Perl 5.18 it is included,
1614            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            which means that Perl space and POSIX space are now identical. PCRE
1615                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;            was changed at release 8.34. */
break;
1616
1617              case PT_SPACE:    /* Perl space */
1618            case PT_PXSPACE:  /* POSIX space */            case PT_PXSPACE:  /* POSIX space */
1619            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            switch(c)
1620                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||              {
1621                 c == CHAR_FF || c == CHAR_CR;              HSPACE_CASES:
1622                VSPACE_CASES:
1623                OK = TRUE;
1624                break;
1625
1626                default:
1627                OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
1628                break;
1629                }
1630            break;            break;
1631
1632            case PT_WORD:            case PT_WORD:
# Line 1589  for (;;) Line 1635  for (;;)
1635                 c == CHAR_UNDERSCORE;                 c == CHAR_UNDERSCORE;
1636            break;            break;
1637
1638              case PT_CLIST:
1639              cp = PRIV(ucd_caseless_sets) + code[3];
1640              for (;;)
1641                {
1642                if (c < *cp) { OK = FALSE; break; }
1643                if (c == *cp++) { OK = TRUE; break; }
1644                }
1645              break;
1646
1647              case PT_UCNC:
1648              OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
1649                   c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
1650                   c >= 0xe000;
1651              break;
1652
1653            /* Should never occur, but keep compilers from grumbling. */            /* Should never occur, but keep compilers from grumbling. */
1654
1655            default:            default:
# Line 1624  for (;;) Line 1685  for (;;)
1685        QS2:        QS2:
1686
1688        if (clen > 0 && UCD_CATEGORY(c) != ucp_M)        if (clen > 0)
1689          {          {
1690            int lgb, rgb;
1691          const pcre_uchar *nptr = ptr + clen;          const pcre_uchar *nptr = ptr + clen;
1692          int ncount = 0;          int ncount = 0;
1693          if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||          if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||
# Line 1634  for (;;) Line 1696  for (;;)
1696            active_count--;           /* Remove non-match possibility */            active_count--;           /* Remove non-match possibility */
1697            next_active_state--;            next_active_state--;
1698            }            }
1699            lgb = UCD_GRAPHBREAK(c);
1700          while (nptr < end_subject)          while (nptr < end_subject)
1701            {            {
1702            int nd;            dlen = 1;
1703            int ndlen = 1;            if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
1704            GETCHARLEN(nd, nptr, ndlen);            rgb = UCD_GRAPHBREAK(d);
1705            if (UCD_CATEGORY(nd) != ucp_M) break;            if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
1706            ncount++;            ncount++;
1707            nptr += ndlen;            lgb = rgb;
1708              nptr += dlen;
1709            }            }
1711          }          }
# Line 1667  for (;;) Line 1731  for (;;)
1731          int ncount = 0;          int ncount = 0;
1732          switch (c)          switch (c)
1733            {            {
1734            case 0x000b:            case CHAR_VT:
1735            case 0x000c:            case CHAR_FF:
1736            case 0x0085:            case CHAR_NEL:
1737    #ifndef EBCDIC
1738            case 0x2028:            case 0x2028:
1739            case 0x2029:            case 0x2029:
1740    #endif  /* Not EBCDIC */
1741            if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;            if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
1742            goto ANYNL02;            goto ANYNL02;
1743
1744            case 0x000d:            case CHAR_CR:
1745            if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;            if (ptr + 1 < end_subject && ptr[1] == CHAR_LF) ncount = 1;
1746            /* Fall through */            /* Fall through */
1747
1748            ANYNL02:            ANYNL02:
1749            case 0x000a:            case CHAR_LF:
1750            if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR ||            if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR ||
1751                codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY)                codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY)
1752              {              {
1753              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
1754              next_active_state--;              next_active_state--;
1755              }              }
1757            break;            break;
1758
1759            default:            default:
# Line 1715  for (;;) Line 1781  for (;;)
1781          BOOL OK;          BOOL OK;
1782          switch (c)          switch (c)
1783            {            {
1784            case 0x000a:            VSPACE_CASES:
case 0x000b:
case 0x000c:
case 0x000d:
case 0x0085:
case 0x2028:
case 0x2029:
1785            OK = TRUE;            OK = TRUE;
1786            break;            break;
1787
# Line 1737  for (;;) Line 1797  for (;;)
1797              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
1798              next_active_state--;              next_active_state--;
1799              }              }
1801            }            }
1802          }          }
1803        break;        break;
# Line 1761  for (;;) Line 1821  for (;;)
1821          BOOL OK;          BOOL OK;
1822          switch (c)          switch (c)
1823            {            {
1824            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 */
1825            OK = TRUE;            OK = TRUE;
1826            break;            break;
1827
# Line 1796  for (;;) Line 1838  for (;;)
1838              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
1839              next_active_state--;              next_active_state--;
1840              }              }
1842            }            }
1843          }          }
1844        break;        break;
# Line 1813  for (;;) Line 1855  for (;;)
1855        if (clen > 0)        if (clen > 0)
1856          {          {
1857          BOOL OK;          BOOL OK;
1858            const pcre_uint32 *cp;
1859          const ucd_record * prop = GET_UCD(c);          const ucd_record * prop = GET_UCD(c);
1860          switch(code[1 + IMM2_SIZE + 1])          switch(code[1 + IMM2_SIZE + 1])
1861            {            {
# Line 1844  for (;;) Line 1887  for (;;)
1887                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;
1888            break;            break;
1889
1890            case PT_SPACE:    /* Perl space */            /* Perl space used to exclude VT, but from Perl 5.18 it is included,
1891            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            which means that Perl space and POSIX space are now identical. PCRE
1892                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;            was changed at release 8.34. */
break;
1893
1894              case PT_SPACE:    /* Perl space */
1895            case PT_PXSPACE:  /* POSIX space */            case PT_PXSPACE:  /* POSIX space */
1896            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            switch(c)
1897                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||              {
1898                 c == CHAR_FF || c == CHAR_CR;              HSPACE_CASES:
1899                VSPACE_CASES:
1900                OK = TRUE;
1901                break;
1902
1903                default:
1904                OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
1905                break;
1906                }
1907            break;            break;
1908
1909            case PT_WORD:            case PT_WORD:
# Line 1861  for (;;) Line 1912  for (;;)
1912                 c == CHAR_UNDERSCORE;                 c == CHAR_UNDERSCORE;
1913            break;            break;
1914
1915              case PT_CLIST:
1916              cp = PRIV(ucd_caseless_sets) + code[1 + IMM2_SIZE + 2];
1917              for (;;)
1918                {
1919                if (c < *cp) { OK = FALSE; break; }
1920                if (c == *cp++) { OK = TRUE; break; }
1921                }
1922              break;
1923
1924              case PT_UCNC:
1925              OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
1926                   c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
1927                   c >= 0xe000;
1928              break;
1929
1930            /* Should never occur, but keep compilers from grumbling. */            /* Should never occur, but keep compilers from grumbling. */
1931
1932            default:            default:
# Line 1875  for (;;) Line 1941  for (;;)
1941              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
1942              next_active_state--;              next_active_state--;
1943              }              }
1944            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
1945              { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); }              { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); }
1946            else            else
# Line 1891  for (;;) Line 1957  for (;;)
1957        if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT)        if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT)
1958          { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }          { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
1959        count = current_state->count;  /* Number already matched */        count = current_state->count;  /* Number already matched */
1960        if (clen > 0 && UCD_CATEGORY(c) != ucp_M)        if (clen > 0)
1961          {          {
1962            int lgb, rgb;
1963          const pcre_uchar *nptr = ptr + clen;          const pcre_uchar *nptr = ptr + clen;
1964          int ncount = 0;          int ncount = 0;
1965          if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)          if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)
# Line 1900  for (;;) Line 1967  for (;;)
1967            active_count--;           /* Remove non-match possibility */            active_count--;           /* Remove non-match possibility */
1968            next_active_state--;            next_active_state--;
1969            }            }
1970            lgb = UCD_GRAPHBREAK(c);
1971          while (nptr < end_subject)          while (nptr < end_subject)
1972            {            {
1973            int nd;            dlen = 1;
1974            int ndlen = 1;            if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
1975            GETCHARLEN(nd, nptr, ndlen);            rgb = UCD_GRAPHBREAK(d);
1976            if (UCD_CATEGORY(nd) != ucp_M) break;            if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
1977            ncount++;            ncount++;
1978            nptr += ndlen;            lgb = rgb;
1979              nptr += dlen;
1980            }            }
1981          if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0)          if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0)
1982              reset_could_continue = TRUE;              reset_could_continue = TRUE;
1983          if (++count >= GET2(code, 1))          if (++count >= (int)GET2(code, 1))
1984            { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }            { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
1985          else          else
# Line 1932  for (;;) Line 2001  for (;;)
2001          int ncount = 0;          int ncount = 0;
2002          switch (c)          switch (c)
2003            {            {
2004            case 0x000b:            case CHAR_VT:
2005            case 0x000c:            case CHAR_FF:
2006            case 0x0085:            case CHAR_NEL:
2007    #ifndef EBCDIC
2008            case 0x2028:            case 0x2028:
2009            case 0x2029:            case 0x2029:
2010    #endif  /* Not EBCDIC */
2011            if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;            if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
2012            goto ANYNL03;            goto ANYNL03;
2013
2014            case 0x000d:            case CHAR_CR:
2015            if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;            if (ptr + 1 < end_subject && ptr[1] == CHAR_LF) ncount = 1;
2016            /* Fall through */            /* Fall through */
2017
2018            ANYNL03:            ANYNL03:
2019            case 0x000a:            case CHAR_LF:
2020            if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO)            if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO)
2021              {              {
2022              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
2023              next_active_state--;              next_active_state--;
2024              }              }
2025            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
2026              { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }              { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
2027            else            else
# Line 1976  for (;;) Line 2047  for (;;)
2047          BOOL OK;          BOOL OK;
2048          switch (c)          switch (c)
2049            {            {
2050            case 0x000a:            VSPACE_CASES:
case 0x000b:
case 0x000c:
case 0x000d:
case 0x0085:
case 0x2028:
case 0x2029:
2051            OK = TRUE;            OK = TRUE;
2052            break;            break;
2053
# Line 1997  for (;;) Line 2062  for (;;)
2062              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
2063              next_active_state--;              next_active_state--;
2064              }              }
2065            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
2066              { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }              { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
2067            else            else
# Line 2018  for (;;) Line 2083  for (;;)
2083          BOOL OK;          BOOL OK;
2084          switch (c)          switch (c)
2085            {            {
2086            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 */
2087            OK = TRUE;            OK = TRUE;
2088            break;            break;
2089
# Line 2052  for (;;) Line 2099  for (;;)
2099              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
2100              next_active_state--;              next_active_state--;
2101              }              }
2102            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
2103              { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }              { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
2104            else            else
# Line 2112  for (;;) Line 2159  for (;;)
2159        to wait for them to pass before continuing. */        to wait for them to pass before continuing. */
2160
2161        case OP_EXTUNI:        case OP_EXTUNI:
2162        if (clen > 0 && UCD_CATEGORY(c) != ucp_M)        if (clen > 0)
2163          {          {
2164            int lgb, rgb;
2165          const pcre_uchar *nptr = ptr + clen;          const pcre_uchar *nptr = ptr + clen;
2166          int ncount = 0;          int ncount = 0;
2167            lgb = UCD_GRAPHBREAK(c);
2168          while (nptr < end_subject)          while (nptr < end_subject)
2169            {            {
2170            int nclen = 1;            dlen = 1;
2171            GETCHARLEN(c, nptr, nclen);            if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
2172            if (UCD_CATEGORY(c) != ucp_M) break;            rgb = UCD_GRAPHBREAK(d);
2173              if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
2174            ncount++;            ncount++;
2175            nptr += nclen;            lgb = rgb;
2176              nptr += dlen;
2177            }            }
2178          if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0)          if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0)
2179              reset_could_continue = TRUE;              reset_could_continue = TRUE;
# Line 2139  for (;;) Line 2190  for (;;)
2190        case OP_ANYNL:        case OP_ANYNL:
2191        if (clen > 0) switch(c)        if (clen > 0) switch(c)
2192          {          {
2193          case 0x000b:          case CHAR_VT:
2194          case 0x000c:          case CHAR_FF:
2195          case 0x0085:          case CHAR_NEL:
2196    #ifndef EBCDIC
2197          case 0x2028:          case 0x2028:
2198          case 0x2029:          case 0x2029:
2199    #endif  /* Not EBCDIC */
2200          if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;          if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
2201
2202          case 0x000a:          case CHAR_LF:
2204          break;          break;
2205
2206          case 0x000d:          case CHAR_CR:
2207          if (ptr + 1 >= end_subject)          if (ptr + 1 >= end_subject)
2208            {            {
2210            if ((md->moptions & PCRE_PARTIAL_HARD) != 0)            if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
2211              reset_could_continue = TRUE;              reset_could_continue = TRUE;
2212            }            }
2213          else if (ptr[1] == 0x0a)          else if (ptr[1] == CHAR_LF)
2214            {            {
2216            }            }
# Line 2173  for (;;) Line 2226  for (;;)
2226        case OP_NOT_VSPACE:        case OP_NOT_VSPACE:
2227        if (clen > 0) switch(c)        if (clen > 0) switch(c)
2228          {          {
2229          case 0x000a:          VSPACE_CASES:
case 0x000b:
case 0x000c:
case 0x000d:
case 0x0085:
case 0x2028:
case 0x2029:
2230          break;          break;
2231
2232          default:          default:
# Line 2192  for (;;) Line 2239  for (;;)
2239        case OP_VSPACE:        case OP_VSPACE:
2240        if (clen > 0) switch(c)        if (clen > 0) switch(c)
2241          {          {
2242          case 0x000a:          VSPACE_CASES:
case 0x000b:
case 0x000c:
case 0x000d:
case 0x0085:
case 0x2028:
case 0x2029:
2244          break;          break;
2245
2246          default: break;          default:
2247            break;
2248          }          }
2249        break;        break;
2250
# Line 2210  for (;;) Line 2252  for (;;)
2252        case OP_NOT_HSPACE:        case OP_NOT_HSPACE:
2253        if (clen > 0) switch(c)        if (clen > 0) switch(c)
2254          {          {
2255          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 */
2256          break;          break;
2257
2258          default:          default:
# Line 2241  for (;;) Line 2265  for (;;)
2265        case OP_HSPACE:        case OP_HSPACE:
2266        if (clen > 0) switch(c)        if (clen > 0) switch(c)
2267          {          {
2268          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 */
2270          break;          break;
2271
2272            default:
2273            break;
2274          }          }
2275        break;        break;
2276
# Line 2315  for (;;) Line 2324  for (;;)
2324        if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); }        if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); }
2325        if (clen > 0)        if (clen > 0)
2326          {          {
2327          unsigned int otherd = NOTACHAR;          pcre_uint32 otherd = NOTACHAR;
2328          if (caseless)          if (caseless)
2329            {            {
2330  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 2362  for (;;) Line 2371  for (;;)
2371        ADD_ACTIVE(state_offset + dlen + 1, 0);        ADD_ACTIVE(state_offset + dlen + 1, 0);
2372        if (clen > 0)        if (clen > 0)
2373          {          {
2374          unsigned int otherd = NOTACHAR;          pcre_uint32 otherd = NOTACHAR;
2375          if (caseless)          if (caseless)
2376            {            {
2377  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 2407  for (;;) Line 2416  for (;;)
2416        ADD_ACTIVE(state_offset + dlen + 1, 0);        ADD_ACTIVE(state_offset + dlen + 1, 0);
2417        if (clen > 0)        if (clen > 0)
2418          {          {
2419          unsigned int otherd = NOTACHAR;          pcre_uint32 otherd = NOTACHAR;
2420          if (caseless)          if (caseless)
2421            {            {
2422  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 2444  for (;;) Line 2453  for (;;)
2453        count = current_state->count;  /* Number already matched */        count = current_state->count;  /* Number already matched */
2454        if (clen > 0)        if (clen > 0)
2455          {          {
2456          unsigned int otherd = NOTACHAR;          pcre_uint32 otherd = NOTACHAR;
2457          if (caseless)          if (caseless)
2458            {            {
2459  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 2460  for (;;) Line 2469  for (;;)
2469            }            }
2470          if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))          if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
2471            {            {
2472            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
2473              { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }              { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
2474            else            else
# Line 2488  for (;;) Line 2497  for (;;)
2497        count = current_state->count;  /* Number already matched */        count = current_state->count;  /* Number already matched */
2498        if (clen > 0)        if (clen > 0)
2499          {          {
2500          unsigned int otherd = NOTACHAR;          pcre_uint32 otherd = NOTACHAR;
2501          if (caseless)          if (caseless)
2502            {            {
2503  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 2509  for (;;) Line 2518  for (;;)
2518              active_count--;             /* Remove non-match possibility */              active_count--;             /* Remove non-match possibility */
2519              next_active_state--;              next_active_state--;
2520              }              }
2521            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
2522              { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }              { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
2523            else            else
# Line 2562  for (;;) Line 2571  for (;;)
2571            {            {
2572            case OP_CRSTAR:            case OP_CRSTAR:
2573            case OP_CRMINSTAR:            case OP_CRMINSTAR:
2574              case OP_CRPOSSTAR:
2576            if (isinclass) { ADD_NEW(state_offset, 0); }            if (isinclass)
2577                {
2578                if (*ecode == OP_CRPOSSTAR)
2579                  {
2580                  active_count--;           /* Remove non-match possibility */
2581                  next_active_state--;
2582                  }
2584                }
2585            break;            break;
2586
2587            case OP_CRPLUS:            case OP_CRPLUS:
2588            case OP_CRMINPLUS:            case OP_CRMINPLUS:
2589              case OP_CRPOSPLUS:
2590            count = current_state->count;  /* Already matched */            count = current_state->count;  /* Already matched */
2591            if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); }            if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); }
2592            if (isinclass) { count++; ADD_NEW(state_offset, count); }            if (isinclass)
2593                {
2594                if (count > 0 && *ecode == OP_CRPOSPLUS)
2595                  {
2596                  active_count--;           /* Remove non-match possibility */
2597                  next_active_state--;
2598                  }
2599                count++;
2601                }
2602            break;            break;
2603
2604            case OP_CRQUERY:            case OP_CRQUERY:
2605            case OP_CRMINQUERY:            case OP_CRMINQUERY:
2606              case OP_CRPOSQUERY:
2608            if (isinclass) { ADD_NEW(next_state_offset + 1, 0); }            if (isinclass)
2609                {
2610                if (*ecode == OP_CRPOSQUERY)
2611                  {
2612                  active_count--;           /* Remove non-match possibility */
2613                  next_active_state--;
2614                  }
2616                }
2617            break;            break;
2618
2619            case OP_CRRANGE:            case OP_CRRANGE:
2620            case OP_CRMINRANGE:            case OP_CRMINRANGE:
2621              case OP_CRPOSRANGE:
2622            count = current_state->count;  /* Already matched */            count = current_state->count;  /* Already matched */
2623            if (count >= GET2(ecode, 1))            if (count >= (int)GET2(ecode, 1))
2624              { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }              { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
2625            if (isinclass)            if (isinclass)
2626              {              {
2627              int max = GET2(ecode, 1 + IMM2_SIZE);              int max = (int)GET2(ecode, 1 + IMM2_SIZE);
2628                if (*ecode == OP_CRPOSRANGE)
2629                  {
2630                  active_count--;           /* Remove non-match possibility */
2631                  next_active_state--;
2632                  }
2633              if (++count >= max && max != 0)   /* Max 0 => no limit */              if (++count >= max && max != 0)   /* Max 0 => no limit */
2634                { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }                { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
2635              else              else
# Line 2662  for (;;) Line 2705  for (;;)
2705              cb.version          = 1;   /* Version 1 of the callout block */              cb.version          = 1;   /* Version 1 of the callout block */
2707              cb.offset_vector    = offsets;              cb.offset_vector    = offsets;
2708  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2709              cb.subject          = (PCRE_SPTR)start_subject;              cb.subject          = (PCRE_SPTR)start_subject;
2710  #else  #elif defined COMPILE_PCRE16
2711              cb.subject          = (PCRE_SPTR16)start_subject;              cb.subject          = (PCRE_SPTR16)start_subject;
2712    #elif defined COMPILE_PCRE32
2713                cb.subject          = (PCRE_SPTR32)start_subject;
2714  #endif  #endif
2715              cb.subject_length   = (int)(end_subject - start_subject);              cb.subject_length   = (int)(end_subject - start_subject);
2716              cb.start_match      = (int)(current_subject - start_subject);              cb.start_match      = (int)(current_subject - start_subject);
# Line 2684  for (;;) Line 2729  for (;;)
2729
2731
2732          /* Back reference conditions are not supported */          /* Back reference conditions and duplicate named recursion conditions
2733            are not supported */
2734
2735          if (condcode == OP_CREF || condcode == OP_NCREF)          if (condcode == OP_CREF || condcode == OP_DNCREF ||
2736                condcode == OP_DNRREF)
2737            return PCRE_ERROR_DFA_UCOND;            return PCRE_ERROR_DFA_UCOND;
2738
2739          /* The DEFINE condition is always false */          /* The DEFINE condition is always false */
# Line 2698  for (;;) Line 2745  for (;;)
2745          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
2746          recursed groups. */          recursed groups. */
2747
2748          else if (condcode == OP_RREF || condcode == OP_NRREF)          else if (condcode == OP_RREF)
2749            {            {
2750            int value = GET2(code, LINK_SIZE + 2);            int value = GET2(code, LINK_SIZE + 2);
2751            if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND;            if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND;
# Line 2796  for (;;) Line 2843  for (;;)
2843            for (rc = rc*2 - 2; rc >= 0; rc -= 2)            for (rc = rc*2 - 2; rc >= 0; rc -= 2)
2844              {              {
2845              int charcount = local_offsets[rc+1] - local_offsets[rc];              int charcount = local_offsets[rc+1] - local_offsets[rc];
2846  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2847              const pcre_uchar *p = start_subject + local_offsets[rc];              if (utf)
2848              const pcre_uchar *pp = start_subject + local_offsets[rc+1];                {
2849              while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;                const pcre_uchar *p = start_subject + local_offsets[rc];
2850                  const pcre_uchar *pp = start_subject + local_offsets[rc+1];
2851                  while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
2852                  }
2853  #endif  #endif
2854              if (charcount > 0)              if (charcount > 0)
2855                {                {
# Line 2897  for (;;) Line 2947  for (;;)
2947              const pcre_uchar *p = ptr;              const pcre_uchar *p = ptr;
2948              const pcre_uchar *pp = local_ptr;              const pcre_uchar *pp = local_ptr;
2949              charcount = (int)(pp - p);              charcount = (int)(pp - p);
2950  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2951              while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;              if (utf) while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
2952  #endif  #endif
2954              }              }
# Line 2979  for (;;) Line 3029  for (;;)
3029              }              }
3030            else            else
3031              {              {
3032  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3033              const pcre_uchar *p = start_subject + local_offsets[0];              if (utf)
3034              const pcre_uchar *pp = start_subject + local_offsets[1];                {
3035              while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;                const pcre_uchar *p = start_subject + local_offsets[0];
3036                  const pcre_uchar *pp = start_subject + local_offsets[1];
3037                  while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
3038                  }
3039  #endif  #endif
3041              if (repeat_state_offset >= 0)              if (repeat_state_offset >= 0)
# Line 3005  for (;;) Line 3058  for (;;)
3058          cb.version          = 1;   /* Version 1 of the callout block */          cb.version          = 1;   /* Version 1 of the callout block */
3059          cb.callout_number   = code[1];          cb.callout_number   = code[1];
3060          cb.offset_vector    = offsets;          cb.offset_vector    = offsets;
3061  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3062          cb.subject          = (PCRE_SPTR)start_subject;          cb.subject          = (PCRE_SPTR)start_subject;
3063  #else  #elif defined COMPILE_PCRE16
3064          cb.subject          = (PCRE_SPTR16)start_subject;          cb.subject          = (PCRE_SPTR16)start_subject;
3065    #elif defined COMPILE_PCRE32
3066            cb.subject          = (PCRE_SPTR32)start_subject;
3067  #endif  #endif
3068          cb.subject_length   = (int)(end_subject - start_subject);          cb.subject_length   = (int)(end_subject - start_subject);
3069          cb.start_match      = (int)(current_subject - start_subject);          cb.start_match      = (int)(current_subject - start_subject);
# Line 3066  for (;;) Line 3121  for (;;)
3121            ptr > md->start_used_ptr)            /* Inspected non-empty string */            ptr > md->start_used_ptr)            /* Inspected non-empty string */
3122            )            )
3123          )          )
{
if (offsetcount >= 2)
{
offsets[0] = (int)(md->start_used_ptr - start_subject);
offsets[1] = (int)(end_subject - start_subject);
}
3124        match_count = PCRE_ERROR_PARTIAL;        match_count = PCRE_ERROR_PARTIAL;
}

3125      DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n"      DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n"
3126        "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, match_count,        "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, match_count,
3127        rlevel*2-2, SP));        rlevel*2-2, SP));
# Line 3124  Returns:          > 0 => number of match Line 3171  Returns:          > 0 => number of match
3171                   < -1 => some kind of unexpected problem                   < -1 => some kind of unexpected problem
3172  */  */
3173
3174  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3175  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
3176  pcre_dfa_exec(const pcre *argument_re, const pcre_extra *extra_data,  pcre_dfa_exec(const pcre *argument_re, const pcre_extra *extra_data,
3177    const char *subject, int length, int start_offset, int options, int *offsets,    const char *subject, int length, int start_offset, int options, int *offsets,
3178    int offsetcount, int *workspace, int wscount)    int offsetcount, int *workspace, int wscount)
3179  #else  #elif defined COMPILE_PCRE16
3180  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
3181  pcre16_dfa_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,  pcre16_dfa_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
3182    PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,    PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,
3183    int offsetcount, int *workspace, int wscount)    int offsetcount, int *workspace, int wscount)
3184    #elif defined COMPILE_PCRE32
3185    PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
3186    pcre32_dfa_exec(const pcre32 *argument_re, const pcre32_extra *extra_data,
3187      PCRE_SPTR32 subject, int length, int start_offset, int options, int *offsets,
3188      int offsetcount, int *workspace, int wscount)
3189  #endif  #endif
3190  {  {
3191  REAL_PCRE *re = (REAL_PCRE *)argument_re;  REAL_PCRE *re = (REAL_PCRE *)argument_re;
# Line 3160  if (re == NULL || subject == NULL || wor Line 3212  if (re == NULL || subject == NULL || wor
3212     (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;     (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
3213  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
3214  if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE;  if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE;
3215    if (length < 0) return PCRE_ERROR_BADLENGTH;
3216  if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;  if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
3217
3218  /* Check that the first field in the block is the magic number. If it is not,  /* Check that the first field in the block is the magic number. If it is not,
# Line 3208  end_subject = (const pcre_uchar *)subjec Line 3261  end_subject = (const pcre_uchar *)subjec
3261  req_char_ptr = current_subject - 1;  req_char_ptr = current_subject - 1;
3262
3263  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3264  /* PCRE_UTF16 has the same value as PCRE_UTF8. */  /* PCRE_UTF(16|32) have the same value as PCRE_UTF8. */
3265  utf = (re->options & PCRE_UTF8) != 0;  utf = (re->options & PCRE_UTF8) != 0;
3266  #else  #else
3267  utf = FALSE;  utf = FALSE;
# Line 3294  if (utf && (options & PCRE_NO_UTF8_CHECK Line 3347  if (utf && (options & PCRE_NO_UTF8_CHECK
3347        offsets[0] = erroroffset;        offsets[0] = erroroffset;
3348        offsets[1] = errorcode;        offsets[1] = errorcode;
3349        }        }
3350      return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0)?  #if defined COMPILE_PCRE8
3351        return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0) ?
3353    #elif defined COMPILE_PCRE16
3354        return (errorcode <= PCRE_UTF16_ERR1 && (options & PCRE_PARTIAL_HARD) != 0) ?
3356    #elif defined COMPILE_PCRE32
3358    #endif
3359      }      }
3360    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3361    if (start_offset > 0 && start_offset < length &&    if (start_offset > 0 && start_offset < length &&
3362          NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))          NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))
3364    #endif
3365    }    }
3366  #endif  #endif
3367
# Line 3409  for (;;) Line 3471  for (;;)
3471        if (has_first_char)        if (has_first_char)
3472          {          {
3473          if (first_char != first_char2)          if (first_char != first_char2)
3474              {
3475              pcre_uchar csc;
3476            while (current_subject < end_subject &&            while (current_subject < end_subject &&
3477                *current_subject != first_char && *current_subject != first_char2)                   (csc = *current_subject) != first_char && csc != first_char2)
3478              current_subject++;              current_subject++;
3479              }
3480          else          else
3481            while (current_subject < end_subject &&            while (current_subject < end_subject &&
3482                   *current_subject != first_char)                   *current_subject != first_char)
# Line 3446  for (;;) Line 3511  for (;;)
3511
3512            if (current_subject[-1] == CHAR_CR &&            if (current_subject[-1] == CHAR_CR &&
3513                 (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&                 (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
3514                 current_subject < end_subject &&                 current_subject < end_subject && *current_subject == CHAR_NL)
*current_subject == CHAR_NL)
3515              current_subject++;              current_subject++;
3516            }            }
3517          }          }
# Line 3458  for (;;) Line 3522  for (;;)
3522          {          {
3523          while (current_subject < end_subject)          while (current_subject < end_subject)
3524            {            {
3525            register unsigned int c = *current_subject;            register pcre_uint32 c = *current_subject;
3526  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3527            if (c > 255) c = 255;            if (c > 255) c = 255;
3528  #endif  #endif
# Line 3524  for (;;) Line 3588  for (;;)
3588              {              {
3589              while (p < end_subject)              while (p < end_subject)
3590                {                {
3591                register int pp = *p++;                register pcre_uint32 pp = *p++;
3592                if (pp == req_char || pp == req_char2) { p--; break; }                if (pp == req_char || pp == req_char2) { p--; break; }
3593                }                }
3594              }              }
# Line 3570  for (;;) Line 3634  for (;;)
3634    /* Anything other than "no match" means we are done, always; otherwise, carry    /* Anything other than "no match" means we are done, always; otherwise, carry
3635    on only if not anchored. */    on only if not anchored. */
3636
3637    if (rc != PCRE_ERROR_NOMATCH || anchored) return rc;    if (rc != PCRE_ERROR_NOMATCH || anchored)
3638        {
3639        if (rc == PCRE_ERROR_PARTIAL && offsetcount >= 2)
3640          {
3641          offsets[0] = (int)(md->start_used_ptr - (PCRE_PUCHAR)subject);
3642          offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);
3643          if (offsetcount > 2)
3644            offsets[2] = (int)(current_subject - (PCRE_PUCHAR)subject);
3645          }
3646        return rc;
3647        }
3648
3649    /* 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
3650    and firstline is set. */    and firstline is set. */

Legend:
 Removed from v.975 changed lines Added in v.1425