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

Diff of /code/trunk/pcre_exec.c

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

revision 835 by ph10, Wed Dec 28 16:10:09 2011 UTC revision 836 by ph10, Wed Dec 28 17:16:11 2011 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2011 University of Cambridge             Copyright (c) 1997-2012 University of Cambridge
10    
11  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
12  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 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.
# Line 816  for (;;) Line 824  for (;;)
824        if (rrc == MATCH_MATCH)  /* Note: _not_ MATCH_ACCEPT */        if (rrc == MATCH_MATCH)  /* Note: _not_ MATCH_ACCEPT */
825          {          {
826          mstart = md->start_match_ptr;          mstart = md->start_match_ptr;
         markptr = md->mark;  
827          break;          break;
828          }          }
829        if (rrc == MATCH_THEN)        if (rrc == MATCH_THEN)
# Line 916  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    
# Line 954  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 1004  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
# Line 1028  for (;;) Line 1034  for (;;)
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 1042  for (;;) Line 1048  for (;;)
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 1071  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 1094  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 1130  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 1162  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 1217  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 1232  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 1262  for (;;) Line 1266  for (;;)
1266    
1267          if (!condition && condcode == OP_NRREF)          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 1275  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 1295  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 1308  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 1325  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 1339  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 1361  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 1376  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 1468  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 1488  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 1497  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 1528  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    
# Line 1540  for (;;) Line 1543  for (;;)
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 1570  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);
# Line 1596  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 1614  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 1628  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 1643  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 1703  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 1718  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 1727  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 1745  for (;;) Line 1748  for (;;)
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 1757  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 1838  for (;;) Line 1841  for (;;)
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 1980  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 2018  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 2031  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 2039  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 2050  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 2069  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 2142  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 2165  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 2200  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 2210  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 2227  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 2244  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 2261  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 2278  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 2295  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 2312  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 2331  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 2341  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 2366  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 2375  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 2409  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 2422  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 2431  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 2458  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 2467  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 2539  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 2567  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 2607  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 */
2630        }        }
2631    
2632      /* Handle repeated back references. If the length of the reference is      /* Handle repeated back references. If the length of the reference is
2633      zero, just continue with the main loop. */      zero, just continue with the main loop. If the length is negative, it
2634        means the reference is unset in non-Java-compatible mode. If the minimum is
2635        zero, we can continue at the same level without recursion. For any other
2636        minimum, carrying on will result in NOMATCH. */
2637    
2638      if (length == 0) continue;      if (length == 0) continue;
2639        if (length < 0 && min == 0) continue;
2640    
2641      /* First, ensure the minimum number of matches are present. We get back      /* First, ensure the minimum number of matches are present. We get back
2642      the length of the reference string explicitly rather than passing the      the length of the reference string explicitly rather than passing the
# Line 2637  for (;;) Line 2648  for (;;)
2648        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2649          {          {
2650          CHECK_PARTIAL();          CHECK_PARTIAL();
2651          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2652          }          }
2653        eptr += slength;        eptr += slength;
2654        }        }
# Line 2656  for (;;) Line 2667  for (;;)
2667          int slength;          int slength;
2668          RMATCH(eptr, ecode, offset_top, md, eptrb, RM14);          RMATCH(eptr, ecode, offset_top, md, eptrb, RM14);
2669          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2670          if (fi >= max) MRRETURN(MATCH_NOMATCH);          if (fi >= max) RRETURN(MATCH_NOMATCH);
2671          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2672            {            {
2673            CHECK_PARTIAL();            CHECK_PARTIAL();
2674            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2675            }            }
2676          eptr += slength;          eptr += slength;
2677          }          }
# Line 2688  for (;;) Line 2699  for (;;)
2699          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2700          eptr -= length;          eptr -= length;
2701          }          }
2702        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2703        }        }
2704      /* Control never gets here */      /* Control never gets here */
2705    
# Line 2706  for (;;) Line 2717  for (;;)
2717      case OP_NCLASS:      case OP_NCLASS:
2718      case OP_CLASS:      case OP_CLASS:
2719        {        {
2720          /* The data variable is saved across frames, so the byte map needs to
2721          be stored there. */
2722    #define BYTE_MAP ((pcre_uint8 *)data)
2723        data = ecode + 1;                /* Save for matching */        data = ecode + 1;                /* Save for matching */
2724        ecode += 33;                     /* Advance past the item */        ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */
2725    
2726        switch (*ecode)        switch (*ecode)
2727          {          {
# Line 2728  for (;;) Line 2742  for (;;)
2742          case OP_CRMINRANGE:          case OP_CRMINRANGE:
2743          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
2744          min = GET2(ecode, 1);          min = GET2(ecode, 1);
2745          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
2746          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
2747          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
2748          break;          break;
2749    
2750          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2740  for (;;) Line 2754  for (;;)
2754    
2755        /* First, ensure the minimum number of matches are present. */        /* First, ensure the minimum number of matches are present. */
2756    
2757  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2758        /* UTF-8 mode */        if (utf)
       if (utf8)  
2759          {          {
2760          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2761            {            {
2762            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2763              {              {
2764              SCHECK_PARTIAL();              SCHECK_PARTIAL();
2765              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2766              }              }
2767            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
2768            if (c > 255)            if (c > 255)
2769              {              {
2770              if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2771              }              }
2772            else            else
2773              {              if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
             if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);  
             }  
2774            }            }
2775          }          }
2776        else        else
2777  #endif  #endif
2778        /* Not UTF-8 mode */        /* Not UTF mode */
2779          {          {
2780          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2781            {            {
2782            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2783              {              {
2784              SCHECK_PARTIAL();              SCHECK_PARTIAL();
2785              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2786              }              }
2787            c = *eptr++;            c = *eptr++;
2788            if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2789              if (c > 255)
2790                {
2791                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2792                }
2793              else
2794    #endif
2795                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2796            }            }
2797          }          }
2798    
# Line 2788  for (;;) Line 2806  for (;;)
2806    
2807        if (minimize)        if (minimize)
2808          {          {
2809  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2810          /* UTF-8 mode */          if (utf)
         if (utf8)  
2811            {            {
2812            for (fi = min;; fi++)            for (fi = min;; fi++)
2813              {              {
2814              RMATCH(eptr, ecode, offset_top, md, eptrb, RM16);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM16);
2815              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2816              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
2817              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
2818                {                {
2819                SCHECK_PARTIAL();                SCHECK_PARTIAL();
2820                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
2821                }                }
2822              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
2823              if (c > 255)              if (c > 255)
2824                {                {
2825                if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2826                }                }
2827              else              else
2828                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
               if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);  
               }  
2829              }              }
2830            }            }
2831          else          else
2832  #endif  #endif
2833          /* Not UTF-8 mode */          /* Not UTF mode */
2834            {            {
2835            for (fi = min;; fi++)            for (fi = min;; fi++)
2836              {              {
2837              RMATCH(eptr, ecode, offset_top, md, eptrb, RM17);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM17);
2838              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2839              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
2840              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
2841                {                {
2842                SCHECK_PARTIAL();                SCHECK_PARTIAL();
2843                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
2844                }                }
2845              c = *eptr++;              c = *eptr++;
2846              if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2847                if (c > 255)
2848                  {
2849                  if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2850                  }
2851                else
2852    #endif
2853                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2854              }              }
2855            }            }
2856          /* Control never gets here */          /* Control never gets here */
# Line 2840  for (;;) Line 2862  for (;;)
2862          {          {
2863          pp = eptr;          pp = eptr;
2864    
2865  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2866          /* UTF-8 mode */          if (utf)
         if (utf8)  
2867            {            {
2868            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2869              {              {
# Line 2858  for (;;) Line 2879  for (;;)
2879                if (op == OP_CLASS) break;                if (op == OP_CLASS) break;
2880                }                }
2881              else              else
2882                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
               if ((data[c/8] & (1 << (c&7))) == 0) break;  
               }  
2883              eptr += len;              eptr += len;
2884              }              }
2885            for (;;)            for (;;)
# Line 2873  for (;;) Line 2892  for (;;)
2892            }            }
2893          else          else
2894  #endif  #endif
2895            /* Not UTF-8 mode */            /* Not UTF mode */
2896            {            {
2897            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2898              {              {
# Line 2883  for (;;) Line 2902  for (;;)
2902                break;                break;
2903                }                }
2904              c = *eptr;              c = *eptr;
2905              if ((data[c/8] & (1 << (c&7))) == 0) break;  #ifndef COMPILE_PCRE8
2906                if (c > 255)
2907                  {
2908                  if (op == OP_CLASS) break;
2909                  }
2910                else
2911    #endif
2912                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
2913              eptr++;              eptr++;
2914              }              }
2915            while (eptr >= pp)            while (eptr >= pp)
# Line 2894  for (;;) Line 2920  for (;;)
2920              }              }
2921            }            }
2922    
2923          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2924          }          }
2925    #undef BYTE_MAP
2926        }        }
2927      /* Control never gets here */      /* Control never gets here */
2928    
# Line 2904  for (;;) Line 2931  for (;;)
2931      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
2932      mode, because Unicode properties are supported in non-UTF-8 mode. */      mode, because Unicode properties are supported in non-UTF-8 mode. */
2933    
2934  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2935      case OP_XCLASS:      case OP_XCLASS:
2936        {        {
2937        data = ecode + 1 + LINK_SIZE;                /* Save for matching */        data = ecode + 1 + LINK_SIZE;                /* Save for matching */
# Line 2929  for (;;) Line 2956  for (;;)
2956          case OP_CRMINRANGE:          case OP_CRMINRANGE:
2957          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
2958          min = GET2(ecode, 1);          min = GET2(ecode, 1);
2959          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
2960          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
2961          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
2962          break;          break;
2963    
2964          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2946  for (;;) Line 2973  for (;;)
2973          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
2974            {            {
2975            SCHECK_PARTIAL();            SCHECK_PARTIAL();
2976            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2977            }            }
2978          GETCHARINCTEST(c, eptr);          GETCHARINCTEST(c, eptr);
2979          if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);          if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
2980          }          }
2981    
2982        /* 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 2966  for (;;) Line 2993  for (;;)
2993            {            {
2994            RMATCH(eptr, ecode, offset_top, md, eptrb, RM20);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM20);
2995            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2996            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
2997            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2998              {              {
2999              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3000              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3001              }              }
3002            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
3003            if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);            if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
3004            }            }
3005          /* Control never gets here */          /* Control never gets here */
3006          }          }
# Line 2991  for (;;) Line 3018  for (;;)
3018              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3019              break;              break;
3020              }              }
3021    #ifdef SUPPORT_UTF
3022            GETCHARLENTEST(c, eptr, len);            GETCHARLENTEST(c, eptr, len);
3023            if (!_pcre_xclass(c, data)) break;  #else
3024              c = *eptr;
3025    #endif
3026              if (!PRIV(xclass)(c, data, utf)) break;
3027            eptr += len;            eptr += len;
3028            }            }
3029          for(;;)          for(;;)
# Line 3000  for (;;) Line 3031  for (;;)
3031            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
3032            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3033            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
3034            if (utf8) BACKCHAR(eptr);  #ifdef SUPPORT_UTF
3035              if (utf) BACKCHAR(eptr);
3036    #endif
3037            }            }
3038          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3039          }          }
3040    
3041        /* Control never gets here */        /* Control never gets here */
# Line 3012  for (;;) Line 3045  for (;;)
3045      /* Match a single character, casefully */      /* Match a single character, casefully */
3046    
3047      case OP_CHAR:      case OP_CHAR:
3048  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3049      if (utf8)      if (utf)
3050        {        {
3051        length = 1;        length = 1;
3052        ecode++;        ecode++;
# Line 3021  for (;;) Line 3054  for (;;)
3054        if (length > md->end_subject - eptr)        if (length > md->end_subject - eptr)
3055          {          {
3056          CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */          CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
3057          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3058          }          }
3059        while (length-- > 0) if (*ecode++ != *eptr++) MRRETURN(MATCH_NOMATCH);        while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);
3060        }        }
3061      else      else
3062  #endif  #endif
3063        /* Not UTF mode */
     /* Non-UTF-8 mode */  
3064        {        {
3065        if (md->end_subject - eptr < 1)        if (md->end_subject - eptr < 1)
3066          {          {
3067          SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */          SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
3068          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3069          }          }
3070        if (ecode[1] != *eptr++) MRRETURN(MATCH_NOMATCH);        if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);
3071        ecode += 2;        ecode += 2;
3072        }        }
3073      break;      break;
3074    
3075      /* Match a single character, caselessly */      /* Match a single character, caselessly. If we are at the end of the
3076        subject, give up immediately. */
3077    
3078      case OP_CHARI:      case OP_CHARI:
3079  #ifdef SUPPORT_UTF8      if (eptr >= md->end_subject)
3080      if (utf8)        {
3081          SCHECK_PARTIAL();
3082          RRETURN(MATCH_NOMATCH);
3083          }
3084    
3085    #ifdef SUPPORT_UTF
3086        if (utf)
3087        {        {
3088        length = 1;        length = 1;
3089        ecode++;        ecode++;
3090        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
3091    
       if (length > md->end_subject - eptr)  
         {  
         CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */  
         MRRETURN(MATCH_NOMATCH);  
         }  
   
3092        /* 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
3093        can use the fast lookup table. */        we know that its other case must also be one byte long, so we can use the
3094          fast lookup table. We know that there is at least one byte left in the
3095          subject. */
3096    
3097        if (fc < 128)        if (fc < 128)
3098          {          {
3099          if (md->lcc[*ecode++] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);          if (md->lcc[fc]
3100                != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3101            ecode++;
3102            eptr++;
3103          }          }
3104    
3105        /* Otherwise we must pick up the subject character */        /* Otherwise we must pick up the subject character. Note that we cannot
3106          use the value of "length" to check for sufficient bytes left, because the
3107          other case of the character may have more or fewer bytes.  */
3108    
3109        else        else
3110          {          {
# Line 3080  for (;;) Line 3120  for (;;)
3120  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3121            if (dc != UCD_OTHERCASE(fc))            if (dc != UCD_OTHERCASE(fc))
3122  #endif  #endif
3123              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3124            }            }
3125          }          }
3126        }        }
3127      else      else
3128  #endif   /* SUPPORT_UTF8 */  #endif   /* SUPPORT_UTF */
3129    
3130      /* Non-UTF-8 mode */      /* Not UTF mode */
3131        {        {
3132        if (md->end_subject - eptr < 1)        if (TABLE_GET(ecode[1], md->lcc, ecode[1])
3133          {            != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3134          SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */        eptr++;
         MRRETURN(MATCH_NOMATCH);  
         }  
       if (md->lcc[ecode[1]] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);  
3135        ecode += 2;        ecode += 2;
3136        }        }
3137      break;      break;
# Line 3104  for (;;) Line 3141  for (;;)
3141      case OP_EXACT:      case OP_EXACT:
3142      case OP_EXACTI:      case OP_EXACTI:
3143      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3144      ecode += 3;      ecode += 1 + IMM2_SIZE;
3145      goto REPEATCHAR;      goto REPEATCHAR;
3146    
3147      case OP_POSUPTO:      case OP_POSUPTO:
# Line 3119  for (;;) Line 3156  for (;;)
3156      min = 0;      min = 0;
3157      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3158      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;
3159      ecode += 3;      ecode += 1 + IMM2_SIZE;
3160      goto REPEATCHAR;      goto REPEATCHAR;
3161    
3162      case OP_POSSTAR:      case OP_POSSTAR:
# Line 3167  for (;;) Line 3204  for (;;)
3204      /* Common code for all repeated single-character matches. */      /* Common code for all repeated single-character matches. */
3205    
3206      REPEATCHAR:      REPEATCHAR:
3207  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3208      if (utf8)      if (utf)
3209        {        {
3210        length = 1;        length = 1;
3211        charptr = ecode;        charptr = ecode;
# Line 3184  for (;;) Line 3221  for (;;)
3221          unsigned int othercase;          unsigned int othercase;
3222          if (op >= OP_STARI &&     /* Caseless */          if (op >= OP_STARI &&     /* Caseless */
3223              (othercase = UCD_OTHERCASE(fc)) != fc)              (othercase = UCD_OTHERCASE(fc)) != fc)
3224            oclength = _pcre_ord2utf8(othercase, occhars);            oclength = PRIV(ord2utf)(othercase, occhars);
3225          else oclength = 0;          else oclength = 0;
3226  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3227    
3228          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3229            {            {
3230            if (eptr <= md->end_subject - length &&            if (eptr <= md->end_subject - length &&
3231              memcmp(eptr, charptr, length) == 0) eptr += length;              memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3232  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3233            else if (oclength > 0 &&            else if (oclength > 0 &&
3234                     eptr <= md->end_subject - oclength &&                     eptr <= md->end_subject - oclength &&
3235                     memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                     memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3236  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3237            else            else
3238              {              {
3239              CHECK_PARTIAL();              CHECK_PARTIAL();
3240              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3241              }              }
3242            }            }
3243    
# Line 3212  for (;;) Line 3249  for (;;)
3249              {              {
3250              RMATCH(eptr, ecode, offset_top, md, eptrb, RM22);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM22);
3251              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3252              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3253              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3254                memcmp(eptr, charptr, length) == 0) eptr += length;                memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3255  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3256              else if (oclength > 0 &&              else if (oclength > 0 &&
3257                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3258                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3259  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3260              else              else
3261                {                {
3262                CHECK_PARTIAL();                CHECK_PARTIAL();
3263                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3264                }                }
3265              }              }
3266            /* Control never gets here */            /* Control never gets here */
# Line 3235  for (;;) Line 3272  for (;;)
3272            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3273              {              {
3274              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3275                  memcmp(eptr, charptr, length) == 0) eptr += length;                  memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3276  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3277              else if (oclength > 0 &&              else if (oclength > 0 &&
3278                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3279                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3280  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3281              else              else
3282                {                {
# Line 3254  for (;;) Line 3291  for (;;)
3291              {              {
3292              RMATCH(eptr, ecode, offset_top, md, eptrb, RM23);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM23);
3293              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3294              if (eptr == pp) { MRRETURN(MATCH_NOMATCH); }              if (eptr == pp) { RRETURN(MATCH_NOMATCH); }
3295  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3296              eptr--;              eptr--;
3297              BACKCHAR(eptr);              BACKCHAR(eptr);
# Line 3271  for (;;) Line 3308  for (;;)
3308        value of fc will always be < 128. */        value of fc will always be < 128. */
3309        }        }
3310      else      else
3311  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
3312          /* When not in UTF-8 mode, load a single-byte character. */
3313      /* When not in UTF-8 mode, load a single-byte character. */        fc = *ecode++;
3314    
3315      fc = *ecode++;      /* The value of fc at this point is always one character, though we may
3316        or may not be in UTF mode. The code is duplicated for the caseless and
     /* The value of fc at this point is always less than 256, though we may or  
     may not be in UTF-8 mode. The code is duplicated for the caseless and  
3317      caseful cases, for speed, since matching characters is likely to be quite      caseful cases, for speed, since matching characters is likely to be quite
3318      common. First, ensure the minimum number of matches are present. If min =      common. First, ensure the minimum number of matches are present. If min =
3319      max, continue at the same level without recursing. Otherwise, if      max, continue at the same level without recursing. Otherwise, if
# Line 3291  for (;;) Line 3326  for (;;)
3326    
3327      if (op >= OP_STARI)  /* Caseless */      if (op >= OP_STARI)  /* Caseless */
3328        {        {
3329        fc = md->lcc[fc];  #ifdef COMPILE_PCRE8
3330          /* fc must be < 128 if UTF is enabled. */
3331          foc = md->fcc[fc];
3332    #else
3333    #ifdef SUPPORT_UTF
3334    #ifdef SUPPORT_UCP
3335          if (utf && fc > 127)
3336            foc = UCD_OTHERCASE(fc);
3337    #else
3338          if (utf && fc > 127)
3339            foc = fc;
3340    #endif /* SUPPORT_UCP */
3341          else
3342    #endif /* SUPPORT_UTF */
3343            foc = TABLE_GET(fc, md->fcc, fc);
3344    #endif /* COMPILE_PCRE8 */
3345    
3346        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
3347          {          {
3348          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
3349            {            {
3350            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3351            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3352            }            }
3353          if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);          if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
3354            eptr++;
3355          }          }
3356        if (min == max) continue;        if (min == max) continue;
3357        if (minimize)        if (minimize)
# Line 3308  for (;;) Line 3360  for (;;)
3360            {            {
3361            RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);
3362            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3363            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
3364            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3365              {              {
3366              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3367              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3368              }              }
3369            if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);            if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
3370              eptr++;
3371            }            }
3372          /* Control never gets here */          /* Control never gets here */
3373          }          }
# Line 3328  for (;;) Line 3381  for (;;)
3381              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3382              break;              break;
3383              }              }
3384            if (fc != md->lcc[*eptr]) break;            if (fc != *eptr && foc != *eptr) break;
3385            eptr++;            eptr++;
3386            }            }
3387    
# Line 3340  for (;;) Line 3393  for (;;)
3393            eptr--;            eptr--;
3394            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3395            }            }
3396          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3397          }          }
3398        /* Control never gets here */        /* Control never gets here */
3399        }        }
# Line 3354  for (;;) Line 3407  for (;;)
3407          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
3408            {            {
3409            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3410            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3411            }            }
3412          if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);          if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
3413          }          }
3414    
3415        if (min == max) continue;        if (min == max) continue;
# Line 3367  for (;;) Line 3420  for (;;)
3420            {            {
3421            RMATCH(eptr, ecode, offset_top, md, eptrb, RM26);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM26);
3422            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3423            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
3424            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3425              {              {
3426              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3427              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3428              }              }
3429            if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);            if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
3430            }            }
3431          /* Control never gets here */          /* Control never gets here */
3432          }          }
# Line 3398  for (;;) Line 3451  for (;;)
3451            eptr--;            eptr--;
3452            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3453            }            }
3454          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3455          }          }
3456        }        }
3457      /* Control never gets here */      /* Control never gets here */
# Line 3411  for (;;) Line 3464  for (;;)
3464      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
3465        {        {
3466        SCHECK_PARTIAL();        SCHECK_PARTIAL();
3467        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
3468        }        }
3469      ecode++;      ecode++;
3470      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
3471      if (op == OP_NOTI)         /* The caseless case */      if (op == OP_NOTI)         /* The caseless case */
3472        {        {
3473  #ifdef SUPPORT_UTF8        register int ch, och;
3474        if (c < 256)        ch = *ecode++;
3475  #endif  #ifdef COMPILE_PCRE8
3476        c = md->lcc[c];        /* ch must be < 128 if UTF is enabled. */
3477        if (md->lcc[*ecode++] == c) MRRETURN(MATCH_NOMATCH);        och = md->fcc[ch];
3478    #else
3479    #ifdef SUPPORT_UTF
3480    #ifdef SUPPORT_UCP
3481          if (utf && ch > 127)
3482            och = UCD_OTHERCASE(ch);
3483    #else
3484          if (utf && ch > 127)
3485            och = ch;
3486    #endif /* SUPPORT_UCP */
3487          else
3488    #endif /* SUPPORT_UTF */
3489            och = TABLE_GET(ch, md->fcc, ch);
3490    #endif /* COMPILE_PCRE8 */
3491          if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
3492        }        }
3493      else    /* Caseful */      else    /* Caseful */
3494        {        {
3495        if (*ecode++ == c) MRRETURN(MATCH_NOMATCH);        if (*ecode++ == c) RRETURN(MATCH_NOMATCH);
3496        }        }
3497      break;      break;
3498    
# Line 3439  for (;;) Line 3506  for (;;)
3506      case OP_NOTEXACT:      case OP_NOTEXACT:
3507      case OP_NOTEXACTI:      case OP_NOTEXACTI:
3508      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3509      ecode += 3;      ecode += 1 + IMM2_SIZE;
3510      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3511    
3512      case OP_NOTUPTO:      case OP_NOTUPTO:
# Line 3449  for (;;) Line 3516  for (;;)
3516      min = 0;      min = 0;
3517      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3518      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;
3519      ecode += 3;      ecode += 1 + IMM2_SIZE;
3520      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3521    
3522      case OP_NOTPOSSTAR:      case OP_NOTPOSSTAR:
# Line 3481  for (;;) Line 3548  for (;;)
3548      possessive = TRUE;      possessive = TRUE;
3549      min = 0;      min = 0;
3550      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3551      ecode += 3;      ecode += 1 + IMM2_SIZE;
3552      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3553    
3554      case OP_NOTSTAR:      case OP_NOTSTAR:
# Line 3520  for (;;) Line 3587  for (;;)
3587    
3588      if (op >= OP_NOTSTARI)     /* Caseless */      if (op >= OP_NOTSTARI)     /* Caseless */
3589        {        {
3590        fc = md->lcc[fc];  #ifdef COMPILE_PCRE8
3591          /* fc must be < 128 if UTF is enabled. */
3592          foc = md->fcc[fc];
3593    #else
3594    #ifdef SUPPORT_UTF
3595    #ifdef SUPPORT_UCP
3596          if (utf && fc > 127)
3597            foc = UCD_OTHERCASE(fc);
3598    #else
3599          if (utf && fc > 127)
3600            foc = fc;
3601    #endif /* SUPPORT_UCP */
3602          else
3603    #endif /* SUPPORT_UTF */
3604            foc = TABLE_GET(fc, md->fcc, fc);
3605    #endif /* COMPILE_PCRE8 */
3606    
3607  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3608        /* UTF-8 mode */        if (utf)
       if (utf8)  
3609          {          {
3610          register unsigned int d;          register unsigned int d;
3611          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 3532  for (;;) Line 3613  for (;;)
3613            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3614              {              {
3615              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3616              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3617              }              }
3618            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3619            if (d < 256) d = md->lcc[d];            if (fc == d || foc == d) RRETURN(MATCH_NOMATCH);
           if (fc == d) MRRETURN(MATCH_NOMATCH);  
3620            }            }
3621          }          }
3622        else        else
3623  #endif  #endif
3624          /* Not UTF mode */
       /* Not UTF-8 mode */  
3625          {          {
3626          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3627            {            {
3628            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3629              {              {
3630              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3631              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3632              }              }
3633            if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);            if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3634              eptr++;
3635            }            }
3636          }          }
3637    
# Line 3559  for (;;) Line 3639  for (;;)
3639    
3640        if (minimize)        if (minimize)
3641          {          {
3642  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3643          /* UTF-8 mode */          if (utf)
         if (utf8)  
3644            {            {
3645            register unsigned int d;            register unsigned int d;
3646            for (fi = min;; fi++)            for (fi = min;; fi++)
3647              {              {
3648              RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);
3649              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3650              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3651              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3652                {                {
3653                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3654                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3655                }                }
3656              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3657              if (d < 256) d = md->lcc[d];              if (fc == d || foc == d) RRETURN(MATCH_NOMATCH);
             if (fc == d) MRRETURN(MATCH_NOMATCH);  
3658              }              }
3659            }            }
3660          else          else
3661  #endif  #endif
3662          /* Not UTF-8 mode */          /* Not UTF mode */
3663            {            {
3664            for (fi = min;; fi++)            for (fi = min;; fi++)
3665              {              {
3666              RMATCH(eptr, ecode, offset_top, md, eptrb, RM29);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM29);
3667              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3668              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3669              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3670                {                {
3671                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3672                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3673                }                }
3674              if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);              if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3675                eptr++;
3676              }              }
3677            }            }
3678          /* Control never gets here */          /* Control never gets here */
# Line 3605  for (;;) Line 3684  for (;;)
3684          {          {
3685          pp = eptr;          pp = eptr;
3686    
3687  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3688          /* UTF-8 mode */          if (utf)
         if (utf8)  
3689            {            {
3690            register unsigned int d;            register unsigned int d;
3691            for (i = min; i < max; i++)            for (i = min; i < max; i++)
# Line 3619  for (;;) Line 3697  for (;;)
3697                break;                break;
3698                }                }
3699              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3700              if (d < 256) d = md->lcc[d];              if (fc == d || foc == d) break;
             if (fc == d) break;  
3701              eptr += len;              eptr += len;
3702              }              }
3703          if (possessive) continue;          if (possessive) continue;
# Line 3634  for (;;) Line 3711  for (;;)
3711            }            }
3712          else          else
3713  #endif  #endif
3714          /* Not UTF-8 mode */          /* Not UTF mode */
3715            {            {
3716            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3717              {              {
# Line 3643  for (;;) Line 3720  for (;;)
3720                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3721                break;                break;
3722                }                }
3723              if (fc == md->lcc[*eptr]) break;              if (fc == *eptr || foc == *eptr) break;
3724              eptr++;              eptr++;
3725              }              }
3726            if (possessive) continue;            if (possessive) continue;
# Line 3655  for (;;) Line 3732  for (;;)
3732              }              }
3733            }            }
3734    
3735          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3736          }          }
3737        /* Control never gets here */        /* Control never gets here */
3738        }        }
# Line 3664  for (;;) Line 3741  for (;;)
3741    
3742      else      else
3743        {        {
3744  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3745        /* UTF-8 mode */        if (utf)
       if (utf8)  
3746          {          {
3747          register unsigned int d;          register unsigned int d;
3748          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 3674  for (;;) Line 3750  for (;;)
3750            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3751              {              {
3752              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3753              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3754              }              }
3755            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3756            if (fc == d) MRRETURN(MATCH_NOMATCH);            if (fc == d) RRETURN(MATCH_NOMATCH);
3757            }            }
3758          }          }
3759        else        else
3760  #endif  #endif
3761        /* Not UTF-8 mode */        /* Not UTF mode */
3762          {          {
3763          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3764            {            {
3765            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3766              {              {
3767              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3768              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3769              }              }
3770            if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);            if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
3771            }            }
3772          }          }
3773    
# Line 3699  for (;;) Line 3775  for (;;)
3775    
3776        if (minimize)        if (minimize)
3777          {          {
3778  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3779          /* UTF-8 mode */          if (utf)
         if (utf8)  
3780            {            {
3781            register unsigned int d;            register unsigned int d;
3782            for (fi = min;; fi++)            for (fi = min;; fi++)
3783              {              {
3784              RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);
3785              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3786              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3787              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3788                {                {
3789                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3790                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3791                }                }
3792              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3793              if (fc == d) MRRETURN(MATCH_NOMATCH);              if (fc == d) RRETURN(MATCH_NOMATCH);
3794              }              }
3795            }            }
3796          else          else
3797  #endif  #endif
3798          /* Not UTF-8 mode */          /* Not UTF mode */
3799            {            {
3800            for (fi = min;; fi++)            for (fi = min;; fi++)
3801              {              {
3802              RMATCH(eptr, ecode, offset_top, md, eptrb, RM33);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM33);
3803              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3804              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3805              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3806                {                {
3807                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3808                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3809                }                }
3810              if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);              if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
3811              }              }
3812            }            }
3813          /* Control never gets here */          /* Control never gets here */
# Line 3744  for (;;) Line 3819  for (;;)
3819          {          {
3820          pp = eptr;          pp = eptr;
3821    
3822  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3823          /* UTF-8 mode */          if (utf)
         if (utf8)  
3824            {            {
3825            register unsigned int d;            register unsigned int d;
3826            for (i = min; i < max; i++)            for (i = min; i < max; i++)
# Line 3772  for (;;) Line 3846  for (;;)
3846            }            }
3847          else          else
3848  #endif  #endif
3849          /* Not UTF-8 mode */          /* Not UTF mode */
3850            {            {
3851            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3852              {              {
# Line 3793  for (;;) Line 3867  for (;;)
3867              }              }
3868            }            }
3869    
3870          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3871          }          }
3872        }        }
3873      /* Control never gets here */      /* Control never gets here */
# Line 3805  for (;;) Line 3879  for (;;)
3879      case OP_TYPEEXACT:      case OP_TYPEEXACT:
3880      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3881      minimize = TRUE;      minimize = TRUE;
3882      ecode += 3;      ecode += 1 + IMM2_SIZE;
3883      goto REPEATTYPE;      goto REPEATTYPE;
3884    
3885      case OP_TYPEUPTO:      case OP_TYPEUPTO:
# Line 3813  for (;;) Line 3887  for (;;)
3887      min = 0;      min = 0;
3888      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3889      minimize = *ecode == OP_TYPEMINUPTO;      minimize = *ecode == OP_TYPEMINUPTO;
3890      ecode += 3;      ecode += 1 + IMM2_SIZE;
3891      goto REPEATTYPE;      goto REPEATTYPE;
3892    
3893      case OP_TYPEPOSSTAR:      case OP_TYPEPOSSTAR:
# Line 3841  for (;;) Line 3915  for (;;)
3915      possessive = TRUE;      possessive = TRUE;
3916      min = 0;      min = 0;
3917      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3918      ecode += 3;      ecode += 1 + IMM2_SIZE;
3919      goto REPEATTYPE;      goto REPEATTYPE;
3920    
3921      case OP_TYPESTAR:      case OP_TYPESTAR:
# Line 3887  for (;;) Line 3961  for (;;)
3961          switch(prop_type)          switch(prop_type)
3962            {            {
3963            case PT_ANY:            case PT_ANY:
3964            if (prop_fail_result) MRRETURN(MATCH_NOMATCH);            if (prop_fail_result) RRETURN(MATCH_NOMATCH);
3965            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3966              {              {
3967              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3968                {                {
3969                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3970                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3971                }                }
3972              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3973              }              }
# Line 3906  for (;;) Line 3980  for (;;)
3980              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3981                {                {
3982                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3983                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3984                }                }
3985              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3986              chartype = UCD_CHARTYPE(c);              chartype = UCD_CHARTYPE(c);
3987              if ((chartype == ucp_Lu ||              if ((chartype == ucp_Lu ||
3988                   chartype == ucp_Ll ||                   chartype == ucp_Ll ||
3989                   chartype == ucp_Lt) == prop_fail_result)                   chartype == ucp_Lt) == prop_fail_result)
3990                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3991              }              }
3992            break;            break;
3993    
# Line 3923  for (;;) Line 3997  for (;;)
3997              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3998                {                {
3999                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4000                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4001                }                }
4002              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4003              if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)              if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
4004                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4005              }              }
4006            break;            break;
4007    
# Line 3937  for (;;) Line 4011  for (;;)
4011              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4012                {                {
4013                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4014                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4015                }                }
4016              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4017              if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)              if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
4018                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4019              }              }
4020            break;            break;
4021    
# Line 3951  for (;;) Line 4025  for (;;)
4025              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4026                {                {
4027                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4028                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4029                }                }
4030              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4031              if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)              if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
4032                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4033              }              }
4034            break;            break;
4035    
# Line 3966  for (;;) Line 4040  for (;;)
4040              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4041                {                {
4042                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4043                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4044                }                }
4045              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4046              category = UCD_CATEGORY(c);              category = UCD_CATEGORY(c);
4047              if ((category == ucp_L || category == ucp_N) == prop_fail_result)              if ((category == ucp_L || category == ucp_N) == prop_fail_result)
4048                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4049              }              }
4050            break;            break;
4051    
# Line 3981  for (;;) Line 4055  for (;;)
4055              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4056                {                {
4057                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4058                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4059                }                }
4060              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4061              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4062                   c == CHAR_FF || c == CHAR_CR)                   c == CHAR_FF || c == CHAR_CR)
4063                     == prop_fail_result)                     == prop_fail_result)
4064                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4065              }              }
4066            break;            break;
4067    
# Line 3997  for (;;) Line 4071  for (;;)
4071              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4072                {                {
4073                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4074                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4075                }                }
4076              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4077              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4078                   c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)                   c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
4079                     == prop_fail_result)                     == prop_fail_result)
4080                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4081              }              }
4082            break;            break;
4083    
# Line 4014  for (;;) Line 4088  for (;;)
4088              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4089                {                {
4090                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4091                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4092                }                }
4093              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4094              category = UCD_CATEGORY(c);              category = UCD_CATEGORY(c);
4095              if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE)              if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE)
4096                     == prop_fail_result)                     == prop_fail_result)
4097                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4098              }              }
4099            break;            break;
4100    
# Line 4041  for (;;) Line 4115  for (;;)
4115            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4116              {              {
4117              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4118              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4119              }              }
4120            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
4121            if (UCD_CATEGORY(c) == ucp_M) MRRETURN(MATCH_NOMATCH);            if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
4122            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4123              {              {
4124              int len = 1;              int len = 1;
4125              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
4126              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
4127              eptr += len;              eptr += len;
4128              }              }
# Line 4060  for (;;) Line 4134  for (;;)
4134    
4135  /* Handle all other cases when the coding is UTF-8 */  /* Handle all other cases when the coding is UTF-8 */
4136    
4137  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4138        if (utf8) switch(ctype)        if (utf) switch(ctype)
4139          {          {
4140          case OP_ANY:          case OP_ANY:
4141          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 4069  for (;;) Line 4143  for (;;)
4143            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4144              {              {
4145              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4146              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4147              }              }
4148            if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4149            eptr++;            eptr++;
4150            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4151            }            }
4152          break;          break;
4153    
# Line 4083  for (;;) Line 4157  for (;;)
4157            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4158              {              {
4159              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4160              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4161              }              }
4162            eptr++;            eptr++;
4163            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4164            }            }
4165          break;          break;
4166    
4167          case OP_ANYBYTE:          case OP_ANYBYTE:
4168          if (eptr > md->end_subject - min) MRRETURN(MATCH_NOMATCH);          if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);
4169          eptr += min;          eptr += min;
4170          break;          break;
4171    
# Line 4101  for (;;) Line 4175  for (;;)
4175            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4176              {              {
4177              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4178              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4179              }              }
4180            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4181            switch(c)            switch(c)
4182              {              {
4183              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4184    
4185              case 0x000d:              case 0x000d:
4186              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
# Line 4120  for (;;) Line 4194  for (;;)
4194              case 0x0085:              case 0x0085:
4195              case 0x2028:              case 0x2028:
4196              case 0x2029:              case 0x2029:
4197              if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4198              break;              break;
4199              }              }
4200            }            }
# Line 4132  for (;;) Line 4206  for (;;)
4206            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4207              {              {
4208              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4209              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4210              }              }
4211            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4212            switch(c)            switch(c)
# Line 4157  for (;;) Line 4231  for (;;)
4231              case 0x202f:    /* NARROW NO-BREAK SPACE */              case 0x202f:    /* NARROW NO-BREAK SPACE */
4232              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4233              case 0x3000:    /* IDEOGRAPHIC SPACE */              case 0x3000:    /* IDEOGRAPHIC SPACE */
4234              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4235              }              }
4236            }            }
4237          break;          break;
# Line 4168  for (;;) Line 4242  for (;;)
4242            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4243              {              {
4244              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4245              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4246              }              }
4247            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4248            switch(c)            switch(c)
4249              {              {
4250              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4251              case 0x09:      /* HT */              case 0x09:      /* HT */
4252              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4253              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
# Line 4204  for (;;) Line 4278  for (;;)
4278            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4279              {              {
4280              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4281              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4282              }              }
4283            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4284            switch(c)            switch(c)
# Line 4217  for (;;) Line 4291  for (;;)
4291              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4292              case 0x2028:    /* LINE SEPARATOR */              case 0x2028:    /* LINE SEPARATOR */
4293              case 0x2029:    /* PARAGRAPH SEPARATOR */              case 0x2029:    /* PARAGRAPH SEPARATOR */
4294              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4295              }              }
4296            }            }
4297          break;          break;
# Line 4228  for (;;) Line 4302  for (;;)
4302            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4303              {              {
4304              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4305              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4306              }              }
4307            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4308            switch(c)            switch(c)
4309              {              {
4310              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4311              case 0x0a:      /* LF */              case 0x0a:      /* LF */
4312              case 0x0b:      /* VT */              case 0x0b:      /* VT */
4313              case 0x0c:      /* FF */              case 0x0c:      /* FF */
# Line 4252  for (;;) Line 4326  for (;;)
4326            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4327              {              {
4328              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4329              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4330              }              }
4331            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4332            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
4333              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4334            }            }
4335          break;          break;
4336    
# Line 4266  for (;;) Line 4340  for (;;)
4340            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4341              {              {
4342              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4343              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4344              }              }
4345            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_digit) == 0)
4346              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4347              eptr++;
4348            /* 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 */
4349            }            }
4350          break;          break;
# Line 4280  for (;;) Line 4355  for (;;)
4355            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4356              {              {
4357              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4358              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4359              }              }
4360            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
4361              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4362            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4363              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4364            }            }
4365          break;          break;
4366    
# Line 4294  for (;;) Line 4370  for (;;)
4370            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4371              {              {
4372              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4373              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4374              }              }
4375            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_space) == 0)
4376              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4377              eptr++;
4378            /* 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 */
4379            }            }
4380          break;          break;
# Line 4308  for (;;) Line 4385  for (;;)
4385            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4386              {              {
4387              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4388              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4389              }              }
4390            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
4391              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4392            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4393              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4394            }            }
4395          break;          break;
4396    
# Line 4322  for (;;) Line 4400  for (;;)
4400            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4401              {              {
4402              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4403              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4404              }              }
4405            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_word) == 0)
4406              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4407              eptr++;
4408            /* 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 */
4409            }            }
4410          break;          break;
# Line 4335  for (;;) Line 4414  for (;;)
4414          }  /* End switch(ctype) */          }  /* End switch(ctype) */
4415    
4416        else        else
4417  #endif     /* SUPPORT_UTF8 */  #endif     /* SUPPORT_UTF */
4418    
4419        /* 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
4420        than OP_PROP and OP_NOTPROP. */        than OP_PROP and OP_NOTPROP. */
# Line 4348  for (;;) Line 4427  for (;;)
4427            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4428              {              {
4429              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4430              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4431              }              }
4432            if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4433            eptr++;            eptr++;
4434            }            }
4435          break;          break;
# Line 4359  for (;;) Line 4438  for (;;)
4438          if (eptr > md->end_subject - min)          if (eptr > md->end_subject - min)
4439            {            {
4440            SCHECK_PARTIAL();            SCHECK_PARTIAL();
4441            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
4442            }            }
4443          eptr += min;          eptr += min;
4444          break;          break;
# Line 4368  for (;;) Line 4447  for (;;)
4447          if (eptr > md->end_subject - min)          if (eptr > md->end_subject - min)
4448            {            {
4449            SCHECK_PARTIAL();            SCHECK_PARTIAL();
4450            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
4451            }            }
4452          eptr += min;          eptr += min;
4453          break;          break;
# Line 4379  for (;;) Line 4458  for (;;)
4458            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4459              {              {
4460              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4461              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4462              }              }
4463            switch(*eptr++)            switch(*eptr++)
4464              {              {
4465              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4466    
4467              case 0x000d:              case 0x000d:
4468              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
# Line 4395  for (;;) Line 4474  for (;;)
4474              case 0x000b:              case 0x000b:
4475              case 0x000c:              case 0x000c:
4476              case 0x0085:              case 0x0085:
4477              if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);  #ifdef COMPILE_PCRE16
4478                case 0x2028:
4479                case 0x2029:
4480    #endif
4481                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4482              break;              break;
4483              }              }
4484            }            }
# Line 4407  for (;;) Line 4490  for (;;)
4490            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4491              {              {
4492              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4493              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4494              }              }
4495            switch(*eptr++)            switch(*eptr++)
4496              {              {
# Line 4415  for (;;) Line 4498  for (;;)
4498              case 0x09:      /* HT */              case 0x09:      /* HT */
4499              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4500              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
4501              MRRETURN(MATCH_NOMATCH);  #ifdef COMPILE_PCRE16
4502                case 0x1680:    /* OGHAM SPACE MARK */
4503                case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
4504                case 0x2000:    /* EN QUAD */
4505                case 0x2001:    /* EM QUAD */
4506                case 0x2002:    /* EN SPACE */
4507                case 0x2003:    /* EM SPACE */
4508                case 0x2004:    /* THREE-PER-EM SPACE */
4509                case 0x2005:    /* FOUR-PER-EM SPACE */
4510                case 0x2006:    /* SIX-PER-EM SPACE */
4511                case 0x2007:    /* FIGURE SPACE */
4512                case 0x2008:    /* PUNCTUATION SPACE */
4513                case 0x2009:    /* THIN SPACE */
4514                case 0x200A:    /* HAIR SPACE */
4515                case 0x202f:    /* NARROW NO-BREAK SPACE */
4516                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4517                case 0x3000:    /* IDEOGRAPHIC SPACE */
4518    #endif
4519                RRETURN(MATCH_NOMATCH);
4520              }              }
4521            }            }
4522          break;          break;
# Line 4426  for (;;) Line 4527  for (;;)
4527            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4528              {              {
4529              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4530              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4531              }              }
4532            switch(*eptr++)            switch(*eptr++)
4533              {              {
4534              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4535              case 0x09:      /* HT */              case 0x09:      /* HT */
4536              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4537              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
4538    #ifdef COMPILE_PCRE16
4539                case 0x1680:    /* OGHAM SPACE MARK */
4540                case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
4541                case 0x2000:    /* EN QUAD */
4542                case 0x2001:    /* EM QUAD */
4543                case 0x2002:    /* EN SPACE */
4544                case 0x2003:    /* EM SPACE */
4545                case 0x2004:    /* THREE-PER-EM SPACE */
4546                case 0x2005:    /* FOUR-PER-EM SPACE */
4547                case 0x2006:    /* SIX-PER-EM SPACE */
4548                case 0x2007:    /* FIGURE SPACE */
4549                case 0x2008:    /* PUNCTUATION SPACE */
4550                case 0x2009:    /* THIN SPACE */
4551                case 0x200A:    /* HAIR SPACE */
4552                case 0x202f:    /* NARROW NO-BREAK SPACE */
4553                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4554                case 0x3000:    /* IDEOGRAPHIC SPACE */
4555    #endif
4556              break;              break;
4557              }              }
4558            }            }
# Line 4445  for (;;) Line 4564  for (;;)
4564            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4565              {              {
4566              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4567              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4568              }              }
4569            switch(*eptr++)            switch(*eptr++)
4570              {              {
# Line 4455  for (;;) Line 4574  for (;;)
4574              case 0x0c:      /* FF */              case 0x0c:      /* FF */
4575              case 0x0d:      /* CR */              case 0x0d:      /* CR */
4576              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4577              MRRETURN(MATCH_NOMATCH);  #ifdef COMPILE_PCRE16
4578                case 0x2028:    /* LINE SEPARATOR */
4579                case 0x2029:    /* PARAGRAPH SEPARATOR */
4580    #endif
4581                RRETURN(MATCH_NOMATCH);
4582              }              }
4583            }            }
4584          break;          break;
# Line 4466  for (;;) Line 4589  for (;;)
4589            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4590              {              {
4591              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4592              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4593              }              }
4594            switch(*eptr++)            switch(*eptr++)
4595              {              {
4596              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4597              case 0x0a:      /* LF */              case 0x0a:      /* LF */
4598              case 0x0b:      /* VT */              case 0x0b:      /* VT */
4599              case 0x0c:      /* FF */              case 0x0c:      /* FF */
4600              case 0x0d:      /* CR */              case 0x0d:      /* CR */
4601              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4602    #ifdef COMPILE_PCRE16
4603                case 0x2028:    /* LINE SEPARATOR */
4604                case 0x2029:    /* PARAGRAPH SEPARATOR */
4605    #endif
4606              break;              break;
4607              }              }
4608            }            }
# Line 4487  for (;;) Line 4614  for (;;)
4614            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4615              {              {
4616              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4617              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4618              }              }
4619            if ((md->ctypes[*eptr++] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0)
4620                RRETURN(MATCH_NOMATCH);
4621              eptr++;
4622            }            }
4623          break;          break;
4624    
# Line 4499  for (;;) Line 4628  for (;;)
4628            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4629              {              {
4630              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4631              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4632              }              }
4633            if ((md->ctypes[*eptr++] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0)
4634                RRETURN(MATCH_NOMATCH);
4635              eptr++;
4636            }            }
4637          break;          break;
4638    
# Line 4511  for (;;) Line 4642  for (;;)
4642            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4643              {              {
4644              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4645              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4646              }              }
4647            if ((md->ctypes[*eptr++] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0)
4648                RRETURN(MATCH_NOMATCH);
4649              eptr++;
4650            }            }
4651          break;          break;
4652    
# Line 4523  for (;;) Line 4656  for (;;)
4656            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4657              {              {
4658              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4659              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4660              }              }
4661            if ((md->ctypes[*eptr++] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0)
4662                RRETURN(MATCH_NOMATCH);
4663              eptr++;
4664            }            }
4665          break;          break;
4666    
# Line 4535  for (;;) Line 4670  for (;;)
4670            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4671              {              {
4672              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4673              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4674              }              }
4675            if ((md->ctypes[*eptr++] & ctype_word) != 0)            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0)
4676              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4677              eptr++;
4678            }            }
4679          break;          break;
4680    
# Line 4548  for (;;) Line 4684  for (;;)
4684            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4685              {              {
4686              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4687              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4688              }              }
4689            if ((md->ctypes[*eptr++] & ctype_word) == 0)            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0)
4690              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4691              eptr++;
4692            }            }
4693          break;          break;
4694    
# Line 4580  for (;;) Line 4717  for (;;)
4717              {              {
4718              RMATCH(eptr, ecode, offset_top, md, eptrb, RM36);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM36);
4719              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4720              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4721              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4722                {                {
4723                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4724                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4725                }                }
4726              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4727              if (prop_fail_result) MRRETURN(MATCH_NOMATCH);              if (prop_fail_result) RRETURN(MATCH_NOMATCH);
4728              }              }
4729            /* Control never gets here */            /* Control never gets here */
4730    
# Line 4597  for (;;) Line 4734  for (;;)
4734              int chartype;              int chartype;
4735              RMATCH(eptr, ecode, offset_top, md, eptrb, RM37);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM37);
4736              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4737              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4738              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4739                {                {
4740                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4741                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4742                }                }
4743              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4744              chartype = UCD_CHARTYPE(c);              chartype = UCD_CHARTYPE(c);
4745              if ((chartype == ucp_Lu ||              if ((chartype == ucp_Lu ||
4746                   chartype == ucp_Ll ||                   chartype == ucp_Ll ||
4747                   chartype == ucp_Lt) == prop_fail_result)                   chartype == ucp_Lt) == prop_fail_result)
4748                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4749              }              }
4750            /* Control never gets here */            /* Control never gets here */
4751    
# Line 4617  for (;;) Line 4754  for (;;)
4754              {              {
4755              RMATCH(eptr, ecode, offset_top, md, eptrb, RM38);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM38);
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              if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)              if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
4765                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4766              }              }
4767            /* Control never gets here */            /* Control never gets here */
4768    
# Line 4634  for (;;) Line 4771  for (;;)
4771              {              {
4772              RMATCH(eptr, ecode, offset_top, md, eptrb, RM39);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM39);
4773              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4774              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4775              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4776                {                {
4777                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4778                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4779                }                }
4780              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4781              if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)              if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
4782                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4783              }              }
4784            /* Control never gets here */            /* Control never gets here */
4785    
# Line 4651  for (;;) Line 4788  for (;;)
4788              {              {
4789              RMATCH(eptr, ecode, offset_top, md, eptrb, RM40);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM40);
4790              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4791              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4792              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4793                {                {
4794                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4795                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4796                }                }
4797              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4798              if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)              if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
4799                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4800              }              }
4801            /* Control never gets here */            /* Control never gets here */
4802    
# Line 4669  for (;;) Line 4806  for (;;)
4806              int category;              int category;
4807              RMATCH(eptr, ecode, offset_top, md, eptrb, RM59);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM59);
4808              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4809              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4810              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4811                {                {
4812                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4813                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4814                }                }
4815              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4816              category = UCD_CATEGORY(c);              category = UCD_CATEGORY(c);
4817              if ((category == ucp_L || category == ucp_N) == prop_fail_result)              if ((category == ucp_L || category == ucp_N) == prop_fail_result)
4818                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4819              }              }
4820            /* Control never gets here */            /* Control never gets here */
4821    
# Line 4687  for (;;) Line 4824  for (;;)
4824              {              {
4825              RMATCH(eptr, ecode, offset_top, md, eptrb, RM60);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM60);
4826              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4827              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4828              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4829                {                {
4830                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4831                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4832                }                }
4833              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4834              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4835                   c == CHAR_FF || c == CHAR_CR)                   c == CHAR_FF || c == CHAR_CR)
4836                     == prop_fail_result)                     == prop_fail_result)
4837                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4838              }              }
4839            /* Control never gets here */            /* Control never gets here */
4840    
# Line 4706  for (;;) Line 4843  for (;;)
4843              {              {
4844              RMATCH(eptr, ecode, offset_top, md, eptrb, RM61);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM61);
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_Z || c == CHAR_HT || c == CHAR_NL ||              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4854                   c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)                   c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
4855                     == prop_fail_result)                     == prop_fail_result)
4856                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4857              }              }
4858            /* Control never gets here */            /* Control never gets here */
4859    
# Line 4726  for (;;) Line 4863  for (;;)
4863              int category;              int category;
4864              RMATCH(eptr, ecode, offset_top, md, eptrb, RM62);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM62);
4865              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4866              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4867              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4868                {                {
4869                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4870                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4871                }                }
4872              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4873              category = UCD_CATEGORY(c);              category = UCD_CATEGORY(c);
# Line 4738  for (;;) Line 4875  for (;;)
4875                   category == ucp_N ||                   category == ucp_N ||
4876                   c == CHAR_UNDERSCORE)                   c == CHAR_UNDERSCORE)
4877                     == prop_fail_result)                     == prop_fail_result)
4878                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4879              }              }
4880            /* Control never gets here */            /* Control never gets here */
4881    
# Line 4758  for (;;) Line 4895  for (;;)
4895            {            {
4896            RMATCH(eptr, ecode, offset_top, md, eptrb, RM41);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM41);
4897            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4898            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
4899            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4900              {              {
4901              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4902              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4903              }              }
4904            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
4905            if (UCD_CATEGORY(c) == ucp_M) MRRETURN(MATCH_NOMATCH);            if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
4906            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4907              {              {
4908              int len = 1;              int len = 1;
4909              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
4910              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
4911              eptr += len;              eptr += len;
4912              }              }
# Line 4778  for (;;) Line 4915  for (;;)
4915        else        else
4916  #endif     /* SUPPORT_UCP */  #endif     /* SUPPORT_UCP */
4917    
4918  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4919        /* UTF-8 mode */        if (utf)
       if (utf8)  
4920          {          {
4921          for (fi = min;; fi++)          for (fi = min;; fi++)
4922            {            {
4923            RMATCH(eptr, ecode, offset_top, md, eptrb, RM42);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM42);
4924            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4925            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
4926            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4927              {              {
4928              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4929              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4930              }              }
4931            if (ctype == OP_ANY && IS_NEWLINE(eptr))            if (ctype == OP_ANY && IS_NEWLINE(eptr))
4932              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4933            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4934            switch(ctype)            switch(ctype)
4935              {              {
# Line 4805  for (;;) Line 4941  for (;;)
4941              case OP_ANYNL:              case OP_ANYNL:
4942              switch(c)              switch(c)
4943                {                {
4944                default: MRRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
4945                case 0x000d:                case 0x000d:
4946                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
4947                break;                break;
# Line 4817  for (;;) Line 4953  for (;;)
4953                case 0x0085:                case 0x0085:
4954                case 0x2028:                case 0x2028:
4955                case 0x2029:                case 0x2029:
4956                if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4957                break;                break;
4958                }                }
4959              break;              break;
# Line 4845  for (;;) Line 4981  for (;;)
4981                case 0x202f:    /* NARROW NO-BREAK SPACE */                case 0x202f:    /* NARROW NO-BREAK SPACE */
4982                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4983                case 0x3000:    /* IDEOGRAPHIC SPACE */                case 0x3000:    /* IDEOGRAPHIC SPACE */
4984                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4985                }                }
4986              break;              break;
4987    
4988              case OP_HSPACE:              case OP_HSPACE:
4989              switch(c)              switch(c)
4990                {                {
4991                default: MRRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
4992                case 0x09:      /* HT */                case 0x09:      /* HT */
4993                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
4994                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
# Line 4887  for (;;) Line 5023  for (;;)
5023                case 0x85:      /* NEL */                case 0x85:      /* NEL */
5024                case 0x2028:    /* LINE SEPARATOR */                case 0x2028:    /* LINE SEPARATOR */
5025                case 0x2029:    /* PARAGRAPH SEPARATOR */                case 0x2029:    /* PARAGRAPH SEPARATOR */
5026                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5027                }                }
5028              break;              break;
5029    
5030              case OP_VSPACE:              case OP_VSPACE:
5031              switch(c)              switch(c)
5032                {                {
5033                default: MRRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5034                case 0x0a:      /* LF */                case 0x0a:      /* LF */
5035                case 0x0b:      /* VT */                case 0x0b:      /* VT */
5036                case 0x0c:      /* FF */                case 0x0c:      /* FF */
# Line 4908  for (;;) Line 5044  for (;;)
5044    
5045              case OP_NOT_DIGIT:              case OP_NOT_DIGIT:
5046              if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)              if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)
5047                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5048              break;              break;
5049    
5050              case OP_DIGIT:              case OP_DIGIT:
5051              if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)
5052                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5053              break;              break;
5054    
5055              case OP_NOT_WHITESPACE:              case OP_NOT_WHITESPACE:
5056              if (c < 256 && (md->ctypes[c] & ctype_space) != 0)              if (c < 256 && (md->ctypes[c] & ctype_space) != 0)
5057                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5058              break;              break;
5059    
5060              case OP_WHITESPACE:              case OP_WHITESPACE:
5061              if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
5062                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5063              break;              break;
5064    
5065              case OP_NOT_WORDCHAR:              case OP_NOT_WORDCHAR:
5066              if (c < 256 && (md->ctypes[c] & ctype_word) != 0)              if (c < 256 && (md->ctypes[c] & ctype_word) != 0)
5067                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5068              break;              break;
5069    
5070              case OP_WORDCHAR:              case OP_WORDCHAR:
5071              if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)
5072                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5073              break;              break;
5074    
5075              default:              default:
# Line 4943  for (;;) Line 5079  for (;;)
5079          }          }
5080        else        else
5081  #endif  #endif
5082        /* Not UTF-8 mode */        /* Not UTF mode */
5083          {          {
5084          for (fi = min;; fi++)          for (fi = min;; fi++)
5085            {            {
5086            RMATCH(eptr, ecode, offset_top, md, eptrb, RM43);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM43);
5087            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5088            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
5089            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
5090              {              {
5091              SCHECK_PARTIAL();              SCHECK_PARTIAL();
5092              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
5093              }              }
5094            if (ctype == OP_ANY && IS_NEWLINE(eptr))            if (ctype == OP_ANY && IS_NEWLINE(eptr))
5095              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
5096            c = *eptr++;            c = *eptr++;
5097            switch(ctype)            switch(ctype)
5098              {              {
# Line 4968  for (;;) Line 5104  for (;;)
5104              case OP_ANYNL:              case OP_ANYNL:
5105              switch(c)              switch(c)
5106                {                {
5107                default: MRRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5108                case 0x000d:                case 0x000d:
5109                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
5110                break;                break;
# Line 4979  for (;;) Line 5115  for (;;)
5115                case 0x000b:                case 0x000b:
5116                case 0x000c:                case 0x000c:
5117                case 0x0085:                case 0x0085:
5118                if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);  #ifdef COMPILE_PCRE16
5119                  case 0x2028:
5120                  case 0x2029:
5121    #endif
5122                  if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
5123                break;                break;
5124                }                }
5125              break;              break;
# Line 4991  for (;;) Line 5131  for (;;)
5131                case 0x09:      /* HT */                case 0x09:      /* HT */
5132                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
5133                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
5134                MRRETURN(MATCH_NOMATCH);  #ifdef COMPILE_PCRE16
5135                  case 0x1680:    /* OGHAM SPACE MARK */
5136                  case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
5137                  case 0x2000:    /* EN QUAD */
5138                  case 0x2001:    /* EM QUAD */
5139                  case 0x2002:    /* EN SPACE */
5140                  case 0x2003:    /* EM SPACE */
5141                  case 0x2004:    /* THREE-PER-EM SPACE */
5142                  case 0x2005:    /* FOUR-PER-EM SPACE */
5143                  case 0x2006:    /* SIX-PER-EM SPACE */
5144                  case 0x2007:    /* FIGURE SPACE */
5145                  case 0x2008:    /* PUNCTUATION SPACE */
5146                  case 0x2009:    /* THIN SPACE */
5147                  case 0x200A:    /* HAIR SPACE */
5148                  case 0x202f:    /* NARROW NO-BREAK SPACE */
5149                  case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
5150                  case 0x3000:    /* IDEOGRAPHIC SPACE */
5151    #endif
5152                  RRETURN(MATCH_NOMATCH);
5153                }                }
5154              break;              break;
5155    
5156              case OP_HSPACE:              case OP_HSPACE:
5157              switch(c)              switch(c)
5158                {                {
5159                default: MRRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5160                case 0x09:      /* HT */                case 0x09:      /* HT */
5161                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
5162                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
5163    #ifdef COMPILE_PCRE16
5164                  case 0x1680:    /* OGHAM SPACE MARK */
5165                  case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
5166                  case 0x2000:    /* EN QUAD */
5167                  case 0x2001:    /* EM QUAD */
5168                  case 0x2002:    /* EN SPACE */
5169                  case 0x2003:    /* EM SPACE */
5170                  case 0x2004:    /* THREE-PER-EM SPACE */
5171                  case 0x2005:    /* FOUR-PER-EM SPACE */
5172                  case 0x2006:    /* SIX-PER-EM SPACE */
5173                  case 0x2007:    /* FIGURE SPACE */
5174                  case 0x2008:    /* PUNCTUATION SPACE */
5175                  case 0x2009:    /* THIN SPACE */
5176                  case 0x200A:    /* HAIR SPACE */
5177                  case 0x202f:    /* NARROW NO-BREAK SPACE */
5178                  case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
5179                  case 0x3000:    /* IDEOGRAPHIC SPACE */
5180    #endif