/[pcre]/code/branches/pcre16/pcre_exec.c
ViewVC logotype

Diff of /code/branches/pcre16/pcre_exec.c

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

code/trunk/pcre_exec.c revision 723 by ph10, Sat Oct 8 15:55:23 2011 UTC code/branches/pcre16/pcre_exec.c revision 806 by zherczeg, Thu Dec 15 11:57:39 2011 UTC
# Line 82  negative to avoid the external error cod Line 82  negative to avoid the external error cod
82  #define MATCH_SKIP_ARG     (-993)  #define MATCH_SKIP_ARG     (-993)
83  #define MATCH_THEN         (-992)  #define MATCH_THEN         (-992)
84    
 /* This is a convenience macro for code that occurs many times. */  
   
 #define MRRETURN(ra) \  
   { \  
   md->mark = markptr; \  
   RRETURN(ra); \  
   }  
   
85  /* Maximum number of ints of offset to save on the stack for recursive calls.  /* Maximum number of ints of offset to save on the stack for recursive calls.
86  If the offset vector is bigger, malloc is used. This should be a multiple of 3,  If the offset vector is bigger, malloc is used. This should be a multiple of 3,
87  because the offset vector is always a multiple of 3 long. */  because the offset vector is always a multiple of 3 long. */
# Line 121  Returns:     nothing Line 113  Returns:     nothing
113  */  */
114    
115  static void  static void
116  pchars(const uschar *p, int length, BOOL is_subject, match_data *md)  pchars(const pcre_uchar *p, int length, BOOL is_subject, match_data *md)
117  {  {
118  unsigned int c;  unsigned int c;
119  if (is_subject && length > md->end_subject - p) length = md->end_subject - p;  if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
# Line 152  Returns:      < 0 if not matched, otherw Line 144  Returns:      < 0 if not matched, otherw
144  */  */
145    
146  static int  static int
147  match_ref(int offset, register USPTR eptr, int length, match_data *md,  match_ref(int offset, register PCRE_PUCHAR eptr, int length, match_data *md,
148    BOOL caseless)    BOOL caseless)
149  {  {
150  USPTR eptr_start = eptr;  PCRE_PUCHAR eptr_start = eptr;
151  register USPTR p = md->start_subject + md->offset_vector[offset];  register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset];
152    
153  #ifdef PCRE_DEBUG  #ifdef PCRE_DEBUG
154  if (eptr >= md->end_subject)  if (eptr >= md->end_subject)
# Line 181  ASCII characters. */ Line 173  ASCII characters. */
173    
174  if (caseless)  if (caseless)
175    {    {
176  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
177  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
178    if (md->utf8)    if (md->utf)
179      {      {
180      /* Match characters up to the end of the reference. NOTE: the number of      /* Match characters up to the end of the reference. NOTE: the number of
181      bytes matched may differ, because there are some characters whose upper and      bytes matched may differ, because there are some characters whose upper and
# Line 193  if (caseless) Line 185  if (caseless)
185      the latter. It is important, therefore, to check the length along the      the latter. It is important, therefore, to check the length along the
186      reference, not along the subject (earlier code did this wrong). */      reference, not along the subject (earlier code did this wrong). */
187    
188      USPTR endptr = p + length;      PCRE_PUCHAR endptr = p + length;
189      while (p < endptr)      while (p < endptr)
190        {        {
191        int c, d;        int c, d;
# Line 212  if (caseless) Line 204  if (caseless)
204      {      {
205      if (eptr + length > md->end_subject) return -1;      if (eptr + length > md->end_subject) return -1;
206      while (length-- > 0)      while (length-- > 0)
207        { if (md->lcc[*p++] != md->lcc[*eptr++]) return -1; }        {
208          if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1;
209          p++;
210          eptr++;
211          }
212      }      }
213    }    }
214    
# Line 225  else Line 221  else
221    while (length-- > 0) if (*p++ != *eptr++) return -1;    while (length-- > 0) if (*p++ != *eptr++) return -1;
222    }    }
223    
224  return eptr - eptr_start;  return (int)(eptr - eptr_start);
225  }  }
226    
227    
# Line 290  actually used in this definition. */ Line 286  actually used in this definition. */
286  #define RMATCH(ra,rb,rc,rd,re,rw) \  #define RMATCH(ra,rb,rc,rd,re,rw) \
287    { \    { \
288    printf("match() called in line %d\n", __LINE__); \    printf("match() called in line %d\n", __LINE__); \
289    rrc = match(ra,rb,mstart,markptr,rc,rd,re,rdepth+1); \    rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1); \
290    printf("to line %d\n", __LINE__); \    printf("to line %d\n", __LINE__); \
291    }    }
292  #define RRETURN(ra) \  #define RRETURN(ra) \
# Line 300  actually used in this definition. */ Line 296  actually used in this definition. */
296    }    }
297  #else  #else
298  #define RMATCH(ra,rb,rc,rd,re,rw) \  #define RMATCH(ra,rb,rc,rd,re,rw) \
299    rrc = match(ra,rb,mstart,markptr,rc,rd,re,rdepth+1)    rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1)
300  #define RRETURN(ra) return ra  #define RRETURN(ra) return ra
301  #endif  #endif
302    
# Line 315  argument of match(), which never changes Line 311  argument of match(), which never changes
311    
312  #define RMATCH(ra,rb,rc,rd,re,rw)\  #define RMATCH(ra,rb,rc,rd,re,rw)\
313    {\    {\
314    heapframe *newframe = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));\    heapframe *newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\
315    if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\    if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
316    frame->Xwhere = rw; \    frame->Xwhere = rw; \
317    newframe->Xeptr = ra;\    newframe->Xeptr = ra;\
318    newframe->Xecode = rb;\    newframe->Xecode = rb;\
319    newframe->Xmstart = mstart;\    newframe->Xmstart = mstart;\
   newframe->Xmarkptr = markptr;\  
320    newframe->Xoffset_top = rc;\    newframe->Xoffset_top = rc;\
321    newframe->Xeptrb = re;\    newframe->Xeptrb = re;\
322    newframe->Xrdepth = frame->Xrdepth + 1;\    newframe->Xrdepth = frame->Xrdepth + 1;\
# Line 337  argument of match(), which never changes Line 332  argument of match(), which never changes
332    {\    {\
333    heapframe *oldframe = frame;\    heapframe *oldframe = frame;\
334    frame = oldframe->Xprevframe;\    frame = oldframe->Xprevframe;\
335    (pcre_stack_free)(oldframe);\    (PUBL(stack_free))(oldframe);\
336    if (frame != NULL)\    if (frame != NULL)\
337      {\      {\
338      rrc = ra;\      rrc = ra;\
# Line 354  typedef struct heapframe { Line 349  typedef struct heapframe {
349    
350    /* Function arguments that may change */    /* Function arguments that may change */
351    
352    USPTR Xeptr;    PCRE_PUCHAR Xeptr;
353    const uschar *Xecode;    const pcre_uchar *Xecode;
354    USPTR Xmstart;    PCRE_PUCHAR Xmstart;
   USPTR Xmarkptr;  
355    int Xoffset_top;    int Xoffset_top;
356    eptrblock *Xeptrb;    eptrblock *Xeptrb;
357    unsigned int Xrdepth;    unsigned int Xrdepth;
358    
359    /* Function local variables */    /* Function local variables */
360    
361    USPTR Xcallpat;    PCRE_PUCHAR Xcallpat;
362  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
363    USPTR Xcharptr;    PCRE_PUCHAR Xcharptr;
364  #endif  #endif
365    USPTR Xdata;    PCRE_PUCHAR Xdata;
366    USPTR Xnext;    PCRE_PUCHAR Xnext;
367    USPTR Xpp;    PCRE_PUCHAR Xpp;
368    USPTR Xprev;    PCRE_PUCHAR Xprev;
369    USPTR Xsaved_eptr;    PCRE_PUCHAR Xsaved_eptr;
370    
371    recursion_info Xnew_recursive;    recursion_info Xnew_recursive;
372    
# Line 385  typedef struct heapframe { Line 379  typedef struct heapframe {
379    int Xprop_value;    int Xprop_value;
380    int Xprop_fail_result;    int Xprop_fail_result;
381    int Xoclength;    int Xoclength;
382    uschar Xocchars[8];    pcre_uchar Xocchars[6];
383  #endif  #endif
384    
385    int Xcodelink;    int Xcodelink;
# Line 427  returns a negative (error) response, the Line 421  returns a negative (error) response, the
421  same response. */  same response. */
422    
423  /* These macros pack up tests that are used for partial matching, and which  /* These macros pack up tests that are used for partial matching, and which
424  appears several times in the code. We set the "hit end" flag if the pointer is  appear several times in the code. We set the "hit end" flag if the pointer is
425  at the end of the subject and also past the start of the subject (i.e.  at the end of the subject and also past the start of the subject (i.e.
426  something has been matched). For hard partial matching, we then return  something has been matched). For hard partial matching, we then return
427  immediately. The second one is used when we already know we are past the end of  immediately. The second one is used when we already know we are past the end of
# Line 438  the subject. */ Line 432  the subject. */
432        eptr > md->start_used_ptr) \        eptr > md->start_used_ptr) \
433      { \      { \
434      md->hitend = TRUE; \      md->hitend = TRUE; \
435      if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL); \      if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \
436      }      }
437    
438  #define SCHECK_PARTIAL()\  #define SCHECK_PARTIAL()\
439    if (md->partial != 0 && eptr > md->start_used_ptr) \    if (md->partial != 0 && eptr > md->start_used_ptr) \
440      { \      { \
441      md->hitend = TRUE; \      md->hitend = TRUE; \
442      if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL); \      if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \
443      }      }
444    
445    
446  /* Performance note: It might be tempting to extract commonly used fields from  /* Performance note: It might be tempting to extract commonly used fields from
447  the md structure (e.g. utf8, end_subject) into individual variables to improve  the md structure (e.g. utf, end_subject) into individual variables to improve
448  performance. Tests using gcc on a SPARC disproved this; in the first case, it  performance. Tests using gcc on a SPARC disproved this; in the first case, it
449  made performance worse.  made performance worse.
450    
# Line 459  Arguments: Line 453  Arguments:
453     ecode       pointer to current position in compiled code     ecode       pointer to current position in compiled code
454     mstart      pointer to the current match start position (can be modified     mstart      pointer to the current match start position (can be modified
455                   by encountering \K)                   by encountering \K)
    markptr     pointer to the most recent MARK name, or NULL  
456     offset_top  current top pointer     offset_top  current top pointer
457     md          pointer to "static" info for the match     md          pointer to "static" info for the match
458     eptrb       pointer to chain of blocks containing eptr at start of     eptrb       pointer to chain of blocks containing eptr at start of
# Line 474  Returns:       MATCH_MATCH if matched Line 467  Returns:       MATCH_MATCH if matched
467  */  */
468    
469  static int  static int
470  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,  match(REGISTER PCRE_PUCHAR eptr, REGISTER const pcre_uchar *ecode,
471    const uschar *markptr, int offset_top, match_data *md, eptrblock *eptrb,    PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb,
472    unsigned int rdepth)    unsigned int rdepth)
473  {  {
474  /* These variables do not need to be preserved over recursion in this function,  /* These variables do not need to be preserved over recursion in this function,
# Line 485  so they can be ordinary variables in all Line 478  so they can be ordinary variables in all
478  register int  rrc;         /* Returns from recursive calls */  register int  rrc;         /* Returns from recursive calls */
479  register int  i;           /* Used for loops not involving calls to RMATCH() */  register int  i;           /* Used for loops not involving calls to RMATCH() */
480  register unsigned int c;   /* Character values not kept over RMATCH() calls */  register unsigned int c;   /* Character values not kept over RMATCH() calls */
481  register BOOL utf8;        /* Local copy of UTF-8 flag for speed */  register BOOL utf;         /* Local copy of UTF flag for speed */
482    
483  BOOL minimize, possessive; /* Quantifier options */  BOOL minimize, possessive; /* Quantifier options */
484  BOOL caseless;  BOOL caseless;
# Line 497  heap storage. Set up the top-level frame Line 490  heap storage. Set up the top-level frame
490  heap whenever RMATCH() does a "recursion". See the macro definitions above. */  heap whenever RMATCH() does a "recursion". See the macro definitions above. */
491    
492  #ifdef NO_RECURSE  #ifdef NO_RECURSE
493  heapframe *frame = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));  heapframe *frame = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));
494  if (frame == NULL) RRETURN(PCRE_ERROR_NOMEMORY);  if (frame == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
495  frame->Xprevframe = NULL;            /* Marks the top level */  frame->Xprevframe = NULL;            /* Marks the top level */
496    
# Line 506  frame->Xprevframe = NULL;            /* Line 499  frame->Xprevframe = NULL;            /*
499  frame->Xeptr = eptr;  frame->Xeptr = eptr;
500  frame->Xecode = ecode;  frame->Xecode = ecode;
501  frame->Xmstart = mstart;  frame->Xmstart = mstart;
 frame->Xmarkptr = markptr;  
502  frame->Xoffset_top = offset_top;  frame->Xoffset_top = offset_top;
503  frame->Xeptrb = eptrb;  frame->Xeptrb = eptrb;
504  frame->Xrdepth = rdepth;  frame->Xrdepth = rdepth;
# Line 520  HEAP_RECURSE: Line 512  HEAP_RECURSE:
512  #define eptr               frame->Xeptr  #define eptr               frame->Xeptr
513  #define ecode              frame->Xecode  #define ecode              frame->Xecode
514  #define mstart             frame->Xmstart  #define mstart             frame->Xmstart
 #define markptr            frame->Xmarkptr  
515  #define offset_top         frame->Xoffset_top  #define offset_top         frame->Xoffset_top
516  #define eptrb              frame->Xeptrb  #define eptrb              frame->Xeptrb
517  #define rdepth             frame->Xrdepth  #define rdepth             frame->Xrdepth
518    
519  /* Ditto for the local variables */  /* Ditto for the local variables */
520    
521  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
522  #define charptr            frame->Xcharptr  #define charptr            frame->Xcharptr
523  #endif  #endif
524  #define callpat            frame->Xcallpat  #define callpat            frame->Xcallpat
# Line 585  declarations can be cut out in a block. Line 576  declarations can be cut out in a block.
576  below are for variables that do not have to be preserved over a recursive call  below are for variables that do not have to be preserved over a recursive call
577  to RMATCH(). */  to RMATCH(). */
578    
579  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
580  const uschar *charptr;  const pcre_uchar *charptr;
581  #endif  #endif
582  const uschar *callpat;  const pcre_uchar *callpat;
583  const uschar *data;  const pcre_uchar *data;
584  const uschar *next;  const pcre_uchar *next;
585  USPTR         pp;  PCRE_PUCHAR       pp;
586  const uschar *prev;  const pcre_uchar *prev;
587  USPTR         saved_eptr;  PCRE_PUCHAR       saved_eptr;
588    
589  recursion_info new_recursive;  recursion_info new_recursive;
590    
# Line 606  int prop_type; Line 597  int prop_type;
597  int prop_value;  int prop_value;
598  int prop_fail_result;  int prop_fail_result;
599  int oclength;  int oclength;
600  uschar occhars[8];  pcre_uchar occhars[6];
601  #endif  #endif
602    
603  int codelink;  int codelink;
# Line 634  the alternative names that are used. */ Line 625  the alternative names that are used. */
625  #define code_offset   codelink  #define code_offset   codelink
626  #define condassert    condition  #define condassert    condition
627  #define matched_once  prev_is_word  #define matched_once  prev_is_word
628    #define foc           number
629    
630  /* These statements are here to stop the compiler complaining about unitialized  /* These statements are here to stop the compiler complaining about unitialized
631  variables. */  variables. */
# Line 659  defined). However, RMATCH isn't like a f Line 651  defined). However, RMATCH isn't like a f
651  complicated macro. It has to be used in one particular way. This shouldn't,  complicated macro. It has to be used in one particular way. This shouldn't,
652  however, impact performance when true recursion is being used. */  however, impact performance when true recursion is being used. */
653    
654  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
655  utf8 = md->utf8;       /* Local copy of the flag */  utf = md->utf;       /* Local copy of the flag */
656  #else  #else
657  utf8 = FALSE;  utf = FALSE;
658  #endif  #endif
659    
660  /* First check that we haven't called match() too many times, or that we  /* First check that we haven't called match() too many times, or that we
# Line 701  for (;;) Line 693  for (;;)
693    switch(op)    switch(op)
694      {      {
695      case OP_MARK:      case OP_MARK:
696      markptr = ecode + 2;      md->nomatch_mark = ecode + 2;
697      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      md->mark = NULL;    /* In case previously set by assertion */
698        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
699        eptrb, RM55);        eptrb, RM55);
700        if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
701             md->mark == NULL) md->mark = ecode + 2;
702    
703      /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an      /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
704      argument, and we must check whether that argument matches this MARK's      argument, and we must check whether that argument matches this MARK's
# Line 712  for (;;) Line 707  for (;;)
707      position and return MATCH_SKIP. Otherwise, pass back the return code      position and return MATCH_SKIP. Otherwise, pass back the return code
708      unaltered. */      unaltered. */
709    
710      if (rrc == MATCH_SKIP_ARG &&      else if (rrc == MATCH_SKIP_ARG &&
711          strcmp((char *)markptr, (char *)(md->start_match_ptr)) == 0)          STRCMP_UC_UC(ecode + 2, md->start_match_ptr) == 0)
712        {        {
713        md->start_match_ptr = eptr;        md->start_match_ptr = eptr;
714        RRETURN(MATCH_SKIP);        RRETURN(MATCH_SKIP);
715        }        }
   
     if (md->mark == NULL) md->mark = markptr;  
716      RRETURN(rrc);      RRETURN(rrc);
717    
718      case OP_FAIL:      case OP_FAIL:
719      MRRETURN(MATCH_NOMATCH);      RRETURN(MATCH_NOMATCH);
720    
721      /* COMMIT overrides PRUNE, SKIP, and THEN */      /* COMMIT overrides PRUNE, SKIP, and THEN */
722    
723      case OP_COMMIT:      case OP_COMMIT:
724      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
725        eptrb, RM52);        eptrb, RM52);
726      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&
727          rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&          rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&
728          rrc != MATCH_THEN)          rrc != MATCH_THEN)
729        RRETURN(rrc);        RRETURN(rrc);
730      MRRETURN(MATCH_COMMIT);      RRETURN(MATCH_COMMIT);
731    
732      /* PRUNE overrides THEN */      /* PRUNE overrides THEN */
733    
734      case OP_PRUNE:      case OP_PRUNE:
735      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
736        eptrb, RM51);        eptrb, RM51);
737      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
738      MRRETURN(MATCH_PRUNE);      RRETURN(MATCH_PRUNE);
739    
740      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
741      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      md->nomatch_mark = ecode + 2;
742        md->mark = NULL;    /* In case previously set by assertion */
743        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
744        eptrb, RM56);        eptrb, RM56);
745        if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
746             md->mark == NULL) md->mark = ecode + 2;
747      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
     md->mark = ecode + 2;  
748      RRETURN(MATCH_PRUNE);      RRETURN(MATCH_PRUNE);
749    
750      /* SKIP overrides PRUNE and THEN */      /* SKIP overrides PRUNE and THEN */
751    
752      case OP_SKIP:      case OP_SKIP:
753      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
754        eptrb, RM53);        eptrb, RM53);
755      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
756        RRETURN(rrc);        RRETURN(rrc);
757      md->start_match_ptr = eptr;   /* Pass back current position */      md->start_match_ptr = eptr;   /* Pass back current position */
758      MRRETURN(MATCH_SKIP);      RRETURN(MATCH_SKIP);
759    
760        /* Note that, for Perl compatibility, SKIP with an argument does NOT set
761        nomatch_mark. There is a flag that disables this opcode when re-matching a
762        pattern that ended with a SKIP for which there was not a matching MARK. */
763    
764      case OP_SKIP_ARG:      case OP_SKIP_ARG:
765      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      if (md->ignore_skip_arg)
766          {
767          ecode += PRIV(OP_lengths)[*ecode] + ecode[1];
768          break;
769          }
770        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
771        eptrb, RM57);        eptrb, RM57);
772      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
773        RRETURN(rrc);        RRETURN(rrc);
774    
775      /* Pass back the current skip name by overloading md->start_match_ptr and      /* Pass back the current skip name by overloading md->start_match_ptr and
776      returning the special MATCH_SKIP_ARG return code. This will either be      returning the special MATCH_SKIP_ARG return code. This will either be
777      caught by a matching MARK, or get to the top, where it is treated the same      caught by a matching MARK, or get to the top, where it causes a rematch
778      as PRUNE. */      with the md->ignore_skip_arg flag set. */
779    
780      md->start_match_ptr = ecode + 2;      md->start_match_ptr = ecode + 2;
781      RRETURN(MATCH_SKIP_ARG);      RRETURN(MATCH_SKIP_ARG);
# Line 780  for (;;) Line 785  for (;;)
785      match pointer to do this. */      match pointer to do this. */
786    
787      case OP_THEN:      case OP_THEN:
788      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
789        eptrb, RM54);        eptrb, RM54);
790      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
791      md->start_match_ptr = ecode;      md->start_match_ptr = ecode;
792      MRRETURN(MATCH_THEN);      RRETURN(MATCH_THEN);
793    
794      case OP_THEN_ARG:      case OP_THEN_ARG:
795      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top,      md->nomatch_mark = ecode + 2;
796        md->mark = NULL;    /* In case previously set by assertion */
797        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top,
798        md, eptrb, RM58);        md, eptrb, RM58);
799        if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
800             md->mark == NULL) md->mark = ecode + 2;
801      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
802      md->start_match_ptr = ecode;      md->start_match_ptr = ecode;
     md->mark = ecode + 2;  
803      RRETURN(MATCH_THEN);      RRETURN(MATCH_THEN);
804    
805      /* Handle an atomic group that does not contain any capturing parentheses.      /* Handle an atomic group that does not contain any capturing parentheses.
806      This can be handled like an assertion. Prior to 8.13, all atomic groups      This can be handled like an assertion. Prior to 8.13, all atomic groups
807      were handled this way. In 8.13, the code was changed as below for ONCE, so      were handled this way. In 8.13, the code was changed as below for ONCE, so
808      that backups pass through the group and thereby reset captured values.      that backups pass through the group and thereby reset captured values.
809      However, this uses a lot more stack, so in 8.20, atomic groups that do not      However, this uses a lot more stack, so in 8.20, atomic groups that do not
810      contain any captures generate OP_ONCE_NC, which can be handled in the old,      contain any captures generate OP_ONCE_NC, which can be handled in the old,
811      less stack intensive way.      less stack intensive way.
812    
813      Check the alternative branches in turn - the matching won't pass the KET      Check the alternative branches in turn - the matching won't pass the KET
# Line 821  for (;;) Line 829  for (;;)
829        if (rrc == MATCH_THEN)        if (rrc == MATCH_THEN)
830          {          {
831          next = ecode + GET(ecode,1);          next = ecode + GET(ecode,1);
832          if (md->start_match_ptr < next &&          if (md->start_match_ptr < next &&
833              (*ecode == OP_ALT || *next == OP_ALT))              (*ecode == OP_ALT || *next == OP_ALT))
834            rrc = MATCH_NOMATCH;            rrc = MATCH_NOMATCH;
835          }          }
836    
837        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
838        ecode += GET(ecode,1);        ecode += GET(ecode,1);
839        }        }
# Line 867  for (;;) Line 875  for (;;)
875        }        }
876      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
877        {        {
878        md->match_function_type = MATCH_CBEGROUP;        md->match_function_type = MATCH_CBEGROUP;
879        RMATCH(eptr, prev, offset_top, md, eptrb, RM66);        RMATCH(eptr, prev, offset_top, md, eptrb, RM66);
880        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
881        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
# Line 915  for (;;) Line 923  for (;;)
923        for (;;)        for (;;)
924          {          {
925          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
926          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
927            eptrb, RM1);            eptrb, RM1);
928          if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */          if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */
929    
930          /* If we backed up to a THEN, check whether it is within the current          /* If we backed up to a THEN, check whether it is within the current
931          branch by comparing the address of the THEN that is passed back with          branch by comparing the address of the THEN that is passed back with
932          the end of the branch. If it is within the current branch, and the          the end of the branch. If it is within the current branch, and the
933          branch is one of two or more alternatives (it either starts or ends          branch is one of two or more alternatives (it either starts or ends
934          with OP_ALT), we have reached the limit of THEN's action, so convert          with OP_ALT), we have reached the limit of THEN's action, so convert
935          the return code to NOMATCH, which will cause normal backtracking to          the return code to NOMATCH, which will cause normal backtracking to
936          happen from now on. Otherwise, THEN is passed back to an outer          happen from now on. Otherwise, THEN is passed back to an outer
937          alternative. This implements Perl's treatment of parenthesized groups,          alternative. This implements Perl's treatment of parenthesized groups,
938          where a group not containing | does not affect the current alternative,          where a group not containing | does not affect the current alternative,
939          that is, (X) is NOT the same as (X|(*F)). */          that is, (X) is NOT the same as (X|(*F)). */
940    
941          if (rrc == MATCH_THEN)          if (rrc == MATCH_THEN)
942            {            {
943            next = ecode + GET(ecode,1);            next = ecode + GET(ecode,1);
944            if (md->start_match_ptr < next &&            if (md->start_match_ptr < next &&
945                (*ecode == OP_ALT || *next == OP_ALT))                (*ecode == OP_ALT || *next == OP_ALT))
946              rrc = MATCH_NOMATCH;              rrc = MATCH_NOMATCH;
947            }            }
948    
949          /* Anything other than NOMATCH is passed back. */          /* Anything other than NOMATCH is passed back. */
950    
951          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
# Line 953  for (;;) Line 961  for (;;)
961    
962        /* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */        /* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */
963    
       if (md->mark == NULL) md->mark = markptr;  
964        RRETURN(rrc);        RRETURN(rrc);
965        }        }
966    
# Line 1003  for (;;) Line 1010  for (;;)
1010    
1011        else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)        else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)
1012          {          {
1013          ecode += _pcre_OP_lengths[*ecode];          ecode += PRIV(OP_lengths)[*ecode];
1014          goto TAIL_RECURSE;          goto TAIL_RECURSE;
1015          }          }
1016    
1017        /* In all other cases, we have to make another call to match(). */        /* In all other cases, we have to make another call to match(). */
1018    
1019        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, eptrb,        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
1020          RM2);          RM2);
1021    
1022        /* See comment in the code for capturing groups above about handling        /* See comment in the code for capturing groups above about handling
1023        THEN. */        THEN. */
1024    
1025        if (rrc == MATCH_THEN)        if (rrc == MATCH_THEN)
1026          {          {
1027          next = ecode + GET(ecode,1);          next = ecode + GET(ecode,1);
1028          if (md->start_match_ptr < next &&          if (md->start_match_ptr < next &&
1029              (*ecode == OP_ALT || *next == OP_ALT))              (*ecode == OP_ALT || *next == OP_ALT))
1030            rrc = MATCH_NOMATCH;            rrc = MATCH_NOMATCH;
1031          }          }
1032    
1033        if (rrc != MATCH_NOMATCH)        if (rrc != MATCH_NOMATCH)
1034          {          {
1035          if (rrc == MATCH_ONCE)          if (rrc == MATCH_ONCE)
1036            {            {
1037            const uschar *scode = ecode;            const pcre_uchar *scode = ecode;
1038            if (*scode != OP_ONCE)           /* If not at start, find it */            if (*scode != OP_ONCE)           /* If not at start, find it */
1039              {              {
1040              while (*scode == OP_ALT) scode += GET(scode, 1);              while (*scode == OP_ALT) scode += GET(scode, 1);
# Line 1040  for (;;) Line 1047  for (;;)
1047        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1048        if (*ecode != OP_ALT) break;        if (*ecode != OP_ALT) break;
1049        }        }
1050    
     if (md->mark == NULL) md->mark = markptr;  
1051      RRETURN(MATCH_NOMATCH);      RRETURN(MATCH_NOMATCH);
1052    
1053      /* Handle possessive capturing brackets with an unlimited repeat. We come      /* Handle possessive capturing brackets with an unlimited repeat. We come
# Line 1070  for (;;) Line 1076  for (;;)
1076      if (offset < md->offset_max)      if (offset < md->offset_max)
1077        {        {
1078        matched_once = FALSE;        matched_once = FALSE;
1079        code_offset = ecode - md->start_code;        code_offset = (int)(ecode - md->start_code);
1080    
1081        save_offset1 = md->offset_vector[offset];        save_offset1 = md->offset_vector[offset];
1082        save_offset2 = md->offset_vector[offset+1];        save_offset2 = md->offset_vector[offset+1];
# Line 1093  for (;;) Line 1099  for (;;)
1099          md->offset_vector[md->offset_end - number] =          md->offset_vector[md->offset_end - number] =
1100            (int)(eptr - md->start_subject);            (int)(eptr - md->start_subject);
1101          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
1102          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
1103            eptrb, RM63);            eptrb, RM63);
1104          if (rrc == MATCH_KETRPOS)          if (rrc == MATCH_KETRPOS)
1105            {            {
# Line 1104  for (;;) Line 1110  for (;;)
1110            matched_once = TRUE;            matched_once = TRUE;
1111            continue;            continue;
1112            }            }
1113    
1114          /* See comment in the code for capturing groups above about handling          /* See comment in the code for capturing groups above about handling
1115          THEN. */          THEN. */
1116    
1117          if (rrc == MATCH_THEN)          if (rrc == MATCH_THEN)
1118            {            {
1119            next = ecode + GET(ecode,1);            next = ecode + GET(ecode,1);
1120            if (md->start_match_ptr < next &&            if (md->start_match_ptr < next &&
1121                (*ecode == OP_ALT || *next == OP_ALT))                (*ecode == OP_ALT || *next == OP_ALT))
1122              rrc = MATCH_NOMATCH;              rrc = MATCH_NOMATCH;
1123            }            }
1124    
1125          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1126          md->capture_last = save_capture_last;          md->capture_last = save_capture_last;
# Line 1129  for (;;) Line 1135  for (;;)
1135          md->offset_vector[md->offset_end - number] = save_offset3;          md->offset_vector[md->offset_end - number] = save_offset3;
1136          }          }
1137    
       if (md->mark == NULL) md->mark = markptr;  
1138        if (allow_zero || matched_once)        if (allow_zero || matched_once)
1139          {          {
1140          ecode += 1 + LINK_SIZE;          ecode += 1 + LINK_SIZE;
# Line 1161  for (;;) Line 1166  for (;;)
1166    
1167      POSSESSIVE_NON_CAPTURE:      POSSESSIVE_NON_CAPTURE:
1168      matched_once = FALSE;      matched_once = FALSE;
1169      code_offset = ecode - md->start_code;      code_offset = (int)(ecode - md->start_code);
1170    
1171      for (;;)      for (;;)
1172        {        {
1173        if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;        if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
1174        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
1175          eptrb, RM48);          eptrb, RM48);
1176        if (rrc == MATCH_KETRPOS)        if (rrc == MATCH_KETRPOS)
1177          {          {
# Line 1176  for (;;) Line 1181  for (;;)
1181          matched_once = TRUE;          matched_once = TRUE;
1182          continue;          continue;
1183          }          }
1184    
1185        /* See comment in the code for capturing groups above about handling        /* See comment in the code for capturing groups above about handling
1186        THEN. */        THEN. */
1187    
1188        if (rrc == MATCH_THEN)        if (rrc == MATCH_THEN)
1189          {          {
1190          next = ecode + GET(ecode,1);          next = ecode + GET(ecode,1);
1191          if (md->start_match_ptr < next &&          if (md->start_match_ptr < next &&
1192              (*ecode == OP_ALT || *next == OP_ALT))              (*ecode == OP_ALT || *next == OP_ALT))
1193            rrc = MATCH_NOMATCH;            rrc = MATCH_NOMATCH;
1194          }          }
1195    
1196        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1197        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
# Line 1216  for (;;) Line 1221  for (;;)
1221    
1222      if (ecode[LINK_SIZE+1] == OP_CALLOUT)      if (ecode[LINK_SIZE+1] == OP_CALLOUT)
1223        {        {
1224        if (pcre_callout != NULL)        if (PUBL(callout) != NULL)
1225          {          {
1226          pcre_callout_block cb;          pcre_callout_block cb;
1227          cb.version          = 2;   /* Version 1 of the callout block */          cb.version          = 2;   /* Version 1 of the callout block */
# Line 1231  for (;;) Line 1236  for (;;)
1236          cb.capture_top      = offset_top/2;          cb.capture_top      = offset_top/2;
1237          cb.capture_last     = md->capture_last;          cb.capture_last     = md->capture_last;
1238          cb.callout_data     = md->callout_data;          cb.callout_data     = md->callout_data;
1239          cb.mark             = markptr;          cb.mark             = md->nomatch_mark;
1240          if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);          if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1241          if (rrc < 0) RRETURN(rrc);          if (rrc < 0) RRETURN(rrc);
1242          }          }
1243        ecode += _pcre_OP_lengths[OP_CALLOUT];        ecode += PRIV(OP_lengths)[OP_CALLOUT];
1244        }        }
1245    
1246      condcode = ecode[LINK_SIZE+1];      condcode = ecode[LINK_SIZE+1];
# Line 1252  for (;;) Line 1257  for (;;)
1257        else        else
1258          {          {
1259          int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/          int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/
1260          condition =  (recno == RREF_ANY || recno == md->recursive->group_num);          condition = (recno == RREF_ANY || recno == md->recursive->group_num);
1261    
1262          /* If the test is for recursion into a specific subpattern, and it is          /* If the test is for recursion into a specific subpattern, and it is
1263          false, but the test was set up by name, scan the table to see if the          false, but the test was set up by name, scan the table to see if the
1264          name refers to any other numbers, and test them. The condition is true          name refers to any other numbers, and test them. The condition is true
1265          if any one is set. */          if any one is set. */
1266    
1267          if (!condition && condcode == OP_NRREF && recno != RREF_ANY)          if (!condition && condcode == OP_NRREF)
1268            {            {
1269            uschar *slotA = md->name_table;            pcre_uchar *slotA = md->name_table;
1270            for (i = 0; i < md->name_count; i++)            for (i = 0; i < md->name_count; i++)
1271              {              {
1272              if (GET2(slotA, 0) == recno) break;              if (GET2(slotA, 0) == recno) break;
# Line 1274  for (;;) Line 1279  for (;;)
1279    
1280            if (i < md->name_count)            if (i < md->name_count)
1281              {              {
1282              uschar *slotB = slotA;              pcre_uchar *slotB = slotA;
1283              while (slotB > md->name_table)              while (slotB > md->name_table)
1284                {                {
1285                slotB -= md->name_entry_size;                slotB -= md->name_entry_size;
1286                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1287                  {                  {
1288                  condition = GET2(slotB, 0) == md->recursive->group_num;                  condition = GET2(slotB, 0) == md->recursive->group_num;
1289                  if (condition) break;                  if (condition) break;
# Line 1294  for (;;) Line 1299  for (;;)
1299                for (i++; i < md->name_count; i++)                for (i++; i < md->name_count; i++)
1300                  {                  {
1301                  slotB += md->name_entry_size;                  slotB += md->name_entry_size;
1302                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                  if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1303                    {                    {
1304                    condition = GET2(slotB, 0) == md->recursive->group_num;                    condition = GET2(slotB, 0) == md->recursive->group_num;
1305                    if (condition) break;                    if (condition) break;
# Line 1307  for (;;) Line 1312  for (;;)
1312    
1313          /* Chose branch according to the condition */          /* Chose branch according to the condition */
1314    
1315          ecode += condition? 3 : GET(ecode, 1);          ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
1316          }          }
1317        }        }
1318    
# Line 1324  for (;;) Line 1329  for (;;)
1329        if (!condition && condcode == OP_NCREF)        if (!condition && condcode == OP_NCREF)
1330          {          {
1331          int refno = offset >> 1;          int refno = offset >> 1;
1332          uschar *slotA = md->name_table;          pcre_uchar *slotA = md->name_table;
1333    
1334          for (i = 0; i < md->name_count; i++)          for (i = 0; i < md->name_count; i++)
1335            {            {
# Line 1338  for (;;) Line 1343  for (;;)
1343    
1344          if (i < md->name_count)          if (i < md->name_count)
1345            {            {
1346            uschar *slotB = slotA;            pcre_uchar *slotB = slotA;
1347            while (slotB > md->name_table)            while (slotB > md->name_table)
1348              {              {
1349              slotB -= md->name_entry_size;              slotB -= md->name_entry_size;
1350              if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)              if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1351                {                {
1352                offset = GET2(slotB, 0) << 1;                offset = GET2(slotB, 0) << 1;
1353                condition = offset < offset_top &&                condition = offset < offset_top &&
# Line 1360  for (;;) Line 1365  for (;;)
1365              for (i++; i < md->name_count; i++)              for (i++; i < md->name_count; i++)
1366                {                {
1367                slotB += md->name_entry_size;                slotB += md->name_entry_size;
1368                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1369                  {                  {
1370                  offset = GET2(slotB, 0) << 1;                  offset = GET2(slotB, 0) << 1;
1371                  condition = offset < offset_top &&                  condition = offset < offset_top &&
# Line 1375  for (;;) Line 1380  for (;;)
1380    
1381        /* Chose branch according to the condition */        /* Chose branch according to the condition */
1382    
1383        ecode += condition? 3 : GET(ecode, 1);        ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
1384        }        }
1385    
1386      else if (condcode == OP_DEF)     /* DEFINE - always false */      else if (condcode == OP_DEF)     /* DEFINE - always false */
# Line 1400  for (;;) Line 1405  for (;;)
1405          ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);          ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
1406          while (*ecode == OP_ALT) ecode += GET(ecode, 1);          while (*ecode == OP_ALT) ecode += GET(ecode, 1);
1407          }          }
1408    
1409        /* PCRE doesn't allow the effect of (*THEN) to escape beyond an        /* PCRE doesn't allow the effect of (*THEN) to escape beyond an
1410        assertion; it is therefore treated as NOMATCH. */        assertion; it is therefore treated as NOMATCH. */
1411    
1412        else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)        else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
1413          {          {
1414          RRETURN(rrc);         /* Need braces because of following else */          RRETURN(rrc);         /* Need braces because of following else */
1415          }          }
# Line 1432  for (;;) Line 1437  for (;;)
1437          ecode += 1 + LINK_SIZE;          ecode += 1 + LINK_SIZE;
1438          goto TAIL_RECURSE;          goto TAIL_RECURSE;
1439          }          }
1440    
1441        md->match_function_type = MATCH_CBEGROUP;        md->match_function_type = MATCH_CBEGROUP;
1442        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49);
1443        RRETURN(rrc);        RRETURN(rrc);
# Line 1467  for (;;) Line 1472  for (;;)
1472        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
1473        if (offset_top <= offset) offset_top = offset + 2;        if (offset_top <= offset) offset_top = offset + 2;
1474        }        }
1475      ecode += 3;      ecode += 1 + IMM2_SIZE;
1476      break;      break;
1477    
1478    
# Line 1487  for (;;) Line 1492  for (;;)
1492           (md->notempty ||           (md->notempty ||
1493             (md->notempty_atstart &&             (md->notempty_atstart &&
1494               mstart == md->start_subject + md->start_offset)))               mstart == md->start_subject + md->start_offset)))
1495        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
1496    
1497      /* Otherwise, we have a match. */      /* Otherwise, we have a match. */
1498    
# Line 1496  for (;;) Line 1501  for (;;)
1501      md->start_match_ptr = mstart;       /* and the start (\K can modify) */      md->start_match_ptr = mstart;       /* and the start (\K can modify) */
1502    
1503      /* For some reason, the macros don't work properly if an expression is      /* For some reason, the macros don't work properly if an expression is
1504      given as the argument to MRRETURN when the heap is in use. */      given as the argument to RRETURN when the heap is in use. */
1505    
1506      rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;      rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;
1507      MRRETURN(rrc);      RRETURN(rrc);
1508    
1509      /* Assertion brackets. Check the alternative branches in turn - the      /* Assertion brackets. Check the alternative branches in turn - the
1510      matching won't pass the KET for an assertion. If any one branch matches,      matching won't pass the KET for an assertion. If any one branch matches,
# Line 1527  for (;;) Line 1532  for (;;)
1532        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
1533          {          {
1534          mstart = md->start_match_ptr;   /* In case \K reset it */          mstart = md->start_match_ptr;   /* In case \K reset it */
         markptr = md->mark;  
1535          break;          break;
1536          }          }
1537    
1538        /* PCRE does not allow THEN to escape beyond an assertion; it is treated        /* PCRE does not allow THEN to escape beyond an assertion; it is treated
1539        as NOMATCH. */        as NOMATCH. */
1540    
1541        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1542        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1543        }        }
1544      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
1545    
1546      if (*ecode == OP_KET) MRRETURN(MATCH_NOMATCH);      if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);
1547    
1548      /* If checking an assertion for a condition, return MATCH_MATCH. */      /* If checking an assertion for a condition, return MATCH_MATCH. */
1549    
# Line 1569  for (;;) Line 1573  for (;;)
1573      do      do
1574        {        {
1575        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);
1576        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) MRRETURN(MATCH_NOMATCH);        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);
1577        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
1578          {          {
1579          do ecode += GET(ecode,1); while (*ecode == OP_ALT);          do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1580          break;          break;
1581          }          }
1582    
1583        /* PCRE does not allow THEN to escape beyond an assertion; it is treated        /* PCRE does not allow THEN to escape beyond an assertion; it is treated
1584        as NOMATCH. */        as NOMATCH. */
1585    
1586        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
# Line 1595  for (;;) Line 1599  for (;;)
1599      back a number of characters, not bytes. */      back a number of characters, not bytes. */
1600    
1601      case OP_REVERSE:      case OP_REVERSE:
1602  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1603      if (utf8)      if (utf)
1604        {        {
1605        i = GET(ecode, 1);        i = GET(ecode, 1);
1606        while (i-- > 0)        while (i-- > 0)
1607          {          {
1608          eptr--;          eptr--;
1609          if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);          if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
1610          BACKCHAR(eptr);          BACKCHAR(eptr);
1611          }          }
1612        }        }
# Line 1613  for (;;) Line 1617  for (;;)
1617    
1618        {        {
1619        eptr -= GET(ecode, 1);        eptr -= GET(ecode, 1);
1620        if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);        if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
1621        }        }
1622    
1623      /* Save the earliest consulted character, then skip to next op code */      /* Save the earliest consulted character, then skip to next op code */
# Line 1627  for (;;) Line 1631  for (;;)
1631      function is able to force a failure. */      function is able to force a failure. */
1632    
1633      case OP_CALLOUT:      case OP_CALLOUT:
1634      if (pcre_callout != NULL)      if (PUBL(callout) != NULL)
1635        {        {
1636        pcre_callout_block cb;        pcre_callout_block cb;
1637        cb.version          = 2;   /* Version 1 of the callout block */        cb.version          = 2;   /* Version 1 of the callout block */
# Line 1642  for (;;) Line 1646  for (;;)
1646        cb.capture_top      = offset_top/2;        cb.capture_top      = offset_top/2;
1647        cb.capture_last     = md->capture_last;        cb.capture_last     = md->capture_last;
1648        cb.callout_data     = md->callout_data;        cb.callout_data     = md->callout_data;
1649        cb.mark             = markptr;        cb.mark             = md->nomatch_mark;
1650        if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);        if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1651        if (rrc < 0) RRETURN(rrc);        if (rrc < 0) RRETURN(rrc);
1652        }        }
1653      ecode += 2 + 2*LINK_SIZE;      ecode += 2 + 2*LINK_SIZE;
# Line 1702  for (;;) Line 1706  for (;;)
1706        else        else
1707          {          {
1708          new_recursive.offset_save =          new_recursive.offset_save =
1709            (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int));            (int *)(PUBL(malloc))(new_recursive.saved_max * sizeof(int));
1710          if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);          if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
1711          }          }
1712        memcpy(new_recursive.offset_save, md->offset_vector,        memcpy(new_recursive.offset_save, md->offset_vector,
# Line 1717  for (;;) Line 1721  for (;;)
1721        do        do
1722          {          {
1723          if (cbegroup) md->match_function_type = MATCH_CBEGROUP;          if (cbegroup) md->match_function_type = MATCH_CBEGROUP;
1724          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,          RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top,
1725            md, eptrb, RM6);            md, eptrb, RM6);
1726          memcpy(md->offset_vector, new_recursive.offset_save,          memcpy(md->offset_vector, new_recursive.offset_save,
1727              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
# Line 1726  for (;;) Line 1730  for (;;)
1730            {            {
1731            DPRINTF(("Recursion matched\n"));            DPRINTF(("Recursion matched\n"));
1732            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1733              (pcre_free)(new_recursive.offset_save);              (PUBL(free))(new_recursive.offset_save);
1734    
1735            /* Set where we got to in the subject, and reset the start in case            /* Set where we got to in the subject, and reset the start in case
1736            it was changed by \K. This *is* propagated back out of a recursion,            it was changed by \K. This *is* propagated back out of a recursion,
# Line 1740  for (;;) Line 1744  for (;;)
1744          /* PCRE does not allow THEN to escape beyond a recursion; it is treated          /* PCRE does not allow THEN to escape beyond a recursion; it is treated
1745          as NOMATCH. */          as NOMATCH. */
1746    
1747          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
1748            {            {
1749            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1750            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1751              (pcre_free)(new_recursive.offset_save);              (PUBL(free))(new_recursive.offset_save);
1752            RRETURN(rrc);            RRETURN(rrc);
1753            }            }
1754    
# Line 1756  for (;;) Line 1760  for (;;)
1760        DPRINTF(("Recursion didn't match\n"));        DPRINTF(("Recursion didn't match\n"));
1761        md->recursive = new_recursive.prevrec;        md->recursive = new_recursive.prevrec;
1762        if (new_recursive.offset_save != stacksave)        if (new_recursive.offset_save != stacksave)
1763          (pcre_free)(new_recursive.offset_save);          (PUBL(free))(new_recursive.offset_save);
1764        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
1765        }        }
1766    
1767      RECURSION_MATCHED:      RECURSION_MATCHED:
# Line 1826  for (;;) Line 1830  for (;;)
1830        }        }
1831      else saved_eptr = NULL;      else saved_eptr = NULL;
1832    
1833      /* If we are at the end of an assertion group or a non-capturing atomic      /* If we are at the end of an assertion group or a non-capturing atomic
1834      group, stop matching and return MATCH_MATCH, but record the current high      group, stop matching and return MATCH_MATCH, but record the current high
1835      water mark for use by positive assertions. We also need to record the match      water mark for use by positive assertions. We also need to record the match
1836      start in case it was changed by \K. */      start in case it was changed by \K. */
1837    
1838      if ((*prev >= OP_ASSERT && *prev <= OP_ASSERTBACK_NOT) ||      if ((*prev >= OP_ASSERT && *prev <= OP_ASSERTBACK_NOT) ||
1839           *prev == OP_ONCE_NC)           *prev == OP_ONCE_NC)
1840        {        {
1841        md->end_match_ptr = eptr;      /* For ONCE_NC */        md->end_match_ptr = eptr;      /* For ONCE_NC */
1842        md->end_offset_top = offset_top;        md->end_offset_top = offset_top;
1843        md->start_match_ptr = mstart;        md->start_match_ptr = mstart;
1844        MRRETURN(MATCH_MATCH);         /* Sets md->mark */        RRETURN(MATCH_MATCH);         /* Sets md->mark */
1845        }        }
1846    
1847      /* For capturing groups we have to check the group number back at the start      /* For capturing groups we have to check the group number back at the start
# Line 1979  for (;;) Line 1983  for (;;)
1983      /* Not multiline mode: start of subject assertion, unless notbol. */      /* Not multiline mode: start of subject assertion, unless notbol. */
1984    
1985      case OP_CIRC:      case OP_CIRC:
1986      if (md->notbol && eptr == md->start_subject) MRRETURN(MATCH_NOMATCH);      if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
1987    
1988      /* Start of subject assertion */      /* Start of subject assertion */
1989    
1990      case OP_SOD:      case OP_SOD:
1991      if (eptr != md->start_subject) MRRETURN(MATCH_NOMATCH);      if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH);
1992      ecode++;      ecode++;
1993      break;      break;
1994    
1995      /* Multiline mode: start of subject unless notbol, or after any newline. */      /* Multiline mode: start of subject unless notbol, or after any newline. */
1996    
1997      case OP_CIRCM:      case OP_CIRCM:
1998      if (md->notbol && eptr == md->start_subject) MRRETURN(MATCH_NOMATCH);      if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
1999      if (eptr != md->start_subject &&      if (eptr != md->start_subject &&
2000          (eptr == md->end_subject || !WAS_NEWLINE(eptr)))          (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
2001        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2002      ecode++;      ecode++;
2003      break;      break;
2004    
2005      /* Start of match assertion */      /* Start of match assertion */
2006    
2007      case OP_SOM:      case OP_SOM:
2008      if (eptr != md->start_subject + md->start_offset) MRRETURN(MATCH_NOMATCH);      if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH);
2009      ecode++;      ecode++;
2010      break;      break;
2011    
# Line 2017  for (;;) Line 2021  for (;;)
2021    
2022      case OP_DOLLM:      case OP_DOLLM:
2023      if (eptr < md->end_subject)      if (eptr < md->end_subject)
2024        { if (!IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); }        { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }
2025      else      else
2026        {        {
2027        if (md->noteol) MRRETURN(MATCH_NOMATCH);        if (md->noteol) RRETURN(MATCH_NOMATCH);
2028        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2029        }        }
2030      ecode++;      ecode++;
# Line 2030  for (;;) Line 2034  for (;;)
2034      subject unless noteol is set. */      subject unless noteol is set. */
2035    
2036      case OP_DOLL:      case OP_DOLL:
2037      if (md->noteol) MRRETURN(MATCH_NOMATCH);      if (md->noteol) RRETURN(MATCH_NOMATCH);
2038      if (!md->endonly) goto ASSERT_NL_OR_EOS;      if (!md->endonly) goto ASSERT_NL_OR_EOS;
2039    
2040      /* ... else fall through for endonly */      /* ... else fall through for endonly */
# Line 2038  for (;;) Line 2042  for (;;)
2042      /* End of subject assertion (\z) */      /* End of subject assertion (\z) */
2043    
2044      case OP_EOD:      case OP_EOD:
2045      if (eptr < md->end_subject) MRRETURN(MATCH_NOMATCH);      if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH);
2046      SCHECK_PARTIAL();      SCHECK_PARTIAL();
2047      ecode++;      ecode++;
2048      break;      break;
# Line 2049  for (;;) Line 2053  for (;;)
2053      ASSERT_NL_OR_EOS:      ASSERT_NL_OR_EOS:
2054      if (eptr < md->end_subject &&      if (eptr < md->end_subject &&
2055          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
2056        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2057    
2058      /* Either at end of string or \n before end. */      /* Either at end of string or \n before end. */
2059    
# Line 2068  for (;;) Line 2072  for (;;)
2072        be "non-word" characters. Remember the earliest consulted character for        be "non-word" characters. Remember the earliest consulted character for
2073        partial matching. */        partial matching. */
2074    
2075  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2076        if (utf8)        if (utf)
2077          {          {
2078          /* Get status of previous character */          /* Get status of previous character */
2079    
2080          if (eptr == md->start_subject) prev_is_word = FALSE; else          if (eptr == md->start_subject) prev_is_word = FALSE; else
2081            {            {
2082            USPTR lastptr = eptr - 1;            PCRE_PUCHAR lastptr = eptr - 1;
2083            while((*lastptr & 0xc0) == 0x80) lastptr--;            BACKCHAR(lastptr);
2084            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
2085            GETCHAR(c, lastptr);            GETCHAR(c, lastptr);
2086  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2141  for (;;) Line 2145  for (;;)
2145              }              }
2146            else            else
2147  #endif  #endif
2148            prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);            prev_is_word = MAX_255(eptr[-1])
2149                && ((md->ctypes[eptr[-1]] & ctype_word) != 0);
2150            }            }
2151    
2152          /* Get status of next character */          /* Get status of next character */
# Line 2164  for (;;) Line 2169  for (;;)
2169            }            }
2170          else          else
2171  #endif  #endif
2172          cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);          cur_is_word = MAX_255(*eptr)
2173              && ((md->ctypes[*eptr] & ctype_word) != 0);
2174          }          }
2175    
2176        /* Now see if the situation is what we want */        /* Now see if the situation is what we want */
2177    
2178        if ((*ecode++ == OP_WORD_BOUNDARY)?        if ((*ecode++ == OP_WORD_BOUNDARY)?
2179             cur_is_word == prev_is_word : cur_is_word != prev_is_word)             cur_is_word == prev_is_word : cur_is_word != prev_is_word)
2180          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2181        }        }
2182      break;      break;
2183    
2184      /* Match a single character type; inline for speed */      /* Match a single character type; inline for speed */
2185    
2186      case OP_ANY:      case OP_ANY:
2187      if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
2188      /* Fall through */      /* Fall through */
2189    
2190      case OP_ALLANY:      case OP_ALLANY:
2191      if (eptr >= md->end_subject)   /* DO NOT merge the eptr++ here; it must */      if (eptr >= md->end_subject)   /* DO NOT merge the eptr++ here; it must */
2192        {                            /* not be updated before SCHECK_PARTIAL. */        {                            /* not be updated before SCHECK_PARTIAL. */
2193        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2194        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2195        }        }
2196      eptr++;      eptr++;
2197      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;  #ifdef SUPPORT_UTF
2198        if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
2199    #endif
2200      ecode++;      ecode++;
2201      break;      break;
2202    
# Line 2199  for (;;) Line 2207  for (;;)
2207      if (eptr >= md->end_subject)   /* DO NOT merge the eptr++ here; it must */      if (eptr >= md->end_subject)   /* DO NOT merge the eptr++ here; it must */
2208        {                            /* not be updated before SCHECK_PARTIAL. */        {                            /* not be updated before SCHECK_PARTIAL. */
2209        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2210        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2211        }        }
2212      eptr++;      eptr++;
2213      ecode++;      ecode++;
# Line 2209  for (;;) Line 2217  for (;;)
2217      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2218        {        {
2219        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2220        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2221        }        }
2222      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2223      if (      if (
2224  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2225         c < 256 &&         c < 256 &&
2226  #endif  #endif
2227         (md->ctypes[c] & ctype_digit) != 0         (md->ctypes[c] & ctype_digit) != 0
2228         )         )
2229        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2230      ecode++;      ecode++;
2231      break;      break;
2232    
# Line 2226  for (;;) Line 2234  for (;;)
2234      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2235        {        {
2236        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2237        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2238        }        }
2239      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2240      if (      if (
2241  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2242         c >= 256 ||         c > 255 ||
2243  #endif  #endif
2244         (md->ctypes[c] & ctype_digit) == 0         (md->ctypes[c] & ctype_digit) == 0
2245         )         )
2246        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2247      ecode++;      ecode++;
2248      break;      break;
2249    
# Line 2243  for (;;) Line 2251  for (;;)
2251      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2252        {        {
2253        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2254        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2255        }        }
2256      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2257      if (      if (
2258  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2259         c < 256 &&         c < 256 &&
2260  #endif  #endif
2261         (md->ctypes[c] & ctype_space) != 0         (md->ctypes[c] & ctype_space) != 0
2262         )         )
2263        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2264      ecode++;      ecode++;
2265      break;      break;
2266    
# Line 2260  for (;;) Line 2268  for (;;)
2268      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2269        {        {
2270        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2271        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2272        }        }
2273      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2274      if (      if (
2275  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2276         c >= 256 ||         c > 255 ||
2277  #endif  #endif
2278         (md->ctypes[c] & ctype_space) == 0         (md->ctypes[c] & ctype_space) == 0
2279         )         )
2280        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2281      ecode++;      ecode++;
2282      break;      break;
2283    
# Line 2277  for (;;) Line 2285  for (;;)
2285      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2286        {        {
2287        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2288        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2289        }        }
2290      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2291      if (      if (
2292  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2293         c < 256 &&         c < 256 &&
2294  #endif  #endif
2295         (md->ctypes[c] & ctype_word) != 0         (md->ctypes[c] & ctype_word) != 0
2296         )         )
2297        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2298      ecode++;      ecode++;
2299      break;      break;
2300    
# Line 2294  for (;;) Line 2302  for (;;)
2302      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2303        {        {
2304        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2305        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2306        }        }
2307      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2308      if (      if (
2309  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2310         c >= 256 ||         c > 255 ||
2311  #endif  #endif
2312         (md->ctypes[c] & ctype_word) == 0         (md->ctypes[c] & ctype_word) == 0
2313         )         )
2314        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2315      ecode++;      ecode++;
2316      break;      break;
2317    
# Line 2311  for (;;) Line 2319  for (;;)
2319      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2320        {        {
2321        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2322        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2323        }        }
2324      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2325      switch(c)      switch(c)
2326        {        {
2327        default: MRRETURN(MATCH_NOMATCH);        default: RRETURN(MATCH_NOMATCH);
2328    
2329        case 0x000d:        case 0x000d:
2330        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
# Line 2330  for (;;) Line 2338  for (;;)
2338        case 0x0085:        case 0x0085:
2339        case 0x2028:        case 0x2028:
2340        case 0x2029:        case 0x2029:
2341        if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);        if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
2342        break;        break;
2343        }        }
2344      ecode++;      ecode++;
# Line 2340  for (;;) Line 2348  for (;;)
2348      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2349        {        {
2350        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2351        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2352        }        }
2353      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2354      switch(c)      switch(c)
# Line 2365  for (;;) Line 2373  for (;;)
2373        case 0x202f:    /* NARROW NO-BREAK SPACE */        case 0x202f:    /* NARROW NO-BREAK SPACE */
2374        case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */        case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
2375        case 0x3000:    /* IDEOGRAPHIC SPACE */        case 0x3000:    /* IDEOGRAPHIC SPACE */
2376        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2377        }        }
2378      ecode++;      ecode++;
2379      break;      break;
# Line 2374  for (;;) Line 2382  for (;;)
2382      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2383        {        {
2384        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2385        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2386        }        }
2387      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2388      switch(c)      switch(c)
2389        {        {
2390        default: MRRETURN(MATCH_NOMATCH);        default: RRETURN(MATCH_NOMATCH);
2391        case 0x09:      /* HT */        case 0x09:      /* HT */
2392        case 0x20:      /* SPACE */        case 0x20:      /* SPACE */
2393        case 0xa0:      /* NBSP */        case 0xa0:      /* NBSP */
# Line 2408  for (;;) Line 2416  for (;;)
2416      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2417        {        {
2418        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2419        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2420        }        }
2421      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2422      switch(c)      switch(c)
# Line 2421  for (;;) Line 2429  for (;;)
2429        case 0x85:      /* NEL */        case 0x85:      /* NEL */
2430        case 0x2028:    /* LINE SEPARATOR */        case 0x2028:    /* LINE SEPARATOR */
2431        case 0x2029:    /* PARAGRAPH SEPARATOR */        case 0x2029:    /* PARAGRAPH SEPARATOR */
2432        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2433        }        }
2434      ecode++;      ecode++;
2435      break;      break;
# Line 2430  for (;;) Line 2438  for (;;)
2438      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2439        {        {
2440        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2441        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2442        }        }
2443      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2444      switch(c)      switch(c)
2445        {        {
2446        default: MRRETURN(MATCH_NOMATCH);        default: RRETURN(MATCH_NOMATCH);
2447        case 0x0a:      /* LF */        case 0x0a:      /* LF */
2448        case 0x0b:      /* VT */        case 0x0b:      /* VT */
2449        case 0x0c:      /* FF */        case 0x0c:      /* FF */
# Line 2457  for (;;) Line 2465  for (;;)
2465      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2466        {        {
2467        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2468        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2469        }        }
2470      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2471        {        {
# Line 2466  for (;;) Line 2474  for (;;)
2474        switch(ecode[1])        switch(ecode[1])
2475          {          {
2476          case PT_ANY:          case PT_ANY:
2477          if (op == OP_NOTPROP) MRRETURN(MATCH_NOMATCH);          if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
2478          break;          break;
2479    
2480          case PT_LAMP:          case PT_LAMP:
2481          if ((prop->chartype == ucp_Lu ||          if ((prop->chartype == ucp_Lu ||
2482               prop->chartype == ucp_Ll ||               prop->chartype == ucp_Ll ||
2483               prop->chartype == ucp_Lt) == (op == OP_NOTPROP))               prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
2484            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2485          break;          break;
2486    
2487          case PT_GC:          case PT_GC:
2488          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))          if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP))
2489            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2490          break;          break;
2491    
2492          case PT_PC:          case PT_PC:
2493          if ((ecode[2] != prop->chartype) == (op == OP_PROP))          if ((ecode[2] != prop->chartype) == (op == OP_PROP))
2494            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2495          break;          break;
2496    
2497          case PT_SC:          case PT_SC:
2498          if ((ecode[2] != prop->script) == (op == OP_PROP))          if ((ecode[2] != prop->script) == (op == OP_PROP))
2499            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2500          break;          break;
2501    
2502          /* These are specials */          /* These are specials */
2503    
2504          case PT_ALNUM:          case PT_ALNUM:
2505          if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
2506               _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP))               PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
2507            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2508          break;          break;
2509    
2510          case PT_SPACE:    /* Perl space */          case PT_SPACE:    /* Perl space */
2511          if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
2512               c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)               c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
2513                 == (op == OP_NOTPROP))                 == (op == OP_NOTPROP))
2514            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2515          break;          break;
2516    
2517          case PT_PXSPACE:  /* POSIX space */          case PT_PXSPACE:  /* POSIX space */
2518          if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
2519               c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||               c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
2520               c == CHAR_FF || c == CHAR_CR)               c == CHAR_FF || c == CHAR_CR)
2521                 == (op == OP_NOTPROP))                 == (op == OP_NOTPROP))
2522            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2523          break;          break;
2524    
2525          case PT_WORD:          case PT_WORD:
2526          if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
2527               _pcre_ucp_gentype[prop->chartype] == ucp_N ||               PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
2528               c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))               c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
2529            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2530          break;          break;
2531    
2532          /* This should never occur */          /* This should never occur */
# Line 2538  for (;;) Line 2546  for (;;)
2546      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2547        {        {
2548        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2549        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2550        }        }
2551      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2552      if (UCD_CATEGORY(c) == ucp_M) MRRETURN(MATCH_NOMATCH);      if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
2553      while (eptr < md->end_subject)      while (eptr < md->end_subject)
2554        {        {
2555        int len = 1;        int len = 1;
2556        if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }        if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
2557        if (UCD_CATEGORY(c) != ucp_M) break;        if (UCD_CATEGORY(c) != ucp_M) break;
2558        eptr += len;        eptr += len;
2559        }        }
# Line 2566  for (;;) Line 2574  for (;;)
2574      case OP_REFI:      case OP_REFI:
2575      caseless = op == OP_REFI;      caseless = op == OP_REFI;
2576      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */
2577      ecode += 3;      ecode += 1 + IMM2_SIZE;
2578    
2579      /* If the reference is unset, there are two possibilities:      /* If the reference is unset, there are two possibilities:
2580    
# Line 2606  for (;;) Line 2614  for (;;)
2614        case OP_CRMINRANGE:        case OP_CRMINRANGE:
2615        minimize = (*ecode == OP_CRMINRANGE);        minimize = (*ecode == OP_CRMINRANGE);
2616        min = GET2(ecode, 1);        min = GET2(ecode, 1);
2617        max = GET2(ecode, 3);        max = GET2(ecode, 1 + IMM2_SIZE);
2618        if (max == 0) max = INT_MAX;        if (max == 0) max = INT_MAX;
2619        ecode += 5;        ecode += 1 + 2 * IMM2_SIZE;
2620        break;        break;
2621    
2622        default:               /* No repeat follows */        default:               /* No repeat follows */
2623        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)
2624          {          {
2625          CHECK_PARTIAL();          CHECK_PARTIAL();
2626          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2627          }          }
2628        eptr += length;        eptr += length;
2629        continue;              /* With the main loop */        continue;              /* With the main loop */
# Line 2636  for (;;) Line 2644  for (;;)
2644        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2645          {          {
2646          CHECK_PARTIAL();          CHECK_PARTIAL();
2647          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2648          }          }
2649        eptr += slength;        eptr += slength;
2650        }        }
# Line 2655  for (;;) Line 2663  for (;;)
2663          int slength;          int slength;
2664          RMATCH(eptr, ecode, offset_top, md, eptrb, RM14);          RMATCH(eptr, ecode, offset_top, md, eptrb, RM14);
2665          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2666          if (fi >= max) MRRETURN(MATCH_NOMATCH);          if (fi >= max) RRETURN(MATCH_NOMATCH);
2667          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2668            {            {
2669            CHECK_PARTIAL();            CHECK_PARTIAL();
2670            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2671            }            }
2672          eptr += slength;          eptr += slength;
2673          }          }
# Line 2687  for (;;) Line 2695  for (;;)
2695          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2696          eptr -= length;          eptr -= length;
2697          }          }
2698        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2699        }        }
2700      /* Control never gets here */      /* Control never gets here */
2701    
# Line 2705  for (;;) Line 2713  for (;;)
2713      case OP_NCLASS:      case OP_NCLASS:
2714      case OP_CLASS:      case OP_CLASS:
2715        {        {
2716          /* The data variable is saved across frames, so the byte map needs to
2717          be stored there. */
2718    #define BYTE_MAP ((pcre_uint8 *)data)
2719        data = ecode + 1;                /* Save for matching */        data = ecode + 1;                /* Save for matching */
2720        ecode += 33;                     /* Advance past the item */        ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */
2721    
2722        switch (*ecode)        switch (*ecode)
2723          {          {
# Line 2727  for (;;) Line 2738  for (;;)
2738          case OP_CRMINRANGE:          case OP_CRMINRANGE:
2739          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
2740          min = GET2(ecode, 1);          min = GET2(ecode, 1);
2741          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
2742          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
2743          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
2744          break;          break;
2745    
2746          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2739  for (;;) Line 2750  for (;;)
2750    
2751        /* First, ensure the minimum number of matches are present. */        /* First, ensure the minimum number of matches are present. */
2752    
2753  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2754        /* UTF-8 mode */        if (utf)
       if (utf8)  
2755          {          {
2756          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2757            {            {
2758            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2759              {              {
2760              SCHECK_PARTIAL();              SCHECK_PARTIAL();
2761              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2762              }              }
2763            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
2764            if (c > 255)            if (c > 255)
2765              {              {
2766              if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2767              }              }
2768            else            else
2769              {              if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
             if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);  
             }  
2770            }            }
2771          }          }
2772        else        else
2773  #endif  #endif
2774        /* Not UTF-8 mode */        /* Not UTF mode */
2775          {          {
2776          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2777            {            {
2778            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2779              {              {
2780              SCHECK_PARTIAL();              SCHECK_PARTIAL();
2781              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2782              }              }
2783            c = *eptr++;            c = *eptr++;
2784            if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2785              if (c > 255)
2786                {
2787                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2788                }
2789              else
2790    #endif
2791                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2792            }            }
2793          }          }
2794    
# Line 2787  for (;;) Line 2802  for (;;)
2802    
2803        if (minimize)        if (minimize)
2804          {          {
2805  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2806          /* UTF-8 mode */          if (utf)
         if (utf8)  
2807            {            {
2808            for (fi = min;; fi++)            for (fi = min;; fi++)
2809              {              {
2810              RMATCH(eptr, ecode, offset_top, md, eptrb, RM16);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM16);
2811              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2812              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
2813              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
2814                {                {
2815                SCHECK_PARTIAL();                SCHECK_PARTIAL();
2816                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
2817                }                }
2818              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
2819              if (c > 255)              if (c > 255)
2820                {                {
2821                if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2822                }                }
2823              else              else
2824                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
               if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);  
               }  
2825              }              }
2826            }            }
2827          else          else
2828  #endif  #endif
2829          /* Not UTF-8 mode */          /* Not UTF mode */
2830            {            {
2831            for (fi = min;; fi++)            for (fi = min;; fi++)
2832              {              {
2833              RMATCH(eptr, ecode, offset_top, md, eptrb, RM17);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM17);
2834              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2835              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
2836              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
2837                {                {
2838                SCHECK_PARTIAL();                SCHECK_PARTIAL();
2839                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
2840                }                }
2841              c = *eptr++;              c = *eptr++;
2842              if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2843                if (c > 255)
2844                  {
2845                  if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2846                  }
2847                else
2848    #endif
2849                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2850              }              }
2851            }            }
2852          /* Control never gets here */          /* Control never gets here */
# Line 2839  for (;;) Line 2858  for (;;)
2858          {          {
2859          pp = eptr;          pp = eptr;
2860    
2861  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2862          /* UTF-8 mode */          if (utf)
         if (utf8)  
2863            {            {
2864            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2865              {              {
# Line 2857  for (;;) Line 2875  for (;;)
2875                if (op == OP_CLASS) break;                if (op == OP_CLASS) break;
2876                }                }
2877              else              else
2878                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
               if ((data[c/8] & (1 << (c&7))) == 0) break;  
               }  
2879              eptr += len;              eptr += len;
2880              }              }
2881            for (;;)            for (;;)
# Line 2872  for (;;) Line 2888  for (;;)
2888            }            }
2889          else          else
2890  #endif  #endif
2891            /* Not UTF-8 mode */            /* Not UTF mode */
2892            {            {
2893            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2894              {              {
# Line 2882  for (;;) Line 2898  for (;;)
2898                break;                break;
2899                }                }
2900              c = *eptr;              c = *eptr;
2901              if ((data[c/8] & (1 << (c&7))) == 0) break;  #ifndef COMPILE_PCRE8
2902                if (c > 255)
2903                  {
2904                  if (op == OP_CLASS) break;
2905                  }
2906                else
2907    #endif
2908                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
2909              eptr++;              eptr++;
2910              }              }
2911            while (eptr >= pp)            while (eptr >= pp)
# Line 2893  for (;;) Line 2916  for (;;)
2916              }              }
2917            }            }
2918    
2919          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2920          }          }
2921    #undef BYTE_MAP
2922        }        }
2923      /* Control never gets here */      /* Control never gets here */
2924    
# Line 2903  for (;;) Line 2927  for (;;)
2927      when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8      when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8
2928      mode, because Unicode properties are supported in non-UTF-8 mode. */      mode, because Unicode properties are supported in non-UTF-8 mode. */
2929    
2930  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2931      case OP_XCLASS:      case OP_XCLASS:
2932        {        {
2933        data = ecode + 1 + LINK_SIZE;                /* Save for matching */        data = ecode + 1 + LINK_SIZE;                /* Save for matching */
# Line 2928  for (;;) Line 2952  for (;;)
2952          case OP_CRMINRANGE:          case OP_CRMINRANGE:
2953          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
2954          min = GET2(ecode, 1);          min = GET2(ecode, 1);
2955          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
2956          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
2957          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
2958          break;          break;
2959    
2960          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2945  for (;;) Line 2969  for (;;)
2969          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
2970            {            {
2971            SCHECK_PARTIAL();            SCHECK_PARTIAL();
2972            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2973            }            }
2974          GETCHARINCTEST(c, eptr);          GETCHARINCTEST(c, eptr);
2975          if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);          if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
2976          }          }
2977    
2978        /* If max == min we can continue with the main loop without the        /* If max == min we can continue with the main loop without the
# Line 2965  for (;;) Line 2989  for (;;)
2989            {            {
2990            RMATCH(eptr, ecode, offset_top, md, eptrb, RM20);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM20);
2991            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2992            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
2993            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2994              {              {
2995              SCHECK_PARTIAL();              SCHECK_PARTIAL();
2996              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2997              }              }
2998            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
2999            if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);            if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
3000            }            }
3001          /* Control never gets here */          /* Control never gets here */
3002          }          }
# Line 2990  for (;;) Line 3014  for (;;)
3014              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3015              break;              break;
3016              }              }
3017    #ifdef SUPPORT_UTF
3018            GETCHARLENTEST(c, eptr, len);            GETCHARLENTEST(c, eptr, len);
3019            if (!_pcre_xclass(c, data)) break;  #else
3020              c = *eptr;
3021    #endif
3022              if (!PRIV(xclass)(c, data, utf)) break;
3023            eptr += len;            eptr += len;
3024            }            }
3025          for(;;)          for(;;)
# Line 2999  for (;;) Line 3027  for (;;)
3027            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
3028            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3029            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
3030            if (utf8) BACKCHAR(eptr);  #ifdef SUPPORT_UTF
3031              if (utf) BACKCHAR(eptr);
3032    #endif
3033            }            }
3034          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3035          }          }
3036    
3037        /* Control never gets here */        /* Control never gets here */
# Line 3011  for (;;) Line 3041  for (;;)
3041      /* Match a single character, casefully */      /* Match a single character, casefully */
3042    
3043      case OP_CHAR:      case OP_CHAR:
3044  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3045      if (utf8)      if (utf)
3046        {        {
3047        length = 1;        length = 1;
3048        ecode++;        ecode++;
# Line 3020  for (;;) Line 3050  for (;;)
3050        if (length > md->end_subject - eptr)        if (length > md->end_subject - eptr)
3051          {          {
3052          CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */          CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
3053          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3054          }          }
3055        while (length-- > 0) if (*ecode++ != *eptr++) MRRETURN(MATCH_NOMATCH);        while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);
3056        }        }
3057      else      else
3058  #endif  #endif
3059        /* Not UTF mode */
     /* Non-UTF-8 mode */  
3060        {        {
3061        if (md->end_subject - eptr < 1)        if (md->end_subject - eptr < 1)
3062          {          {
3063          SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */          SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
3064          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3065          }          }
3066        if (ecode[1] != *eptr++) MRRETURN(MATCH_NOMATCH);        if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);
3067        ecode += 2;        ecode += 2;
3068        }        }
3069      break;      break;
3070    
3071      /* Match a single character, caselessly */      /* Match a single character, caselessly. If we are at the end of the
3072        subject, give up immediately. */
3073    
3074      case OP_CHARI:      case OP_CHARI:
3075  #ifdef SUPPORT_UTF8      if (eptr >= md->end_subject)
3076      if (utf8)        {
3077          SCHECK_PARTIAL();
3078          RRETURN(MATCH_NOMATCH);
3079          }
3080    
3081    #ifdef SUPPORT_UTF
3082        if (utf)
3083        {        {
3084        length = 1;        length = 1;
3085        ecode++;        ecode++;
3086        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
3087    
       if (length > md->end_subject - eptr)  
         {  
         CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */  
         MRRETURN(MATCH_NOMATCH);  
         }  
   
3088        /* If the pattern character's value is < 128, we have only one byte, and        /* If the pattern character's value is < 128, we have only one byte, and
3089        can use the fast lookup table. */        we know that its other case must also be one byte long, so we can use the
3090          fast lookup table. We know that there is at least one byte left in the
3091          subject. */
3092    
3093        if (fc < 128)        if (fc < 128)
3094          {          {
3095          if (md->lcc[*ecode++] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);          if (md->lcc[fc]
3096                != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3097            ecode++;
3098            eptr++;
3099          }          }
3100    
3101        /* Otherwise we must pick up the subject character */        /* Otherwise we must pick up the subject character. Note that we cannot
3102          use the value of "length" to check for sufficient bytes left, because the
3103          other case of the character may have more or fewer bytes.  */
3104    
3105        else        else
3106          {          {
# Line 3079  for (;;) Line 3116  for (;;)
3116  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3117            if (dc != UCD_OTHERCASE(fc))            if (dc != UCD_OTHERCASE(fc))
3118  #endif  #endif
3119              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3120            }            }
3121          }          }
3122        }        }
3123      else      else
3124  #endif   /* SUPPORT_UTF8 */  #endif   /* SUPPORT_UTF */
3125    
3126      /* Non-UTF-8 mode */      /* Not UTF mode */
3127        {        {
3128        if (md->end_subject - eptr < 1)        if (TABLE_GET(ecode[1], md->lcc, ecode[1])
3129          {            != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3130          SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */        eptr++;
         MRRETURN(MATCH_NOMATCH);  
         }  
       if (md->lcc[ecode[1]] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);  
3131        ecode += 2;        ecode += 2;
3132        }        }
3133      break;      break;
# Line 3103  for (;;) Line 3137  for (;;)
3137      case OP_EXACT:      case OP_EXACT:
3138      case OP_EXACTI:      case OP_EXACTI:
3139      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3140      ecode += 3;      ecode += 1 + IMM2_SIZE;
3141      goto REPEATCHAR;      goto REPEATCHAR;
3142    
3143      case OP_POSUPTO:      case OP_POSUPTO:
# Line 3118  for (;;) Line 3152  for (;;)
3152      min = 0;      min = 0;
3153      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3154      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;
3155      ecode += 3;      ecode += 1 + IMM2_SIZE;
3156      goto REPEATCHAR;      goto REPEATCHAR;
3157    
3158      case OP_POSSTAR:      case OP_POSSTAR:
# Line 3166  for (;;) Line 3200  for (;;)
3200      /* Common code for all repeated single-character matches. */      /* Common code for all repeated single-character matches. */
3201    
3202      REPEATCHAR:      REPEATCHAR:
3203  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3204      if (utf8)      if (utf)
3205        {        {
3206        length = 1;        length = 1;
3207        charptr = ecode;        charptr = ecode;
# Line 3183  for (;;) Line 3217  for (;;)
3217          unsigned int othercase;          unsigned int othercase;
3218          if (op >= OP_STARI &&     /* Caseless */          if (op >= OP_STARI &&     /* Caseless */
3219              (othercase = UCD_OTHERCASE(fc)) != fc)              (othercase = UCD_OTHERCASE(fc)) != fc)
3220            oclength = _pcre_ord2utf8(othercase, occhars);            oclength = PRIV(ord2utf)(othercase, occhars);
3221          else oclength = 0;          else oclength = 0;
3222  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3223    
3224          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3225            {            {
3226            if (eptr <= md->end_subject - length &&            if (eptr <= md->end_subject - length &&
3227              memcmp(eptr, charptr, length) == 0) eptr += length;              memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3228  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3229            else if (oclength > 0 &&            else if (oclength > 0 &&
3230                     eptr <= md->end_subject - oclength &&                     eptr <= md->end_subject - oclength &&
3231                     memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                     memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3232  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3233            else            else
3234              {              {
3235              CHECK_PARTIAL();              CHECK_PARTIAL();
3236              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3237              }              }
3238            }            }
3239    
# Line 3211  for (;;) Line 3245  for (;;)
3245              {              {
3246              RMATCH(eptr, ecode, offset_top, md, eptrb, RM22);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM22);
3247              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3248              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3249              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3250                memcmp(eptr, charptr, length) == 0) eptr += length;                memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3251  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3252              else if (oclength > 0 &&              else if (oclength > 0 &&
3253                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3254                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3255  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3256              else              else
3257                {                {
3258                CHECK_PARTIAL();                CHECK_PARTIAL();
3259                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3260                }                }
3261              }              }
3262            /* Control never gets here */            /* Control never gets here */
# Line 3234  for (;;) Line 3268  for (;;)
3268            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3269              {              {
3270              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3271                  memcmp(eptr, charptr, length) == 0) eptr += length;                  memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3272  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3273              else if (oclength > 0 &&              else if (oclength > 0 &&
3274                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3275                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3276  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3277              else              else
3278                {                {
# Line 3253  for (;;) Line 3287  for (;;)
3287              {              {
3288              RMATCH(eptr, ecode, offset_top, md, eptrb, RM23);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM23);
3289              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3290              if (eptr == pp) { MRRETURN(MATCH_NOMATCH); }              if (eptr == pp) { RRETURN(MATCH_NOMATCH); }
3291  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3292              eptr--;              eptr--;
3293              BACKCHAR(eptr);              BACKCHAR(eptr);
# Line 3270  for (;;) Line 3304  for (;;)
3304        value of fc will always be < 128. */        value of fc will always be < 128. */
3305        }        }
3306      else      else
3307  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
3308          /* When not in UTF-8 mode, load a single-byte character. */
3309      /* When not in UTF-8 mode, load a single-byte character. */        fc = *ecode++;
   
     fc = *ecode++;  
3310    
3311      /* The value of fc at this point is always less than 256, though we may or      /* The value of fc at this point is always one character, though we may
3312      may not be in UTF-8 mode. The code is duplicated for the caseless and      or may not be in UTF mode. The code is duplicated for the caseless and
3313      caseful cases, for speed, since matching characters is likely to be quite      caseful cases, for speed, since matching characters is likely to be quite
3314      common. First, ensure the minimum number of matches are present. If min =      common. First, ensure the minimum number of matches are present. If min =
3315      max, continue at the same level without recursing. Otherwise, if      max, continue at the same level without recursing. Otherwise, if
# Line 3290  for (;;) Line 3322  for (;;)
3322    
3323      if (op >= OP_STARI)  /* Caseless */      if (op >= OP_STARI)  /* Caseless */
3324        {        {
3325        fc = md->lcc[fc];  #ifdef COMPILE_PCRE8
3326          /* fc must be < 128 if UTF is enabled. */
3327          foc = md->fcc[fc];
3328    #else
3329    #ifdef SUPPORT_UTF
3330    #ifdef SUPPORT_UCP
3331          if (utf && fc > 127)
3332            foc = UCD_OTHERCASE(fc);
3333    #else
3334          if (utf && fc > 127)
3335            foc = fc;
3336    #endif /* SUPPORT_UCP */
3337          else
3338    #endif /* SUPPORT_UTF */
3339            foc = TABLE_GET(fc, md->fcc, fc);
3340    #endif /* COMPILE_PCRE8 */
3341    
3342        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
3343          {          {
3344          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
3345            {            {
3346            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3347            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3348            }            }
3349          if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);          if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
3350            eptr++;
3351          }          }
3352        if (min == max) continue;        if (min == max) continue;
3353        if (minimize)        if (minimize)
# Line 3307  for (;;) Line 3356  for (;;)
3356            {            {
3357            RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);
3358            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3359            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
3360            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3361              {              {
3362              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3363              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3364              }              }
3365            if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);            if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
3366              eptr++;
3367            }            }
3368          /* Control never gets here */          /* Control never gets here */
3369          }          }
# Line 3327  for (;;) Line 3377  for (;;)
3377              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3378              break;              break;
3379              }              }
3380            if (fc != md->lcc[*eptr]) break;            if (fc != *eptr && foc != *eptr) break;
3381            eptr++;            eptr++;
3382            }            }
3383    
# Line 3339  for (;;) Line 3389  for (;;)
3389            eptr--;            eptr--;
3390            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3391            }            }
3392          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3393          }          }
3394        /* Control never gets here */        /* Control never gets here */
3395        }        }
# Line 3353  for (;;) Line 3403  for (;;)
3403          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
3404            {            {
3405            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3406            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3407            }            }
3408          if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);          if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
3409          }          }
3410    
3411        if (min == max) continue;        if (min == max) continue;
# Line 3366  for (;;) Line 3416  for (;;)
3416            {            {
3417            RMATCH(eptr, ecode, offset_top, md, eptrb, RM26);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM26);
3418            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3419            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
3420            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3421              {              {
3422              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3423              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3424              }              }
3425            if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);            if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
3426            }            }
3427          /* Control never gets here */          /* Control never gets here */
3428          }          }
# Line 3397  for (;;) Line 3447  for (;;)
3447            eptr--;            eptr--;
3448            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3449            }            }
3450          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3451          }          }
3452        }        }
3453      /* Control never gets here */      /* Control never gets here */
# Line 3410  for (;;) Line 3460  for (;;)
3460      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
3461        {        {
3462        SCHECK_PARTIAL();        SCHECK_PARTIAL();
3463        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
3464        }        }
3465      ecode++;      ecode++;
3466      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
3467      if (op == OP_NOTI)         /* The caseless case */      if (op == OP_NOTI)         /* The caseless case */
3468        {        {
3469  #ifdef SUPPORT_UTF8        register int ch, och;
3470        if (c < 256)        ch = *ecode++;
3471  #endif  #ifdef COMPILE_PCRE8
3472        c = md->lcc[c];        /* ch must be < 128 if UTF is enabled. */
3473        if (md->lcc[*ecode++] == c) MRRETURN(MATCH_NOMATCH);        och = md->fcc[ch];
3474    #else
3475    #ifdef SUPPORT_UTF
3476    #ifdef SUPPORT_UCP
3477          if (utf && ch > 127)
3478            och = UCD_OTHERCASE(ch);
3479    #else
3480          if (utf && ch > 127)
3481            och = ch;
3482    #endif /* SUPPORT_UCP */
3483          else
3484    #endif /* SUPPORT_UTF */
3485            och = TABLE_GET(ch, md->fcc, ch);
3486    #endif /* COMPILE_PCRE8 */
3487          if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
3488        }        }
3489      else    /* Caseful */      else    /* Caseful */
3490        {        {
3491        if (*ecode++ == c) MRRETURN(MATCH_NOMATCH);        if (*ecode++ == c) RRETURN(MATCH_NOMATCH);
3492        }        }
3493      break;      break;
3494    
# Line 3438  for (;;) Line 3502  for (;;)
3502      case OP_NOTEXACT:      case OP_NOTEXACT:
3503      case OP_NOTEXACTI:      case OP_NOTEXACTI:
3504      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3505      ecode += 3;      ecode += 1 + IMM2_SIZE;
3506      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3507    
3508      case OP_NOTUPTO:      case OP_NOTUPTO:
# Line 3448  for (;;) Line 3512  for (;;)
3512      min = 0;      min = 0;
3513      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3514      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;
3515      ecode += 3;      ecode += 1 + IMM2_SIZE;
3516      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3517    
3518      case OP_NOTPOSSTAR:      case OP_NOTPOSSTAR:
# Line 3480  for (;;) Line 3544  for (;;)
3544      possessive = TRUE;      possessive = TRUE;
3545      min = 0;      min = 0;
3546      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3547      ecode += 3;      ecode += 1 + IMM2_SIZE;
3548      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3549    
3550      case OP_NOTSTAR:      case OP_NOTSTAR:
# Line 3519  for (;;) Line 3583  for (;;)
3583    
3584      if (op >= OP_NOTSTARI)     /* Caseless */      if (op >= OP_NOTSTARI)     /* Caseless */
3585        {        {
3586        fc = md->lcc[fc];  #ifdef COMPILE_PCRE8
3587          /* fc must be < 128 if UTF is enabled. */
3588          foc = md->fcc[fc];
3589    #else
3590    #ifdef SUPPORT_UTF
3591    #ifdef SUPPORT_UCP
3592          if (utf && fc > 127)
3593            foc = UCD_OTHERCASE(fc);
3594    #else
3595          if (utf && fc > 127)
3596            foc = fc;
3597    #endif /* SUPPORT_UCP */
3598          else
3599    #endif /* SUPPORT_UTF */
3600            foc = TABLE_GET(fc, md->fcc, fc);
3601    #endif /* COMPILE_PCRE8 */
3602    
3603  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3604        /* UTF-8 mode */        if (utf)
       if (utf8)  
3605          {          {
3606          register unsigned int d;          register unsigned int d;
3607          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 3531  for (;;) Line 3609  for (;;)
3609            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3610              {              {
3611              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3612              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3613              }              }
3614            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3615            if (d < 256) d = md->lcc[d];            if (fc == d || foc == d) RRETURN(MATCH_NOMATCH);
           if (fc == d) MRRETURN(MATCH_NOMATCH);  
3616            }            }
3617          }          }
3618        else        else
3619  #endif  #endif
3620          /* Not UTF mode */
       /* Not UTF-8 mode */  
3621          {          {
3622          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3623            {            {
3624            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3625              {              {
3626              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3627              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3628              }              }
3629            if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);            if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3630              eptr++;
3631            }            }
3632          }          }
3633    
# Line 3558  for (;;) Line 3635  for (;;)
3635    
3636        if (minimize)        if (minimize)
3637          {          {
3638  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3639          /* UTF-8 mode */          if (utf)
         if (utf8)  
3640            {            {
3641            register unsigned int d;            register unsigned int d;
3642            for (fi = min;; fi++)            for (fi = min;; fi++)
3643              {              {
3644              RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);
3645              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3646              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3647              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3648                {                {
3649                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3650                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3651                }                }
3652              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3653              if (d < 256) d = md->lcc[d];              if (fc == d || foc == d) RRETURN(MATCH_NOMATCH);
             if (fc == d) MRRETURN(MATCH_NOMATCH);  
3654              }              }
3655            }            }
3656          else          else
3657  #endif  #endif
3658          /* Not UTF-8 mode */          /* Not UTF mode */
3659            {            {
3660            for (fi = min;; fi++)            for (fi = min;; fi++)
3661              {              {
3662              RMATCH(eptr, ecode, offset_top, md, eptrb, RM29);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM29);
3663              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3664              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3665              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3666                {                {
3667                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3668                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3669                }                }
3670              if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);              if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3671                eptr++;
3672              }              }
3673            }            }
3674          /* Control never gets here */          /* Control never gets here */
# Line 3604  for (;;) Line 3680  for (;;)
3680          {          {
3681          pp = eptr;          pp = eptr;
3682    
3683  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3684          /* UTF-8 mode */          if (utf)
         if (utf8)  
3685            {            {
3686            register unsigned int d;            register unsigned int d;
3687            for (i = min; i < max; i++)            for (i = min; i < max; i++)
# Line 3618  for (;;) Line 3693  for (;;)
3693                break;                break;
3694                }                }
3695              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3696              if (d < 256) d = md->lcc[d];              if (fc == d || foc == d) break;
             if (fc == d) break;  
3697              eptr += len;              eptr += len;
3698              }              }
3699          if (possessive) continue;          if (possessive) continue;
# Line 3633  for (;;) Line 3707  for (;;)
3707            }            }
3708          else          else
3709  #endif  #endif
3710          /* Not UTF-8 mode */          /* Not UTF mode */
3711            {            {
3712            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3713              {              {
# Line 3642  for (;;) Line 3716  for (;;)
3716                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3717                break;                break;
3718                }                }
3719              if (fc == md->lcc[*eptr]) break;              if (fc == *eptr || foc == *eptr) break;
3720              eptr++;              eptr++;
3721              }              }
3722            if (possessive) continue;            if (possessive) continue;
# Line 3654  for (;;) Line 3728  for (;;)
3728              }              }
3729            }            }
3730    
3731          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3732          }          }
3733        /* Control never gets here */        /* Control never gets here */
3734        }        }
# Line 3663  for (;;) Line 3737  for (;;)
3737    
3738      else      else
3739        {        {
3740  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3741        /* UTF-8 mode */        if (utf)
       if (utf8)  
3742          {          {
3743          register unsigned int d;          register unsigned int d;
3744          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 3673  for (;;) Line 3746  for (;;)
3746            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3747              {              {
3748              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3749              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3750              }              }
3751            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3752            if (fc == d) MRRETURN(MATCH_NOMATCH);            if (fc == d) RRETURN(MATCH_NOMATCH);
3753            }            }
3754          }          }
3755        else        else
3756  #endif  #endif
3757        /* Not UTF-8 mode */        /* Not UTF mode */
3758          {          {
3759          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3760            {            {
3761            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3762              {              {
3763              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3764              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3765              }              }
3766            if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);            if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
3767            }            }
3768          }          }
3769    
# Line 3698  for (;;) Line 3771  for (;;)
3771    
3772        if (minimize)        if (minimize)
3773          {          {
3774  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3775          /* UTF-8 mode */          if (utf)
         if (utf8)  
3776            {            {
3777            register unsigned int d;            register unsigned int d;
3778            for (fi = min;; fi++)            for (fi = min;; fi++)
3779              {              {
3780              RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);
3781              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3782              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3783              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3784                {                {
3785                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3786                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3787                }                }
3788              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3789              if (fc == d) MRRETURN(MATCH_NOMATCH);              if (fc == d) RRETURN(MATCH_NOMATCH);
3790              }              }
3791            }            }
3792          else          else
3793  #endif  #endif
3794          /* Not UTF-8 mode */          /* Not UTF mode */
3795            {            {
3796            for (fi = min;; fi++)            for (fi = min;; fi++)
3797              {              {
3798              RMATCH(eptr, ecode, offset_top, md, eptrb, RM33);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM33);
3799              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3800              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3801              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3802                {                {
3803                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3804                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3805                }                }
3806              if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);              if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
3807              }              }
3808            }            }
3809          /* Control never gets here */          /* Control never gets here */
# Line 3743  for (;;) Line 3815  for (;;)
3815          {          {
3816          pp = eptr;          pp = eptr;
3817    
3818  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3819          /* UTF-8 mode */          if (utf)
         if (utf8)  
3820            {            {
3821            register unsigned int d;            register unsigned int d;
3822            for (i = min; i < max; i++)            for (i = min; i < max; i++)
# Line 3771  for (;;) Line 3842  for (;;)
3842            }            }
3843          else          else
3844  #endif  #endif
3845          /* Not UTF-8 mode */          /* Not UTF mode */
3846            {            {
3847            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3848              {              {
# Line 3792  for (;;) Line 3863  for (;;)
3863              }              }
3864            }            }
3865    
3866          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3867          }          }
3868        }        }
3869      /* Control never gets here */      /* Control never gets here */
# Line 3804  for (;;) Line 3875  for (;;)
3875      case OP_TYPEEXACT:      case OP_TYPEEXACT:
3876      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3877      minimize = TRUE;      minimize = TRUE;
3878      ecode += 3;      ecode += 1 + IMM2_SIZE;
3879      goto REPEATTYPE;      goto REPEATTYPE;
3880    
3881      case OP_TYPEUPTO:      case OP_TYPEUPTO:
# Line 3812  for (;;) Line 3883  for (;;)
3883      min = 0;      min = 0;
3884      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3885      minimize = *ecode == OP_TYPEMINUPTO;      minimize = *ecode == OP_TYPEMINUPTO;
3886      ecode += 3;      ecode += 1 + IMM2_SIZE;
3887      goto REPEATTYPE;      goto REPEATTYPE;
3888    
3889      case OP_TYPEPOSSTAR:      case OP_TYPEPOSSTAR:
# Line 3840  for (;;) Line 3911  for (;;)
3911      possessive = TRUE;      possessive = TRUE;
3912      min = 0;      min = 0;
3913      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3914      ecode += 3;      ecode += 1 + IMM2_SIZE;
3915      goto REPEATTYPE;      goto REPEATTYPE;
3916    
3917      case OP_TYPESTAR:      case OP_TYPESTAR:
# Line 3886  for (;;) Line 3957  for (;;)
3957          switch(prop_type)          switch(prop_type)
3958            {            {
3959            case PT_ANY:            case PT_ANY:
3960            if (prop_fail_result) MRRETURN(MATCH_NOMATCH);            if (prop_fail_result) RRETURN(MATCH_NOMATCH);
3961            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3962              {              {
3963              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3964                {                {
3965                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3966                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3967                }                }
3968              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3969              }              }
# Line 3905  for (;;) Line 3976  for (;;)
3976              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3977                {                {
3978                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3979                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3980                }                }
3981              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3982              chartype = UCD_CHARTYPE(c);              chartype = UCD_CHARTYPE(c);
3983              if ((chartype == ucp_Lu ||              if ((chartype == ucp_Lu ||
3984                   chartype == ucp_Ll ||                   chartype == ucp_Ll ||
3985                   chartype == ucp_Lt) == prop_fail_result)                   chartype == ucp_Lt) == prop_fail_result)
3986                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3987              }              }
3988            break;            break;
3989    
# Line 3922  for (;;) Line 3993  for (;;)
3993              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3994                {                {
3995                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3996                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3997                }                }
3998              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3999              if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)              if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
4000                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4001              }              }
4002            break;            break;
4003    
# Line 3936  for (;;) Line 4007  for (;;)
4007              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4008                {                {
4009                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4010                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4011                }                }
4012              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4013              if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)              if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
4014                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4015              }              }
4016            break;            break;
4017    
# Line 3950  for (;;) Line 4021  for (;;)
4021              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4022                {                {
4023                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4024                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4025                }                }
4026              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4027              if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)              if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
4028                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4029              }              }
4030            break;            break;
4031    
# Line 3965  for (;;) Line 4036  for (;;)
4036              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4037                {                {
4038                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4039                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4040                }                }
4041              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4042              category = UCD_CATEGORY(c);              category = UCD_CATEGORY(c);
4043              if ((category == ucp_L || category == ucp_N) == prop_fail_result)              if ((category == ucp_L || category == ucp_N) == prop_fail_result)
4044                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4045              }              }
4046            break;            break;
4047    
# Line 3980  for (;;) Line 4051  for (;;)
4051              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4052                {                {
4053                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4054                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4055                }                }
4056              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4057              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4058                   c == CHAR_FF || c == CHAR_CR)                   c == CHAR_FF || c == CHAR_CR)
4059                     == prop_fail_result)                     == prop_fail_result)
4060                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4061              }              }
4062            break;            break;
4063    
# Line 3996  for (;;) Line 4067  for (;;)
4067              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4068                {                {
4069                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4070                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4071                }                }
4072              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4073              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4074                   c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)                   c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
4075                     == prop_fail_result)                     == prop_fail_result)
4076                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4077              }              }
4078            break;            break;
4079    
# Line 4013  for (;;) Line 4084  for (;;)
4084              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4085                {                {
4086                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4087                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4088                }                }
4089              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4090              category = UCD_CATEGORY(c);              category = UCD_CATEGORY(c);
4091              if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE)              if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE)
4092                     == prop_fail_result)                     == prop_fail_result)
4093                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4094              }              }
4095            break;            break;
4096    
# Line 4040  for (;;) Line 4111  for (;;)
4111            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4112              {              {
4113              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4114              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4115              }              }
4116            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
4117            if (UCD_CATEGORY(c) == ucp_M) MRRETURN(MATCH_NOMATCH);            if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
4118            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4119              {              {
4120              int len = 1;              int len = 1;
4121              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
4122              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
4123              eptr += len;              eptr += len;
4124              }              }
# Line 4059  for (;;) Line 4130  for (;;)
4130    
4131  /* Handle all other cases when the coding is UTF-8 */  /* Handle all other cases when the coding is UTF-8 */
4132    
4133  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4134        if (utf8) switch(ctype)        if (utf) switch(ctype)
4135          {          {
4136          case OP_ANY:          case OP_ANY:
4137          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 4068  for (;;) Line 4139  for (;;)
4139            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4140              {              {
4141              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4142              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4143              }              }
4144            if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4145            eptr++;            eptr++;
4146            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4147            }            }
4148          break;          break;
4149    
# Line 4082  for (;;) Line 4153  for (;;)
4153            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4154              {              {
4155              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4156              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4157              }              }
4158            eptr++;            eptr++;
4159            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4160            }            }
4161          break;          break;
4162    
4163          case OP_ANYBYTE:          case OP_ANYBYTE:
4164          if (eptr > md->end_subject - min) MRRETURN(MATCH_NOMATCH);          if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);
4165          eptr += min;          eptr += min;
4166          break;          break;
4167    
# Line 4100  for (;;) Line 4171  for (;;)
4171            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4172              {              {
4173              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4174              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4175              }              }
4176            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4177            switch(c)            switch(c)
4178              {              {
4179              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4180    
4181              case 0x000d:              case 0x000d:
4182              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
# Line 4119  for (;;) Line 4190  for (;;)
4190              case 0x0085:              case 0x0085:
4191              case 0x2028:              case 0x2028:
4192              case 0x2029:              case 0x2029:
4193              if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4194              break;              break;
4195              }              }
4196            }            }
# Line 4131  for (;;) Line 4202  for (;;)
4202            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4203              {              {
4204              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4205              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4206              }              }
4207            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4208            switch(c)            switch(c)
# Line 4156  for (;;) Line 4227  for (;;)
4227              case 0x202f:    /* NARROW NO-BREAK SPACE */              case 0x202f:    /* NARROW NO-BREAK SPACE */
4228              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4229              case 0x3000:    /* IDEOGRAPHIC SPACE */              case 0x3000:    /* IDEOGRAPHIC SPACE */
4230              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4231              }              }
4232            }            }
4233          break;          break;
# Line 4167  for (;;) Line 4238  for (;;)
4238            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4239              {              {
4240              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4241              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4242              }              }
4243            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4244            switch(c)            switch(c)
4245              {              {
4246              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4247              case 0x09:      /* HT */              case 0x09:      /* HT */
4248              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4249              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
# Line 4203  for (;;) Line 4274  for (;;)
4274            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4275              {              {
4276              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4277              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4278              }              }
4279            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4280            switch(c)            switch(c)
# Line 4216  for (;;) Line 4287  for (;;)
4287              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4288              case 0x2028:    /* LINE SEPARATOR */              case 0x2028:    /* LINE SEPARATOR */
4289              case 0x2029:    /* PARAGRAPH SEPARATOR */              case 0x2029:    /* PARAGRAPH SEPARATOR */
4290              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4291              }              }
4292            }            }
4293          break;          break;
# Line 4227  for (;;) Line 4298  for (;;)
4298            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4299              {              {
4300              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4301              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4302              }              }
4303            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4304            switch(c)            switch(c)
4305              {              {
4306              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4307              case 0x0a:      /* LF */              case 0x0a:      /* LF */
4308              case 0x0b:      /* VT */              case 0x0b:      /* VT */
4309              case 0x0c:      /* FF */              case 0x0c:      /* FF */
# Line 4251  for (;;) Line 4322  for (;;)
4322            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4323              {              {
4324              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4325              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4326              }              }
4327            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4328            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
4329              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4330            }            }
4331          break;          break;
4332    
# Line 4265  for (;;) Line 4336  for (;;)
4336            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4337              {              {
4338              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4339              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4340              }              }
4341            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_digit) == 0)
4342              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4343              eptr++;
4344            /* No need to skip more bytes - we know it's a 1-byte character */            /* No need to skip more bytes - we know it's a 1-byte character */
4345            }            }
4346          break;          break;
# Line 4279  for (;;) Line 4351  for (;;)
4351            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4352              {              {
4353              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4354              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4355              }              }
4356            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
4357              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4358            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4359              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4360            }            }
4361          break;          break;
4362    
# Line 4293  for (;;) Line 4366  for (;;)
4366            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4367              {              {
4368              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4369              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4370              }              }
4371            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_space) == 0)
4372              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4373              eptr++;
4374            /* No need to skip more bytes - we know it's a 1-byte character */            /* No need to skip more bytes - we know it's a 1-byte character */
4375            }            }
4376          break;          break;
# Line 4307  for (;;) Line 4381  for (;;)
4381            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4382              {              {
4383              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4384              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4385              }              }
4386            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
4387              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4388            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4389              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4390            }            }
4391          break;          break;
4392    
# Line 4321  for (;;) Line 4396  for (;;)
4396            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4397              {              {
4398              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4399              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4400              }              }
4401            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_word) == 0)
4402              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4403              eptr++;
4404            /* No need to skip more bytes - we know it's a 1-byte character */            /* No need to skip more bytes - we know it's a 1-byte character */
4405            }            }
4406          break;          break;
# Line 4334  for (;;) Line 4410  for (;;)
4410          }  /* End switch(ctype) */          }  /* End switch(ctype) */
4411    
4412        else        else
4413  #endif     /* SUPPORT_UTF8 */  #endif     /* SUPPORT_UTF */
4414    
4415        /* Code for the non-UTF-8 case for minimum matching of operators other        /* Code for the non-UTF-8 case for minimum matching of operators other
4416        than OP_PROP and OP_NOTPROP. */        than OP_PROP and OP_NOTPROP. */
# Line 4347  for (;;) Line 4423  for (;;)
4423            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4424              {              {
4425              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4426              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4427              }              }
4428            if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4429            eptr++;            eptr++;
4430            }            }
4431          break;          break;
# Line 4358  for (;;) Line 4434  for (;;)
4434          if (eptr > md->end_subject - min)          if (eptr > md->end_subject - min)
4435            {            {
4436            SCHECK_PARTIAL();            SCHECK_PARTIAL();
4437            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
4438            }            }
4439          eptr += min;          eptr += min;
4440          break;          break;
# Line 4367  for (;;) Line 4443  for (;;)
4443          if (eptr > md->end_subject - min)          if (eptr > md->end_subject - min)
4444            {            {
4445            SCHECK_PARTIAL();            SCHECK_PARTIAL();
4446            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
4447            }            }
4448          eptr += min;          eptr += min;
4449          break;          break;
# Line 4378  for (;;) Line 4454  for (;;)
4454            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4455              {              {
4456              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4457              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4458              }              }
4459            switch(*eptr++)            switch(*eptr++)
4460              {              {
4461              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4462    
4463              case 0x000d:              case 0x000d:
4464              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
# Line 4394  for (;;) Line 4470  for (;;)
4470              case 0x000b:              case 0x000b:
4471              case 0x000c:              case 0x000c:
4472              case 0x0085:              case 0x0085:
4473              if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4474              break;              break;
4475              }              }
4476            }            }
# Line 4406  for (;;) Line 4482  for (;;)
4482            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4483              {              {
4484              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4485              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4486              }              }
4487            switch(*eptr++)            switch(*eptr++)
4488              {              {
# Line 4414  for (;;) Line 4490  for (;;)
4490              case 0x09:      /* HT */              case 0x09:      /* HT */
4491              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4492              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
4493              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4494              }              }
4495            }            }
4496          break;          break;
# Line 4425  for (;;) Line 4501  for (;;)
4501            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4502              {              {
4503              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4504              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4505              }              }
4506            switch(*eptr++)            switch(*eptr++)
4507              {              {
4508              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4509              case 0x09:      /* HT */              case 0x09:      /* HT */
4510              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4511              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
# Line 4444  for (;;) Line 4520  for (;;)
4520            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4521              {              {
4522              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4523              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4524              }              }
4525            switch(*eptr++)            switch(*eptr++)
4526              {              {
# Line 4454  for (;;) Line 4530  for (;;)
4530              case 0x0c:      /* FF */              case 0x0c:      /* FF */
4531              case 0x0d:      /* CR */              case 0x0d:      /* CR */
4532              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4533              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4534              }              }
4535            }            }
4536          break;          break;
# Line 4465  for (;;) Line 4541  for (;;)
4541            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4542              {              {
4543              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4544              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4545              }              }
4546            switch(*eptr++)            switch(*eptr++)
4547              {              {
4548              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4549              case 0x0a:      /* LF */              case 0x0a:      /* LF */
4550              case 0x0b:      /* VT */              case 0x0b:      /* VT */
4551              case 0x0c:      /* FF */              case 0x0c:      /* FF */
# Line 4486  for (;;) Line 4562  for (;;)
4562            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4563              {              {
4564              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4565              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4566              }              }
4567            if ((md->ctypes[*eptr++] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0)
4568                RRETURN(MATCH_NOMATCH);
4569              eptr++;
4570            }            }
4571          break;          break;
4572    
# Line 4498  for (;;) Line 4576  for (;;)
4576            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4577              {              {
4578              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4579              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4580              }              }
4581            if ((md->ctypes[*eptr++] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0)
4582                RRETURN(MATCH_NOMATCH);
4583              eptr++;
4584            }            }
4585          break;          break;
4586    
# Line 4510  for (;;) Line 4590  for (;;)
4590            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4591              {              {
4592              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4593              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4594              }              }
4595            if ((md->ctypes[*eptr++] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0)
4596                RRETURN(MATCH_NOMATCH);
4597              eptr++;
4598            }            }
4599          break;          break;
4600    
# Line 4522  for (;;) Line 4604  for (;;)
4604            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4605              {              {
4606              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4607              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4608              }              }
4609            if ((md->ctypes[*eptr++] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0)
4610                RRETURN(MATCH_NOMATCH);
4611              eptr++;
4612            }            }
4613          break;          break;
4614    
# Line 4534  for (;;) Line 4618  for (;;)
4618            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4619              {              {
4620              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4621              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4622              }              }
4623            if ((md->ctypes[*eptr++] & ctype_word) != 0)            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0)
4624              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4625              eptr++;
4626            }            }
4627          break;          break;
4628    
# Line 4547  for (;;) Line 4632  for (;;)
4632            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4633              {              {
4634              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4635              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4636              }              }
4637            if ((md->ctypes[*eptr++] & ctype_word) == 0)            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0)
4638              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4639              eptr++;
4640            }            }
4641          break;          break;
4642    
# Line 4579  for (;;) Line 4665  for (;;)
4665              {              {
4666              RMATCH(eptr, ecode, offset_top, md, eptrb, RM36);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM36);
4667              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4668              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4669              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4670                {                {
4671                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4672                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4673                }                }
4674              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4675              if (prop_fail_result) MRRETURN(MATCH_NOMATCH);              if (prop_fail_result) RRETURN(MATCH_NOMATCH);
4676              }              }
4677            /* Control never gets here */            /* Control never gets here */
4678    
# Line 4596  for (;;) Line 4682  for (;;)
4682              int chartype;              int chartype;
4683              RMATCH(eptr, ecode, offset_top, md, eptrb, RM37);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM37);
4684              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4685              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4686              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4687                {                {
4688                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4689                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4690                }                }
4691              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4692              chartype = UCD_CHARTYPE(c);              chartype = UCD_CHARTYPE(c);
4693              if ((chartype == ucp_Lu ||              if ((chartype == ucp_Lu ||
4694                   chartype == ucp_Ll ||                   chartype == ucp_Ll ||
4695                   chartype == ucp_Lt) == prop_fail_result)                   chartype == ucp_Lt) == prop_fail_result)
4696                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4697              }              }
4698            /* Control never gets here */            /* Control never gets here */
4699    
# Line 4616  for (;;) Line 4702  for (;;)
4702              {              {
4703              RMATCH(eptr, ecode, offset_top, md, eptrb, RM38);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM38);
4704              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4705              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4706              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4707                {                {
4708                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4709                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4710                }                }
4711              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4712              if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)              if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
4713                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4714              }              }
4715            /* Control never gets here */            /* Control never gets here */
4716    
# Line 4633  for (;;) Line 4719  for (;;)
4719              {              {
4720              RMATCH(eptr, ecode, offset_top, md, eptrb, RM39);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM39);
4721              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4722              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4723              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4724                {                {
4725                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4726                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4727                }                }
4728              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4729              if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)              if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
4730                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4731              }              }
4732            /* Control never gets here */            /* Control never gets here */
4733    
# Line 4650  for (;;) Line 4736  for (;;)
4736              {              {
4737              RMATCH(eptr, ecode, offset_top, md, eptrb, RM40);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM40);
4738              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4739              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4740              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4741                {                {
4742                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4743                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4744                }                }
4745              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4746              if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)              if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
4747                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4748              }              }
4749            /* Control never gets here */            /* Control never gets here */
4750    
# Line 4668  for (;;) Line 4754  for (;;)
4754              int category;              int category;
4755              RMATCH(eptr, ecode, offset_top, md, eptrb, RM59);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM59);
4756              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4757              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4758              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4759                {                {
4760                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4761                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4762                }                }
4763              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4764              category = UCD_CATEGORY(c);              category = UCD_CATEGORY(c);
4765              if ((category == ucp_L || category == ucp_N) == prop_fail_result)              if ((category == ucp_L || category == ucp_N) == prop_fail_result)
4766                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4767              }              }
4768            /* Control never gets here */            /* Control never gets here */
4769    
# Line 4686  for (;;) Line 4772  for (;;)
4772              {              {
4773              RMATCH(eptr, ecode, offset_top, md, eptrb, RM60);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM60);
4774              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4775              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4776              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4777                {                {
4778                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4779                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4780                }                }
4781              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4782              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4783                   c == CHAR_FF || c == CHAR_CR)                   c == CHAR_FF || c == CHAR_CR)
4784                     == prop_fail_result)                     == prop_fail_result)
4785                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4786              }              }
4787            /* Control never gets here */            /* Control never gets here */
4788    
# Line 4705  for (;;) Line 4791  for (;;)
4791              {              {
4792              RMATCH(eptr, ecode, offset_top, md, eptrb, RM61);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM61);
4793              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4794              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4795              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4796                {                {
4797                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4798                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4799                }                }
4800              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4801              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4802                   c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)                   c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
4803                     == prop_fail_result)                     == prop_fail_result)
4804                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4805              }              }
4806            /* Control never gets here */            /* Control never gets here */
4807    
# Line 4725  for (;;) Line 4811  for (;;)
4811              int category;              int category;
4812              RMATCH(eptr, ecode, offset_top, md, eptrb, RM62);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM62);
4813              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4814              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4815              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4816                {                {
4817                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4818                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4819                }                }
4820              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4821              category = UCD_CATEGORY(c);              category = UCD_CATEGORY(c);
# Line 4737  for (;;) Line 4823  for (;;)
4823                   category == ucp_N ||                   category == ucp_N ||
4824                   c == CHAR_UNDERSCORE)                   c == CHAR_UNDERSCORE)
4825                     == prop_fail_result)                     == prop_fail_result)
4826                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4827              }              }
4828            /* Control never gets here */            /* Control never gets here */
4829    
# Line 4757  for (;;) Line 4843  for (;;)
4843            {            {
4844            RMATCH(eptr, ecode, offset_top, md, eptrb, RM41);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM41);
4845            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4846            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
4847            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4848              {              {
4849              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4850              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4851              }              }
4852            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
4853            if (UCD_CATEGORY(c) == ucp_M) MRRETURN(MATCH_NOMATCH);            if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
4854            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4855              {              {
4856              int len = 1;              int len = 1;
4857              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
4858              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
4859              eptr += len;              eptr += len;
4860              }              }
# Line 4777  for (;;) Line 4863  for (;;)
4863        else        else
4864  #endif     /* SUPPORT_UCP */  #endif     /* SUPPORT_UCP */
4865    
4866  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4867        /* UTF-8 mode */        if (utf)
       if (utf8)  
4868          {          {
4869          for (fi = min;; fi++)          for (fi = min;; fi++)
4870            {            {
4871            RMATCH(eptr, ecode, offset_top, md, eptrb, RM42);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM42);
4872            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4873            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
4874            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4875              {              {
4876              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4877              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4878              }              }
4879            if (ctype == OP_ANY && IS_NEWLINE(eptr))            if (ctype == OP_ANY && IS_NEWLINE(eptr))
4880              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4881            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4882            switch(ctype)            switch(ctype)
4883              {              {
# Line 4804  for (;;) Line 4889  for (;;)
4889              case OP_ANYNL:              case OP_ANYNL:
4890              switch(c)              switch(c)
4891                {                {
4892                default: MRRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
4893                case 0x000d:                case 0x000d:
4894                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
4895                break;                break;
# Line 4816  for (;;) Line 4901  for (;;)
4901                case 0x0085:                case 0x0085:
4902                case 0x2028:                case 0x2028:
4903                case 0x2029:                case 0x2029:
4904                if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4905                break;                break;
4906                }                }
4907              break;              break;
# Line 4844  for (;;) Line 4929  for (;;)
4929                case 0x202f:    /* NARROW NO-BREAK SPACE */                case 0x202f:    /* NARROW NO-BREAK SPACE */
4930                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4931                case 0x3000:    /* IDEOGRAPHIC SPACE */                case 0x3000:    /* IDEOGRAPHIC SPACE */
4932                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4933                }                }
4934              break;              break;
4935    
4936              case OP_HSPACE:              case OP_HSPACE:
4937              switch(c)              switch(c)
4938                {                {
4939                default: MRRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
4940                case 0x09:      /* HT */                case 0x09:      /* HT */
4941                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
4942                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
# Line 4886  for (;;) Line 4971  for (;;)
4971                case 0x85:      /* NEL */                case 0x85:      /* NEL */
4972                case 0x2028:    /* LINE SEPARATOR */                case 0x2028:    /* LINE SEPARATOR */
4973                case 0x2029:    /* PARAGRAPH SEPARATOR */                case 0x2029:    /* PARAGRAPH SEPARATOR */
4974                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4975                }                }
4976              break;              break;
4977    
4978              case OP_VSPACE:              case OP_VSPACE:
4979              switch(c)              switch(c)
4980                {                {
4981                default: MRRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
4982                case 0x0a:      /* LF */                case 0x0a:      /* LF */
4983                case 0x0b:      /* VT */                case 0x0b:      /* VT */
4984                case 0x0c:      /* FF */                case 0x0c:      /* FF */
# Line 4907  for (;;) Line 4992  for (;;)
4992    
4993              case OP_NOT_DIGIT:              case OP_NOT_DIGIT:
4994              if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)              if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)
4995                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4996              break;              break;
4997    
4998              case OP_DIGIT:              case OP_DIGIT:
4999              if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)
5000                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5001              break;              break;
5002    
5003              case OP_NOT_WHITESPACE:              case OP_NOT_WHITESPACE:
5004              if (c < 256 && (md->ctypes[c] & ctype_space) != 0)              if (c < 256 && (md->ctypes[c] & ctype_space) != 0)
5005                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5006              break;              break;
5007    
5008              case OP_WHITESPACE:              case OP_WHITESPACE:
5009              if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
5010                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5011              break;              break;
5012    
5013              case OP_NOT_WORDCHAR:              case OP_NOT_WORDCHAR:
5014              if (c < 256 && (md->ctypes[c] & ctype_word) != 0)              if (c < 256 && (md->ctypes[c] & ctype_word) != 0)
5015                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5016              break;              break;
5017    
5018              case OP_WORDCHAR:              case OP_WORDCHAR:
5019              if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)
5020                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5021              break;              break;
5022    
5023              default:              default:
# Line 4942  for (;;) Line 5027  for (;;)
5027          }          }
5028        else        else
5029  #endif  #endif
5030        /* Not UTF-8 mode */        /* Not UTF mode */
5031          {          {
5032          for (fi = min;; fi++)          for (fi = min;; fi++)
5033            {            {
5034            RMATCH(eptr, ecode, offset_top, md, eptrb, RM43);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM43);
5035            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5036            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
5037            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
5038              {              {
5039              SCHECK_PARTIAL();              SCHECK_PARTIAL();
5040              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
5041              }              }
5042