/[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 518 by ph10, Tue May 18 15:47:01 2010 UTC revision 604 by ph10, Thu Jun 2 19:04:54 2011 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-2010 University of Cambridge             Copyright (c) 1997-2011 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 121  static const uschar coptable[] = { Line 121  static const uschar coptable[] = {
121    0, 0,                          /* \P, \p                                 */    0, 0,                          /* \P, \p                                 */
122    0, 0, 0, 0, 0,                 /* \R, \H, \h, \V, \v                     */    0, 0, 0, 0, 0,                 /* \R, \H, \h, \V, \v                     */
123    0,                             /* \X                                     */    0,                             /* \X                                     */
124    0, 0, 0, 0, 0,                 /* \Z, \z, Opt, ^, $                      */    0, 0, 0, 0, 0, 0,              /* \Z, \z, ^, ^M, $, $M                   */
125    1,                             /* Char                                   */    1,                             /* Char                                   */
126    1,                             /* Charnc                                 */    1,                             /* Chari                                  */
127    1,                             /* not                                    */    1,                             /* not                                    */
128      1,                             /* noti                                   */
129    /* Positive single-char repeats                                          */    /* Positive single-char repeats                                          */
130    1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */    1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */
131    3, 3, 3,                       /* upto, minupto, exact                   */    3, 3, 3,                       /* upto, minupto, exact                   */
132    1, 1, 1, 3,                    /* *+, ++, ?+, upto+                      */    1, 1, 1, 3,                    /* *+, ++, ?+, upto+                      */
133      1, 1, 1, 1, 1, 1,              /* *I, *?I, +I, +?I, ?I, ??I              */
134      3, 3, 3,                       /* upto I, minupto I, exact I             */
135      1, 1, 1, 3,                    /* *+I, ++I, ?+I, upto+I                  */
136    /* Negative single-char repeats - only for chars < 256                   */    /* Negative single-char repeats - only for chars < 256                   */
137    1, 1, 1, 1, 1, 1,              /* NOT *, *?, +, +?, ?, ??                */    1, 1, 1, 1, 1, 1,              /* NOT *, *?, +, +?, ?, ??                */
138    3, 3, 3,                       /* NOT upto, minupto, exact               */    3, 3, 3,                       /* NOT upto, minupto, exact               */
139    1, 1, 1, 3,                    /* NOT *+, ++, ?+, updo+                  */    1, 1, 1, 3,                    /* NOT *+, ++, ?+, upto+                  */
140      1, 1, 1, 1, 1, 1,              /* NOT *I, *?I, +I, +?I, ?I, ??I          */
141      3, 3, 3,                       /* NOT upto I, minupto I, exact I         */
142      1, 1, 1, 3,                    /* NOT *+I, ++I, ?+I, upto+I              */
143    /* Positive type repeats                                                 */    /* Positive type repeats                                                 */
144    1, 1, 1, 1, 1, 1,              /* Type *, *?, +, +?, ?, ??               */    1, 1, 1, 1, 1, 1,              /* Type *, *?, +, +?, ?, ??               */
145    3, 3, 3,                       /* Type upto, minupto, exact              */    3, 3, 3,                       /* Type upto, minupto, exact              */
# Line 144  static const uschar coptable[] = { Line 151  static const uschar coptable[] = {
151    0,                             /* NCLASS                                 */    0,                             /* NCLASS                                 */
152    0,                             /* XCLASS - variable length               */    0,                             /* XCLASS - variable length               */
153    0,                             /* REF                                    */    0,                             /* REF                                    */
154      0,                             /* REFI                                   */
155    0,                             /* RECURSE                                */    0,                             /* RECURSE                                */
156    0,                             /* CALLOUT                                */    0,                             /* CALLOUT                                */
157    0,                             /* Alt                                    */    0,                             /* Alt                                    */
158    0,                             /* Ket                                    */    0,                             /* Ket                                    */
159    0,                             /* KetRmax                                */    0,                             /* KetRmax                                */
160    0,                             /* KetRmin                                */    0,                             /* KetRmin                                */
161      0,                             /* KetRpos                                */
162    0,                             /* Assert                                 */    0,                             /* Assert                                 */
163    0,                             /* Assert not                             */    0,                             /* Assert not                             */
164    0,                             /* Assert behind                          */    0,                             /* Assert behind                          */
165    0,                             /* Assert behind not                      */    0,                             /* Assert behind not                      */
166    0,                             /* Reverse                                */    0,                             /* Reverse                                */
167    0, 0, 0, 0,                    /* ONCE, BRA, CBRA, COND                  */    0, 0, 0, 0, 0, 0,              /* ONCE, BRA, BRAPOS, CBRA, CBRAPOS, COND */
168    0, 0, 0,                       /* SBRA, SCBRA, SCOND                     */    0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */
169    0, 0,                          /* CREF, NCREF                            */    0, 0,                          /* CREF, NCREF                            */
170    0, 0,                          /* RREF, NRREF                            */    0, 0,                          /* RREF, NRREF                            */
171    0,                             /* DEF                                    */    0,                             /* DEF                                    */
172    0, 0,                          /* BRAZERO, BRAMINZERO                    */    0, 0, 0,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */
173    0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG,                */    0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG,                */
174    0, 0, 0, 0,                    /* SKIP, SKIP_ARG, THEN, THEN_ARG,        */    0, 0, 0, 0,                    /* SKIP, SKIP_ARG, THEN, THEN_ARG,        */
175    0, 0, 0, 0, 0                  /* COMMIT, FAIL, ACCEPT, CLOSE, SKIPZERO  */    0, 0, 0, 0, 0                  /* COMMIT, FAIL, ACCEPT, CLOSE, SKIPZERO  */
# Line 179  static const uschar poptable[] = { Line 188  static const uschar poptable[] = {
188    1, 1,                          /* \P, \p                                 */    1, 1,                          /* \P, \p                                 */
189    1, 1, 1, 1, 1,                 /* \R, \H, \h, \V, \v                     */    1, 1, 1, 1, 1,                 /* \R, \H, \h, \V, \v                     */
190    1,                             /* \X                                     */    1,                             /* \X                                     */
191    0, 0, 0, 0, 0,                 /* \Z, \z, Opt, ^, $                      */    0, 0, 0, 0, 0, 0,              /* \Z, \z, ^, ^M, $, $M                   */
192    1,                             /* Char                                   */    1,                             /* Char                                   */
193    1,                             /* Charnc                                 */    1,                             /* Chari                                  */
194    1,                             /* not                                    */    1,                             /* not                                    */
195      1,                             /* noti                                   */
196    /* Positive single-char repeats                                          */    /* Positive single-char repeats                                          */
197    1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */    1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */
198    1, 1, 1,                       /* upto, minupto, exact                   */    1, 1, 1,                       /* upto, minupto, exact                   */
199    1, 1, 1, 1,                    /* *+, ++, ?+, upto+                      */    1, 1, 1, 1,                    /* *+, ++, ?+, upto+                      */
200      1, 1, 1, 1, 1, 1,              /* *I, *?I, +I, +?I, ?I, ??I              */
201      1, 1, 1,                       /* upto I, minupto I, exact I             */
202      1, 1, 1, 1,                    /* *+I, ++I, ?+I, upto+I                  */
203    /* Negative single-char repeats - only for chars < 256                   */    /* Negative single-char repeats - only for chars < 256                   */
204    1, 1, 1, 1, 1, 1,              /* NOT *, *?, +, +?, ?, ??                */    1, 1, 1, 1, 1, 1,              /* NOT *, *?, +, +?, ?, ??                */
205    1, 1, 1,                       /* NOT upto, minupto, exact               */    1, 1, 1,                       /* NOT upto, minupto, exact               */
206    1, 1, 1, 1,                    /* NOT *+, ++, ?+, upto+                  */    1, 1, 1, 1,                    /* NOT *+, ++, ?+, upto+                  */
207      1, 1, 1, 1, 1, 1,              /* NOT *I, *?I, +I, +?I, ?I, ??I          */
208      1, 1, 1,                       /* NOT upto I, minupto I, exact I         */
209      1, 1, 1, 1,                    /* NOT *+I, ++I, ?+I, upto+I              */
210    /* Positive type repeats                                                 */    /* Positive type repeats                                                 */
211    1, 1, 1, 1, 1, 1,              /* Type *, *?, +, +?, ?, ??               */    1, 1, 1, 1, 1, 1,              /* Type *, *?, +, +?, ?, ??               */
212    1, 1, 1,                       /* Type upto, minupto, exact              */    1, 1, 1,                       /* Type upto, minupto, exact              */
# Line 202  static const uschar poptable[] = { Line 218  static const uschar poptable[] = {
218    1,                             /* NCLASS                                 */    1,                             /* NCLASS                                 */
219    1,                             /* XCLASS - variable length               */    1,                             /* XCLASS - variable length               */
220    0,                             /* REF                                    */    0,                             /* REF                                    */
221      0,                             /* REFI                                   */
222    0,                             /* RECURSE                                */    0,                             /* RECURSE                                */
223    0,                             /* CALLOUT                                */    0,                             /* CALLOUT                                */
224    0,                             /* Alt                                    */    0,                             /* Alt                                    */
225    0,                             /* Ket                                    */    0,                             /* Ket                                    */
226    0,                             /* KetRmax                                */    0,                             /* KetRmax                                */
227    0,                             /* KetRmin                                */    0,                             /* KetRmin                                */
228      0,                             /* KetRpos                                */
229    0,                             /* Assert                                 */    0,                             /* Assert                                 */
230    0,                             /* Assert not                             */    0,                             /* Assert not                             */
231    0,                             /* Assert behind                          */    0,                             /* Assert behind                          */
232    0,                             /* Assert behind not                      */    0,                             /* Assert behind not                      */
233    0,                             /* Reverse                                */    0,                             /* Reverse                                */
234    0, 0, 0, 0,                    /* ONCE, BRA, CBRA, COND                  */    0, 0, 0, 0, 0, 0,              /* ONCE, BRA, BRAPOS, CBRA, CBRAPOS, COND */
235    0, 0, 0,                       /* SBRA, SCBRA, SCOND                     */    0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */
236    0, 0,                          /* CREF, NCREF                            */    0, 0,                          /* CREF, NCREF                            */
237    0, 0,                          /* RREF, NRREF                            */    0, 0,                          /* RREF, NRREF                            */
238    0,                             /* DEF                                    */    0,                             /* DEF                                    */
239    0, 0,                          /* BRAZERO, BRAMINZERO                    */    0, 0, 0,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */
240    0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG,                */    0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG,                */
241    0, 0, 0, 0,                    /* SKIP, SKIP_ARG, THEN, THEN_ARG,        */    0, 0, 0, 0,                    /* SKIP, SKIP_ARG, THEN, THEN_ARG,        */
242    0, 0, 0, 0, 0                  /* COMMIT, FAIL, ACCEPT, CLOSE, SKIPZERO  */    0, 0, 0, 0, 0                  /* COMMIT, FAIL, ACCEPT, CLOSE, SKIPZERO  */
# Line 252  these structures in, is a vector of ints Line 270  these structures in, is a vector of ints
270  typedef struct stateblock {  typedef struct stateblock {
271    int offset;                     /* Offset to opcode */    int offset;                     /* Offset to opcode */
272    int count;                      /* Count for repeats */    int count;                      /* Count for repeats */
   int ims;                        /* ims flag bits */  
273    int data;                       /* Some use extra data */    int data;                       /* Some use extra data */
274  } stateblock;  } stateblock;
275    
# Line 308  Arguments: Line 325  Arguments:
325    offsetcount       size of same    offsetcount       size of same
326    workspace         vector of workspace    workspace         vector of workspace
327    wscount           size of same    wscount           size of same
   ims               the current ims flags  
328    rlevel            function call recursion level    rlevel            function call recursion level
329    recursing         regex recursive call level    recursing         regex recursive call level
330    
# Line 325  for the current character, one for the f Line 341  for the current character, one for the f
341      { \      { \
342      next_active_state->offset = (x); \      next_active_state->offset = (x); \
343      next_active_state->count  = (y); \      next_active_state->count  = (y); \
     next_active_state->ims    = ims; \  
344      next_active_state++; \      next_active_state++; \
345      DPRINTF(("%.*sADD_ACTIVE(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \      DPRINTF(("%.*sADD_ACTIVE(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \
346      } \      } \
# Line 336  for the current character, one for the f Line 351  for the current character, one for the f
351      { \      { \
352      next_active_state->offset = (x); \      next_active_state->offset = (x); \
353      next_active_state->count  = (y); \      next_active_state->count  = (y); \
     next_active_state->ims    = ims; \  
354      next_active_state->data   = (z); \      next_active_state->data   = (z); \
355      next_active_state++; \      next_active_state++; \
356      DPRINTF(("%.*sADD_ACTIVE_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \      DPRINTF(("%.*sADD_ACTIVE_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \
# Line 348  for the current character, one for the f Line 362  for the current character, one for the f
362      { \      { \
363      next_new_state->offset = (x); \      next_new_state->offset = (x); \
364      next_new_state->count  = (y); \      next_new_state->count  = (y); \
     next_new_state->ims    = ims; \  
365      next_new_state++; \      next_new_state++; \
366      DPRINTF(("%.*sADD_NEW(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \      DPRINTF(("%.*sADD_NEW(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \
367      } \      } \
# Line 359  for the current character, one for the f Line 372  for the current character, one for the f
372      { \      { \
373      next_new_state->offset = (x); \      next_new_state->offset = (x); \
374      next_new_state->count  = (y); \      next_new_state->count  = (y); \
     next_new_state->ims    = ims; \  
375      next_new_state->data   = (z); \      next_new_state->data   = (z); \
376      next_new_state++; \      next_new_state++; \
377      DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \      DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \
# Line 378  internal_dfa_exec( Line 390  internal_dfa_exec(
390    int offsetcount,    int offsetcount,
391    int *workspace,    int *workspace,
392    int wscount,    int wscount,
   int ims,  
393    int  rlevel,    int  rlevel,
394    int  recursing)    int  recursing)
395  {  {
# Line 426  next_new_state = new_states = active_sta Line 437  next_new_state = new_states = active_sta
437  new_count = 0;  new_count = 0;
438    
439  first_op = this_start_code + 1 + LINK_SIZE +  first_op = this_start_code + 1 + LINK_SIZE +
440    ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA)? 2:0);    ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA ||
441        *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS)? 2:0);
442    
443  /* The first thing in any (sub) pattern is a bracket of some sort. Push all  /* The first thing in any (sub) pattern is a bracket of some sort. Push all
444  the alternative states onto the list, and find out where the end is. This  the alternative states onto the list, and find out where the end is. This
# Line 475  if (*first_op == OP_REVERSE) Line 487  if (*first_op == OP_REVERSE)
487    
488      {      {
489      gone_back = (current_subject - max_back < start_subject)?      gone_back = (current_subject - max_back < start_subject)?
490        current_subject - start_subject : max_back;        (int)(current_subject - start_subject) : max_back;
491      current_subject -= gone_back;      current_subject -= gone_back;
492      }      }
493    
# Line 492  if (*first_op == OP_REVERSE) Line 504  if (*first_op == OP_REVERSE)
504      int back = GET(end_code, 2+LINK_SIZE);      int back = GET(end_code, 2+LINK_SIZE);
505      if (back <= gone_back)      if (back <= gone_back)
506        {        {
507        int bstate = end_code - start_code + 2 + 2*LINK_SIZE;        int bstate = (int)(end_code - start_code + 2 + 2*LINK_SIZE);
508        ADD_NEW_DATA(-bstate, 0, gone_back - back);        ADD_NEW_DATA(-bstate, 0, gone_back - back);
509        }        }
510      end_code += GET(end_code, 1);      end_code += GET(end_code, 1);
# Line 525  else Line 537  else
537    else    else
538      {      {
539      int length = 1 + LINK_SIZE +      int length = 1 + LINK_SIZE +
540        ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA)? 2:0);        ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA ||
541            *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS)?
542            2:0);
543      do      do
544        {        {
545        ADD_NEW(end_code - start_code + length, 0);        ADD_NEW((int)(end_code - start_code + length), 0);
546        end_code += GET(end_code, 1);        end_code += GET(end_code, 1);
547        length = 1 + LINK_SIZE;        length = 1 + LINK_SIZE;
548        }        }
# Line 605  for (;;) Line 619  for (;;)
619    for (i = 0; i < active_count; i++)    for (i = 0; i < active_count; i++)
620      {      {
621      stateblock *current_state = active_states + i;      stateblock *current_state = active_states + i;
622        BOOL caseless = FALSE;
623      const uschar *code;      const uschar *code;
624      int state_offset = current_state->offset;      int state_offset = current_state->offset;
625      int count, codevalue, rrc;      int count, codevalue, rrc;
# Line 616  for (;;) Line 631  for (;;)
631          else printf("0x%02x\n", c);          else printf("0x%02x\n", c);
632  #endif  #endif
633    
     /* This variable is referred to implicity in the ADD_xxx macros. */  
   
     ims = current_state->ims;  
   
634      /* 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
635      (negated) state until the number of characters in the data field have      (negated) state until the number of characters in the data field have
636      been skipped". */      been skipped". */
# Line 725  for (;;) Line 736  for (;;)
736    
737  /* ========================================================================== */  /* ========================================================================== */
738        /* Reached a closing bracket. If not at the end of the pattern, carry        /* Reached a closing bracket. If not at the end of the pattern, carry
739        on with the next opcode. Otherwise, unless we have an empty string and        on with the next opcode. For repeating opcodes, also add the repeat
740          state. Note that KETRPOS will always be encountered at the end of the
741          subpattern, because the possessive subpattern repeats are always handled
742          using recursive calls. Thus, it never adds any new states.
743    
744          At the end of the (sub)pattern, unless we have an empty string and
745        PCRE_NOTEMPTY is set, or PCRE_NOTEMPTY_ATSTART is set and we are at the        PCRE_NOTEMPTY is set, or PCRE_NOTEMPTY_ATSTART is set and we are at the
746        start of the subject, save the match data, shifting up all previous        start of the subject, save the match data, shifting up all previous
747        matches so we always have the longest first. */        matches so we always have the longest first. */
# Line 733  for (;;) Line 749  for (;;)
749        case OP_KET:        case OP_KET:
750        case OP_KETRMIN:        case OP_KETRMIN:
751        case OP_KETRMAX:        case OP_KETRMAX:
752          case OP_KETRPOS:
753        if (code != end_code)        if (code != end_code)
754          {          {
755          ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0);          ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0);
# Line 755  for (;;) Line 772  for (;;)
772            if (count > 0) memmove(offsets + 2, offsets, count * sizeof(int));            if (count > 0) memmove(offsets + 2, offsets, count * sizeof(int));
773            if (offsetcount >= 2)            if (offsetcount >= 2)
774              {              {
775              offsets[0] = current_subject - start_subject;              offsets[0] = (int)(current_subject - start_subject);
776              offsets[1] = ptr - start_subject;              offsets[1] = (int)(ptr - start_subject);
777              DPRINTF(("%.*sSet matched string = \"%.*s\"\n", rlevel*2-2, SP,              DPRINTF(("%.*sSet matched string = \"%.*s\"\n", rlevel*2-2, SP,
778                offsets[1] - offsets[0], current_subject));                offsets[1] - offsets[0], current_subject));
779              }              }
# Line 778  for (;;) Line 795  for (;;)
795        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
796        case OP_ALT:        case OP_ALT:
797        do { code += GET(code, 1); } while (*code == OP_ALT);        do { code += GET(code, 1); } while (*code == OP_ALT);
798        ADD_ACTIVE(code - start_code, 0);        ADD_ACTIVE((int)(code - start_code), 0);
799        break;        break;
800    
801        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
# Line 786  for (;;) Line 803  for (;;)
803        case OP_SBRA:        case OP_SBRA:
804        do        do
805          {          {
806          ADD_ACTIVE(code - start_code + 1 + LINK_SIZE, 0);          ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
807          code += GET(code, 1);          code += GET(code, 1);
808          }          }
809        while (*code == OP_ALT);        while (*code == OP_ALT);
# Line 795  for (;;) Line 812  for (;;)
812        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
813        case OP_CBRA:        case OP_CBRA:
814        case OP_SCBRA:        case OP_SCBRA:
815        ADD_ACTIVE(code - start_code + 3 + LINK_SIZE,  0);        ADD_ACTIVE((int)(code - start_code + 3 + LINK_SIZE),  0);
816        code += GET(code, 1);        code += GET(code, 1);
817        while (*code == OP_ALT)        while (*code == OP_ALT)
818          {          {
819          ADD_ACTIVE(code - start_code + 1 + LINK_SIZE,  0);          ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE),  0);
820          code += GET(code, 1);          code += GET(code, 1);
821          }          }
822        break;        break;
# Line 810  for (;;) Line 827  for (;;)
827        ADD_ACTIVE(state_offset + 1, 0);        ADD_ACTIVE(state_offset + 1, 0);
828        code += 1 + GET(code, 2);        code += 1 + GET(code, 2);
829        while (*code == OP_ALT) code += GET(code, 1);        while (*code == OP_ALT) code += GET(code, 1);
830        ADD_ACTIVE(code - start_code + 1 + LINK_SIZE, 0);        ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
831        break;        break;
832    
833        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
834        case OP_SKIPZERO:        case OP_SKIPZERO:
835        code += 1 + GET(code, 2);        code += 1 + GET(code, 2);
836        while (*code == OP_ALT) code += GET(code, 1);        while (*code == OP_ALT) code += GET(code, 1);
837        ADD_ACTIVE(code - start_code + 1 + LINK_SIZE, 0);        ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
838        break;        break;
839    
840        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
841        case OP_CIRC:        case OP_CIRC:
842        if ((ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0) ||        if (ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0)
           ((ims & PCRE_MULTILINE) != 0 &&  
             ptr != end_subject &&  
             WAS_NEWLINE(ptr)))  
843          { ADD_ACTIVE(state_offset + 1, 0); }          { ADD_ACTIVE(state_offset + 1, 0); }
844        break;        break;
845    
846        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
847        case OP_EOD:        case OP_CIRCM:
848        if (ptr >= end_subject) { ADD_ACTIVE(state_offset + 1, 0); }        if ((ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0) ||
849              (ptr != end_subject && WAS_NEWLINE(ptr)))
850            { ADD_ACTIVE(state_offset + 1, 0); }
851        break;        break;
852    
853        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
854        case OP_OPT:        case OP_EOD:
855        ims = code[1];        if (ptr >= end_subject)
856        ADD_ACTIVE(state_offset + 2, 0);          {
857            if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
858              could_continue = TRUE;
859            else { ADD_ACTIVE(state_offset + 1, 0); }
860            }
861        break;        break;
862    
863        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
# Line 871  for (;;) Line 891  for (;;)
891    
892        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
893        case OP_EODN:        case OP_EODN:
894        if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - md->nllen))        if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0)
895            could_continue = TRUE;
896          else if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - md->nllen))
897          { ADD_ACTIVE(state_offset + 1, 0); }          { ADD_ACTIVE(state_offset + 1, 0); }
898        break;        break;
899    
# Line 879  for (;;) Line 901  for (;;)
901        case OP_DOLL:        case OP_DOLL:
902        if ((md->moptions & PCRE_NOTEOL) == 0)        if ((md->moptions & PCRE_NOTEOL) == 0)
903          {          {
904          if (clen == 0 ||          if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0)
905              could_continue = TRUE;
906            else if (clen == 0 ||
907              ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr) &&              ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr) &&
908                 ((ims & PCRE_MULTILINE) != 0 || ptr == end_subject - md->nllen)                 (ptr == end_subject - md->nllen)
909              ))              ))
910            { ADD_ACTIVE(state_offset + 1, 0); }            { ADD_ACTIVE(state_offset + 1, 0); }
911          }          }
912        else if ((ims & PCRE_MULTILINE) != 0 && IS_NEWLINE(ptr))        break;
913    
914          /*-----------------------------------------------------------------*/
915          case OP_DOLLM:
916          if ((md->moptions & PCRE_NOTEOL) == 0)
917            {
918            if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0)
919              could_continue = TRUE;
920            else if (clen == 0 ||
921                ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr)))
922              { ADD_ACTIVE(state_offset + 1, 0); }
923            }
924          else if (IS_NEWLINE(ptr))
925          { ADD_ACTIVE(state_offset + 1, 0); }          { ADD_ACTIVE(state_offset + 1, 0); }
926        break;        break;
927    
# Line 922  for (;;) Line 958  for (;;)
958            if (utf8) BACKCHAR(temp);            if (utf8) BACKCHAR(temp);
959  #endif  #endif
960            GETCHARTEST(d, temp);            GETCHARTEST(d, temp);
961  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
962            if ((md->poptions & PCRE_UCP) != 0)            if ((md->poptions & PCRE_UCP) != 0)
963              {              {
964              if (d == '_') left_word = TRUE; else              if (d == '_') left_word = TRUE; else
965                {                {
966                int cat = UCD_CATEGORY(d);                int cat = UCD_CATEGORY(d);
967                left_word = (cat == ucp_L || cat == ucp_N);                left_word = (cat == ucp_L || cat == ucp_N);
968                }                }
969              }              }
970            else            else
971  #endif  #endif
972            left_word = d < 256 && (ctypes[d] & ctype_word) != 0;            left_word = d < 256 && (ctypes[d] & ctype_word) != 0;
973            }            }
974          else left_word = FALSE;          else left_word = FALSE;
975    
976          if (clen > 0)          if (clen > 0)
977            {            {
978  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
979            if ((md->poptions & PCRE_UCP) != 0)            if ((md->poptions & PCRE_UCP) != 0)
980              {              {
981              if (c == '_') right_word = TRUE; else              if (c == '_') right_word = TRUE; else
982                {                {
983                int cat = UCD_CATEGORY(c);                int cat = UCD_CATEGORY(c);
984                right_word = (cat == ucp_L || cat == ucp_N);                right_word = (cat == ucp_L || cat == ucp_N);
985                }                }
986              }              }
987            else            else
988  #endif  #endif
989            right_word = c < 256 && (ctypes[c] & ctype_word) != 0;            right_word = c < 256 && (ctypes[c] & ctype_word) != 0;
990            }            }
991          else right_word = FALSE;          else right_word = FALSE;
992    
993          if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY))          if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY))
# Line 979  for (;;) Line 1015  for (;;)
1015            break;            break;
1016    
1017            case PT_LAMP:            case PT_LAMP:
1018            OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||            OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
1019                 prop->chartype == ucp_Lt;                 prop->chartype == ucp_Lt;
1020            break;            break;
1021    
# Line 994  for (;;) Line 1030  for (;;)
1030            case PT_SC:            case PT_SC:
1031            OK = prop->script == code[2];            OK = prop->script == code[2];
1032            break;            break;
1033    
1034            /* These are specials for combination cases. */            /* These are specials for combination cases. */
1035    
1036            case PT_ALNUM:            case PT_ALNUM:
1037            OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||            OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||
1038                 _pcre_ucp_gentype[prop->chartype] == ucp_N;                 _pcre_ucp_gentype[prop->chartype] == ucp_N;
1039            break;            break;
1040    
1041            case PT_SPACE:    /* Perl space */            case PT_SPACE:    /* Perl space */
1042            OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||            OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||
1043                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
1044            break;            break;
1045    
1046            case PT_PXSPACE:  /* POSIX space */            case PT_PXSPACE:  /* POSIX space */
1047            OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||            OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||
1048                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
1049                 c == CHAR_FF || c == CHAR_CR;                 c == CHAR_FF || c == CHAR_CR;
1050            break;            break;
1051    
1052            case PT_WORD:            case PT_WORD:
1053            OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||            OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||
1054                 _pcre_ucp_gentype[prop->chartype] == ucp_N ||                 _pcre_ucp_gentype[prop->chartype] == ucp_N ||
1055                 c == CHAR_UNDERSCORE;                 c == CHAR_UNDERSCORE;
1056            break;            break;
1057    
1058            /* Should never occur, but keep compilers from grumbling. */            /* Should never occur, but keep compilers from grumbling. */
1059    
# Line 1173  for (;;) Line 1209  for (;;)
1209            break;            break;
1210    
1211            case PT_LAMP:            case PT_LAMP:
1212            OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||            OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
1213              prop->chartype == ucp_Lt;              prop->chartype == ucp_Lt;
1214            break;            break;
1215    
# Line 1190  for (;;) Line 1226  for (;;)
1226            break;            break;
1227    
1228            /* These are specials for combination cases. */            /* These are specials for combination cases. */
1229    
1230            case PT_ALNUM:            case PT_ALNUM:
1231            OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||            OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||
1232                 _pcre_ucp_gentype[prop->chartype] == ucp_N;                 _pcre_ucp_gentype[prop->chartype] == ucp_N;
1233            break;            break;
1234    
1235            case PT_SPACE:    /* Perl space */            case PT_SPACE:    /* Perl space */
1236            OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||            OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||
1237                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
1238            break;            break;
1239    
1240            case PT_PXSPACE:  /* POSIX space */            case PT_PXSPACE:  /* POSIX space */
1241            OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||            OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||
1242                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
1243                 c == CHAR_FF || c == CHAR_CR;                 c == CHAR_FF || c == CHAR_CR;
1244            break;            break;
1245    
1246            case PT_WORD:            case PT_WORD:
1247            OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||            OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||
1248                 _pcre_ucp_gentype[prop->chartype] == ucp_N ||                 _pcre_ucp_gentype[prop->chartype] == ucp_N ||
1249                 c == CHAR_UNDERSCORE;                 c == CHAR_UNDERSCORE;
1250            break;            break;
1251    
1252            /* Should never occur, but keep compilers from grumbling. */            /* Should never occur, but keep compilers from grumbling. */
1253    
# Line 1420  for (;;) Line 1456  for (;;)
1456            break;            break;
1457    
1458            case PT_LAMP:            case PT_LAMP:
1459            OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||            OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
1460              prop->chartype == ucp_Lt;              prop->chartype == ucp_Lt;
1461            break;            break;
1462    
# Line 1435  for (;;) Line 1471  for (;;)
1471            case PT_SC:            case PT_SC:
1472            OK = prop->script == code[3];            OK = prop->script == code[3];
1473            break;            break;
1474    
1475            /* These are specials for combination cases. */            /* These are specials for combination cases. */
1476    
1477            case PT_ALNUM:            case PT_ALNUM:
1478            OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||            OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||
1479                 _pcre_ucp_gentype[prop->chartype] == ucp_N;                 _pcre_ucp_gentype[prop->chartype] == ucp_N;
1480            break;            break;
1481    
1482            case PT_SPACE:    /* Perl space */            case PT_SPACE:    /* Perl space */
1483            OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||            OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||
1484                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
1485            break;            break;
1486    
1487            case PT_PXSPACE:  /* POSIX space */            case PT_PXSPACE:  /* POSIX space */
1488            OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||            OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||
1489                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
1490                 c == CHAR_FF || c == CHAR_CR;                 c == CHAR_FF || c == CHAR_CR;
1491            break;            break;
1492    
1493            case PT_WORD:            case PT_WORD:
1494            OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||            OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||
1495                 _pcre_ucp_gentype[prop->chartype] == ucp_N ||                 _pcre_ucp_gentype[prop->chartype] == ucp_N ||
1496                 c == CHAR_UNDERSCORE;                 c == CHAR_UNDERSCORE;
1497            break;            break;
1498    
1499            /* Should never occur, but keep compilers from grumbling. */            /* Should never occur, but keep compilers from grumbling. */
1500    
# Line 1692  for (;;) Line 1728  for (;;)
1728            break;            break;
1729    
1730            case PT_LAMP:            case PT_LAMP:
1731            OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||            OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
1732              prop->chartype == ucp_Lt;              prop->chartype == ucp_Lt;
1733            break;            break;
1734    
# Line 1707  for (;;) Line 1743  for (;;)
1743            case PT_SC:            case PT_SC:
1744            OK = prop->script == code[5];            OK = prop->script == code[5];
1745            break;            break;
1746    
1747            /* These are specials for combination cases. */            /* These are specials for combination cases. */
1748    
1749            case PT_ALNUM:            case PT_ALNUM:
1750            OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||            OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||
1751                 _pcre_ucp_gentype[prop->chartype] == ucp_N;                 _pcre_ucp_gentype[prop->chartype] == ucp_N;
1752            break;            break;
1753    
1754            case PT_SPACE:    /* Perl space */            case PT_SPACE:    /* Perl space */
1755            OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||            OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||
1756                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
1757            break;            break;
1758    
1759            case PT_PXSPACE:  /* POSIX space */            case PT_PXSPACE:  /* POSIX space */
1760            OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||            OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||
1761                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
1762                 c == CHAR_FF || c == CHAR_CR;                 c == CHAR_FF || c == CHAR_CR;
1763            break;            break;
1764    
1765            case PT_WORD:            case PT_WORD:
1766            OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||            OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||
1767                 _pcre_ucp_gentype[prop->chartype] == ucp_N ||                 _pcre_ucp_gentype[prop->chartype] == ucp_N ||
1768                 c == CHAR_UNDERSCORE;                 c == CHAR_UNDERSCORE;
1769            break;            break;
1770    
1771            /* Should never occur, but keep compilers from grumbling. */            /* Should never occur, but keep compilers from grumbling. */
1772    
# Line 1941  for (;;) Line 1977  for (;;)
1977        break;        break;
1978    
1979        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
1980        case OP_CHARNC:        case OP_CHARI:
1981        if (clen == 0) break;        if (clen == 0) break;
1982    
1983  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 2127  for (;;) Line 2163  for (;;)
2163        break;        break;
2164    
2165        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
2166        /* Match a negated single character. This is only used for one-byte        /* Match a negated single character casefully. This is only used for
2167        characters, that is, we know that d < 256. The character we are        one-byte characters, that is, we know that d < 256. The character we are
2168        checking (c) can be multibyte. */        checking (c) can be multibyte. */
2169    
2170        case OP_NOT:        case OP_NOT:
2171        if (clen > 0)        if (clen > 0 && c != d) { ADD_NEW(state_offset + dlen + 1, 0); }
2172          {        break;
2173          unsigned int otherd = ((ims & PCRE_CASELESS) != 0)? fcc[d] : d;  
2174          if (c != d && c != otherd) { ADD_NEW(state_offset + dlen + 1, 0); }        /*-----------------------------------------------------------------*/
2175          }        /* Match a negated single character caselessly. This is only used for
2176          one-byte characters, that is, we know that d < 256. The character we are
2177          checking (c) can be multibyte. */
2178    
2179          case OP_NOTI:
2180          if (clen > 0 && c != d && c != fcc[d])
2181            { ADD_NEW(state_offset + dlen + 1, 0); }
2182        break;        break;
2183    
2184        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
2185          case OP_PLUSI:
2186          case OP_MINPLUSI:
2187          case OP_POSPLUSI:
2188          case OP_NOTPLUSI:
2189          case OP_NOTMINPLUSI:
2190          case OP_NOTPOSPLUSI:
2191          caseless = TRUE;
2192          codevalue -= OP_STARI - OP_STAR;
2193    
2194          /* Fall through */
2195        case OP_PLUS:        case OP_PLUS:
2196        case OP_MINPLUS:        case OP_MINPLUS:
2197        case OP_POSPLUS:        case OP_POSPLUS:
# Line 2151  for (;;) Line 2203  for (;;)
2203        if (clen > 0)        if (clen > 0)
2204          {          {
2205          unsigned int otherd = NOTACHAR;          unsigned int otherd = NOTACHAR;
2206          if ((ims & PCRE_CASELESS) != 0)          if (caseless)
2207            {            {
2208  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2209            if (utf8 && d >= 128)            if (utf8 && d >= 128)
# Line 2179  for (;;) Line 2231  for (;;)
2231        break;        break;
2232    
2233        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
2234          case OP_QUERYI:
2235          case OP_MINQUERYI:
2236          case OP_POSQUERYI:
2237          case OP_NOTQUERYI:
2238          case OP_NOTMINQUERYI:
2239          case OP_NOTPOSQUERYI:
2240          caseless = TRUE;
2241          codevalue -= OP_STARI - OP_STAR;
2242          /* Fall through */
2243        case OP_QUERY:        case OP_QUERY:
2244        case OP_MINQUERY:        case OP_MINQUERY:
2245        case OP_POSQUERY:        case OP_POSQUERY:
# Line 2189  for (;;) Line 2250  for (;;)
2250        if (clen > 0)        if (clen > 0)
2251          {          {
2252          unsigned int otherd = NOTACHAR;          unsigned int otherd = NOTACHAR;
2253          if ((ims & PCRE_CASELESS) != 0)          if (caseless)
2254            {            {
2255  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2256            if (utf8 && d >= 128)            if (utf8 && d >= 128)
# Line 2215  for (;;) Line 2276  for (;;)
2276        break;        break;
2277    
2278        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
2279          case OP_STARI:
2280          case OP_MINSTARI:
2281          case OP_POSSTARI:
2282          case OP_NOTSTARI:
2283          case OP_NOTMINSTARI:
2284          case OP_NOTPOSSTARI:
2285          caseless = TRUE;
2286          codevalue -= OP_STARI - OP_STAR;
2287          /* Fall through */
2288        case OP_STAR:        case OP_STAR:
2289        case OP_MINSTAR:        case OP_MINSTAR:
2290        case OP_POSSTAR:        case OP_POSSTAR:
# Line 2225  for (;;) Line 2295  for (;;)
2295        if (clen > 0)        if (clen > 0)
2296          {          {
2297          unsigned int otherd = NOTACHAR;          unsigned int otherd = NOTACHAR;
2298          if ((ims & PCRE_CASELESS) != 0)          if (caseless)
2299            {            {
2300  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2301            if (utf8 && d >= 128)            if (utf8 && d >= 128)
# Line 2251  for (;;) Line 2321  for (;;)
2321        break;        break;
2322    
2323        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
2324          case OP_EXACTI:
2325          case OP_NOTEXACTI:
2326          caseless = TRUE;
2327          codevalue -= OP_STARI - OP_STAR;
2328          /* Fall through */
2329        case OP_EXACT:        case OP_EXACT:
2330        case OP_NOTEXACT:        case OP_NOTEXACT:
2331        count = current_state->count;  /* Number already matched */        count = current_state->count;  /* Number already matched */
2332        if (clen > 0)        if (clen > 0)
2333          {          {
2334          unsigned int otherd = NOTACHAR;          unsigned int otherd = NOTACHAR;
2335          if ((ims & PCRE_CASELESS) != 0)          if (caseless)
2336            {            {
2337  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2338            if (utf8 && d >= 128)            if (utf8 && d >= 128)
# Line 2281  for (;;) Line 2356  for (;;)
2356        break;        break;
2357    
2358        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
2359          case OP_UPTOI:
2360          case OP_MINUPTOI:
2361          case OP_POSUPTOI:
2362          case OP_NOTUPTOI:
2363          case OP_NOTMINUPTOI:
2364          case OP_NOTPOSUPTOI:
2365          caseless = TRUE;
2366          codevalue -= OP_STARI - OP_STAR;
2367          /* Fall through */
2368        case OP_UPTO:        case OP_UPTO:
2369        case OP_MINUPTO:        case OP_MINUPTO:
2370        case OP_POSUPTO:        case OP_POSUPTO:
# Line 2292  for (;;) Line 2376  for (;;)
2376        if (clen > 0)        if (clen > 0)
2377          {          {
2378          unsigned int otherd = NOTACHAR;          unsigned int otherd = NOTACHAR;
2379          if ((ims & PCRE_CASELESS) != 0)          if (caseless)
2380            {            {
2381  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2382            if (utf8 && d >= 128)            if (utf8 && d >= 128)
# Line 2359  for (;;) Line 2443  for (;;)
2443          points to the byte after the end of the class. If there is a          points to the byte after the end of the class. If there is a
2444          quantifier, this is where it will be. */          quantifier, this is where it will be. */
2445    
2446          next_state_offset = ecode - start_code;          next_state_offset = (int)(ecode - start_code);
2447    
2448          switch (*ecode)          switch (*ecode)
2449            {            {
# Line 2430  for (;;) Line 2514  for (;;)
2514            md,                                   /* static match data */            md,                                   /* static match data */
2515            code,                                 /* this subexpression's code */            code,                                 /* this subexpression's code */
2516            ptr,                                  /* where we currently are */            ptr,                                  /* where we currently are */
2517            ptr - start_subject,                  /* start offset */            (int)(ptr - start_subject),           /* start offset */
2518            local_offsets,                        /* offset vector */            local_offsets,                        /* offset vector */
2519            sizeof(local_offsets)/sizeof(int),    /* size of same */            sizeof(local_offsets)/sizeof(int),    /* size of same */
2520            local_workspace,                      /* workspace vector */            local_workspace,                      /* workspace vector */
2521            sizeof(local_workspace)/sizeof(int),  /* size of same */            sizeof(local_workspace)/sizeof(int),  /* size of same */
           ims,                                  /* the current ims flags */  
2522            rlevel,                               /* function recursion level */            rlevel,                               /* function recursion level */
2523            recursing);                           /* pass on regex recursion */            recursing);                           /* pass on regex recursion */
2524    
2525          if (rc == PCRE_ERROR_DFA_UITEM) return rc;          if (rc == PCRE_ERROR_DFA_UITEM) return rc;
2526          if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK))          if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK))
2527              { ADD_ACTIVE(endasscode + LINK_SIZE + 1 - start_code, 0); }              { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); }
2528          }          }
2529        break;        break;
2530    
# Line 2468  for (;;) Line 2551  for (;;)
2551              cb.callout_number   = code[LINK_SIZE+2];              cb.callout_number   = code[LINK_SIZE+2];
2552              cb.offset_vector    = offsets;              cb.offset_vector    = offsets;
2553              cb.subject          = (PCRE_SPTR)start_subject;              cb.subject          = (PCRE_SPTR)start_subject;
2554              cb.subject_length   = end_subject - start_subject;              cb.subject_length   = (int)(end_subject - start_subject);
2555              cb.start_match      = current_subject - start_subject;              cb.start_match      = (int)(current_subject - start_subject);
2556              cb.current_position = ptr - start_subject;              cb.current_position = (int)(ptr - start_subject);
2557              cb.pattern_position = GET(code, LINK_SIZE + 3);              cb.pattern_position = GET(code, LINK_SIZE + 3);
2558              cb.next_item_length = GET(code, 3 + 2*LINK_SIZE);              cb.next_item_length = GET(code, 3 + 2*LINK_SIZE);
2559              cb.capture_top      = 1;              cb.capture_top      = 1;
# Line 2521  for (;;) Line 2604  for (;;)
2604              md,                                   /* fixed match data */              md,                                   /* fixed match data */
2605              asscode,                              /* this subexpression's code */              asscode,                              /* this subexpression's code */
2606              ptr,                                  /* where we currently are */              ptr,                                  /* where we currently are */
2607              ptr - start_subject,                  /* start offset */              (int)(ptr - start_subject),           /* start offset */
2608              local_offsets,                        /* offset vector */              local_offsets,                        /* offset vector */
2609              sizeof(local_offsets)/sizeof(int),    /* size of same */              sizeof(local_offsets)/sizeof(int),    /* size of same */
2610              local_workspace,                      /* workspace vector */              local_workspace,                      /* workspace vector */
2611              sizeof(local_workspace)/sizeof(int),  /* size of same */              sizeof(local_workspace)/sizeof(int),  /* size of same */
             ims,                                  /* the current ims flags */  
2612              rlevel,                               /* function recursion level */              rlevel,                               /* function recursion level */
2613              recursing);                           /* pass on regex recursion */              recursing);                           /* pass on regex recursion */
2614    
2615            if (rc == PCRE_ERROR_DFA_UITEM) return rc;            if (rc == PCRE_ERROR_DFA_UITEM) return rc;
2616            if ((rc >= 0) ==            if ((rc >= 0) ==
2617                  (condcode == OP_ASSERT || condcode == OP_ASSERTBACK))                  (condcode == OP_ASSERT || condcode == OP_ASSERTBACK))
2618              { ADD_ACTIVE(endasscode + LINK_SIZE + 1 - start_code, 0); }              { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); }
2619            else            else
2620              { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }              { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
2621            }            }
# Line 2554  for (;;) Line 2636  for (;;)
2636            md,                                   /* fixed match data */            md,                                   /* fixed match data */
2637            start_code + GET(code, 1),            /* this subexpression's code */            start_code + GET(code, 1),            /* this subexpression's code */
2638            ptr,                                  /* where we currently are */            ptr,                                  /* where we currently are */
2639            ptr - start_subject,                  /* start offset */            (int)(ptr - start_subject),           /* start offset */
2640            local_offsets,                        /* offset vector */            local_offsets,                        /* offset vector */
2641            sizeof(local_offsets)/sizeof(int),    /* size of same */            sizeof(local_offsets)/sizeof(int),    /* size of same */
2642            local_workspace,                      /* workspace vector */            local_workspace,                      /* workspace vector */
2643            sizeof(local_workspace)/sizeof(int),  /* size of same */            sizeof(local_workspace)/sizeof(int),  /* size of same */
           ims,                                  /* the current ims flags */  
2644            rlevel,                               /* function recursion level */            rlevel,                               /* function recursion level */
2645            recursing + 1);                       /* regex recurse level */            recursing + 1);                       /* regex recurse level */
2646    
# Line 2597  for (;;) Line 2678  for (;;)
2678        break;        break;
2679    
2680        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
2681          case OP_BRAPOS:
2682          case OP_SBRAPOS:
2683          case OP_CBRAPOS:
2684          case OP_SCBRAPOS:
2685          case OP_BRAPOSZERO:
2686            {
2687            int charcount, matched_count;
2688            const uschar *local_ptr = ptr;
2689            BOOL allow_zero;
2690    
2691            if (codevalue == OP_BRAPOSZERO)
2692              {
2693              allow_zero = TRUE;
2694              codevalue = *(++code);  /* Codevalue will be one of above BRAs */
2695              }
2696            else allow_zero = FALSE;
2697    
2698            /* Loop to match the subpattern as many times as possible as if it were
2699            a complete pattern. */
2700    
2701            for (matched_count = 0;; matched_count++)
2702              {
2703              int local_offsets[2];
2704              int local_workspace[1000];
2705    
2706              int rc = internal_dfa_exec(
2707                md,                                   /* fixed match data */
2708                code,                                 /* this subexpression's code */
2709                local_ptr,                            /* where we currently are */
2710                (int)(ptr - start_subject),           /* start offset */
2711                local_offsets,                        /* offset vector */
2712                sizeof(local_offsets)/sizeof(int),    /* size of same */
2713                local_workspace,                      /* workspace vector */
2714                sizeof(local_workspace)/sizeof(int),  /* size of same */
2715                rlevel,                               /* function recursion level */
2716                recursing);                           /* pass on regex recursion */
2717    
2718              /* Failed to match */
2719    
2720              if (rc < 0)
2721                {
2722                if (rc != PCRE_ERROR_NOMATCH) return rc;
2723                break;
2724                }
2725    
2726              /* Matched: break the loop if zero characters matched. */
2727    
2728              charcount = local_offsets[1] - local_offsets[0];
2729              if (charcount == 0) break;
2730              local_ptr += charcount;    /* Advance temporary position ptr */
2731              }
2732    
2733            /* At this point we have matched the subpattern matched_count
2734            times, and local_ptr is pointing to the character after the end of the
2735            last match. */
2736    
2737            if (matched_count > 0 || allow_zero)
2738              {
2739              const uschar *end_subpattern = code;
2740              int next_state_offset;
2741    
2742              do { end_subpattern += GET(end_subpattern, 1); }
2743                while (*end_subpattern == OP_ALT);
2744              next_state_offset =
2745                (int)(end_subpattern - start_code + LINK_SIZE + 1);
2746    
2747              /* Optimization: if there are no more active states, and there
2748              are no new states yet set up, then skip over the subject string
2749              right here, to save looping. Otherwise, set up the new state to swing
2750              into action when the end of the matched substring is reached. */
2751    
2752              if (i + 1 >= active_count && new_count == 0)
2753                {
2754                ptr = local_ptr;
2755                clen = 0;
2756                ADD_NEW(next_state_offset, 0);
2757                }
2758              else
2759                {
2760                const uschar *p = ptr;
2761                const uschar *pp = local_ptr;
2762                charcount = pp - p;
2763                while (p < pp) if ((*p++ & 0xc0) == 0x80) charcount--;
2764                ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1));
2765                }
2766              }
2767            }
2768          break;
2769    
2770          /*-----------------------------------------------------------------*/
2771        case OP_ONCE:        case OP_ONCE:
2772          {          {
2773          int local_offsets[2];          int local_offsets[2];
# Line 2606  for (;;) Line 2777  for (;;)
2777            md,                                   /* fixed match data */            md,                                   /* fixed match data */
2778            code,                                 /* this subexpression's code */            code,                                 /* this subexpression's code */
2779            ptr,                                  /* where we currently are */            ptr,                                  /* where we currently are */
2780            ptr - start_subject,                  /* start offset */            (int)(ptr - start_subject),           /* start offset */
2781            local_offsets,                        /* offset vector */            local_offsets,                        /* offset vector */
2782            sizeof(local_offsets)/sizeof(int),    /* size of same */            sizeof(local_offsets)/sizeof(int),    /* size of same */
2783            local_workspace,                      /* workspace vector */            local_workspace,                      /* workspace vector */
2784            sizeof(local_workspace)/sizeof(int),  /* size of same */            sizeof(local_workspace)/sizeof(int),  /* size of same */
           ims,                                  /* the current ims flags */  
2785            rlevel,                               /* function recursion level */            rlevel,                               /* function recursion level */
2786            recursing);                           /* pass on regex recursion */            recursing);                           /* pass on regex recursion */
2787    
# Line 2623  for (;;) Line 2793  for (;;)
2793    
2794            do { end_subpattern += GET(end_subpattern, 1); }            do { end_subpattern += GET(end_subpattern, 1); }
2795              while (*end_subpattern == OP_ALT);              while (*end_subpattern == OP_ALT);
2796            next_state_offset = end_subpattern - start_code + LINK_SIZE + 1;            next_state_offset =
2797                (int)(end_subpattern - start_code + LINK_SIZE + 1);
2798    
2799            /* If the end of this subpattern is KETRMAX or KETRMIN, we must            /* If the end of this subpattern is KETRMAX or KETRMIN, we must
2800            arrange for the repeat state also to be added to the relevant list.            arrange for the repeat state also to be added to the relevant list.
# Line 2631  for (;;) Line 2802  for (;;)
2802    
2803            repeat_state_offset = (*end_subpattern == OP_KETRMAX ||            repeat_state_offset = (*end_subpattern == OP_KETRMAX ||
2804                                   *end_subpattern == OP_KETRMIN)?                                   *end_subpattern == OP_KETRMIN)?
2805              end_subpattern - start_code - GET(end_subpattern, 1) : -1;              (int)(end_subpattern - start_code - GET(end_subpattern, 1)) : -1;
2806    
2807            /* If we have matched an empty string, add the next state at the            /* If we have matched an empty string, add the next state at the
2808            current character pointer. This is important so that the duplicate            current character pointer. This is important so that the duplicate
# Line 2646  for (;;) Line 2817  for (;;)
2817            /* Optimization: if there are no more active states, and there            /* Optimization: if there are no more active states, and there
2818            are no new states yet set up, then skip over the subject string            are no new states yet set up, then skip over the subject string
2819            right here, to save looping. Otherwise, set up the new state to swing            right here, to save looping. Otherwise, set up the new state to swing
2820            into action when the end of the substring is reached. */            into action when the end of the matched substring is reached. */
2821    
2822            else if (i + 1 >= active_count && new_count == 0)            else if (i + 1 >= active_count && new_count == 0)
2823              {              {
# Line 2676  for (;;) Line 2847  for (;;)
2847              if (repeat_state_offset >= 0)              if (repeat_state_offset >= 0)
2848                { ADD_NEW_DATA(-repeat_state_offset, 0, (charcount - 1)); }                { ADD_NEW_DATA(-repeat_state_offset, 0, (charcount - 1)); }
2849              }              }
   
2850            }            }
2851          else if (rc != PCRE_ERROR_NOMATCH) return rc;          else if (rc != PCRE_ERROR_NOMATCH) return rc;
2852          }          }
# Line 2695  for (;;) Line 2865  for (;;)
2865          cb.callout_number   = code[1];          cb.callout_number   = code[1];
2866          cb.offset_vector    = offsets;          cb.offset_vector    = offsets;
2867          cb.subject          = (PCRE_SPTR)start_subject;          cb.subject          = (PCRE_SPTR)start_subject;
2868          cb.subject_length   = end_subject - start_subject;          cb.subject_length   = (int)(end_subject - start_subject);
2869          cb.start_match      = current_subject - start_subject;          cb.start_match      = (int)(current_subject - start_subject);
2870          cb.current_position = ptr - start_subject;          cb.current_position = (int)(ptr - start_subject);
2871          cb.pattern_position = GET(code, 2);          cb.pattern_position = GET(code, 2);
2872          cb.next_item_length = GET(code, 2 + LINK_SIZE);          cb.next_item_length = GET(code, 2 + LINK_SIZE);
2873          cb.capture_top      = 1;          cb.capture_top      = 1;
# Line 2743  for (;;) Line 2913  for (;;)
2913          ((md->moptions & PCRE_PARTIAL_SOFT) != 0 &&  /* Soft partial and */          ((md->moptions & PCRE_PARTIAL_SOFT) != 0 &&  /* Soft partial and */
2914           match_count < 0)                            /* no matches */           match_count < 0)                            /* no matches */
2915          ) &&                                         /* And... */          ) &&                                         /* And... */
2916          ptr >= end_subject &&                     /* Reached end of subject */          ptr >= end_subject &&                  /* Reached end of subject */
2917          ptr > current_subject)                    /* Matched non-empty string */          ptr > md->start_used_ptr)              /* Inspected non-empty string */
2918        {        {
2919        if (offsetcount >= 2)        if (offsetcount >= 2)
2920          {          {
2921          offsets[0] = md->start_used_ptr - start_subject;          offsets[0] = (int)(md->start_used_ptr - start_subject);
2922          offsets[1] = end_subject - start_subject;          offsets[1] = (int)(end_subject - start_subject);
2923          }          }
2924        match_count = PCRE_ERROR_PARTIAL;        match_count = PCRE_ERROR_PARTIAL;
2925        }        }
# Line 2834  if (re == NULL || subject == NULL || wor Line 3004  if (re == NULL || subject == NULL || wor
3004     (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;     (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
3005  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
3006  if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE;  if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE;
3007    if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
3008    
3009  /* We need to find the pointer to any study data before we test for byte  /* We need to find the pointer to any study data before we test for byte
3010  flipping, so we scan the extra_data block first. This may set two fields in the  flipping, so we scan the extra_data block first. This may set two fields in the
# Line 2952  back the character offset. */ Line 3123  back the character offset. */
3123  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
3124  if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)  if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)
3125    {    {
3126    if (_pcre_valid_utf8((uschar *)subject, length) >= 0)    int errorcode;
3127      return PCRE_ERROR_BADUTF8;    int tb = _pcre_valid_utf8((uschar *)subject, length, &errorcode);
3128    if (start_offset > 0 && start_offset < length)    if (tb >= 0)
3129      {      {
3130      int tb = ((uschar *)subject)[start_offset];      if (offsetcount >= 2)
     if (tb > 127)  
3131        {        {
3132        tb &= 0xc0;        offsets[0] = tb;
3133        if (tb != 0 && tb != 0xc0) return PCRE_ERROR_BADUTF8_OFFSET;        offsets[1] = errorcode;
3134        }        }
3135        return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0)?
3136          PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
3137        }
3138      if (start_offset > 0 && start_offset < length)
3139        {
3140        tb = ((USPTR)subject)[start_offset] & 0xc0;
3141        if (tb == 0x80) return PCRE_ERROR_BADUTF8_OFFSET;
3142      }      }
3143    }    }
3144  #endif  #endif
# Line 3048  for (;;) Line 3225  for (;;)
3225    
3226      /* There are some optimizations that avoid running the match if a known      /* There are some optimizations that avoid running the match if a known
3227      starting point is not found. However, there is an option that disables      starting point is not found. However, there is an option that disables
3228      these, for testing and for ensuring that all callouts do actually occur. */      these, for testing and for ensuring that all callouts do actually occur.
3229        The option can be set in the regex by (*NO_START_OPT) or passed in
3230        match-time options. */
3231    
3232      if ((options & PCRE_NO_START_OPTIMIZE) == 0)      if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)
3233        {        {
3234        /* Advance to a known first byte. */        /* Advance to a known first byte. */
3235    
# Line 3108  for (;;) Line 3287  for (;;)
3287          while (current_subject < end_subject)          while (current_subject < end_subject)
3288            {            {
3289            register unsigned int c = *current_subject;            register unsigned int c = *current_subject;
3290            if ((start_bits[c/8] & (1 << (c&7))) == 0) current_subject++;            if ((start_bits[c/8] & (1 << (c&7))) == 0)
3291              else break;              {
3292                current_subject++;
3293    #ifdef SUPPORT_UTF8
3294                if (utf8)
3295                  while(current_subject < end_subject &&
3296                        (*current_subject & 0xc0) == 0x80) current_subject++;
3297    #endif
3298                }
3299              else break;
3300            }            }
3301          }          }
3302        }        }
# Line 3200  for (;;) Line 3387  for (;;)
3387      offsetcount,                       /* size of same */      offsetcount,                       /* size of same */
3388      workspace,                         /* workspace vector */      workspace,                         /* workspace vector */
3389      wscount,                           /* size of same */      wscount,                           /* size of same */
     re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL), /* ims flags */  
3390      0,                                 /* function recurse level */      0,                                 /* function recurse level */
3391      0);                                /* regex recurse level */      0);                                /* regex recurse level */
3392    

Legend:
Removed from v.518  
changed lines
  Added in v.604

  ViewVC Help
Powered by ViewVC 1.1.5