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

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

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

code/trunk/pcre_exec.c revision 723 by ph10, Sat Oct 8 15:55:23 2011 UTC code/branches/pcre16/pcre_exec.c revision 801 by ph10, Mon Dec 12 16:23:37 2011 UTC
# Line 82  negative to avoid the external error cod Line 82  negative to avoid the external error cod
82  #define MATCH_SKIP_ARG     (-993)  #define MATCH_SKIP_ARG     (-993)
83  #define MATCH_THEN         (-992)  #define MATCH_THEN         (-992)
84    
 /* This is a convenience macro for code that occurs many times. */  
   
 #define MRRETURN(ra) \  
   { \  
   md->mark = markptr; \  
   RRETURN(ra); \  
   }  
   
85  /* Maximum number of ints of offset to save on the stack for recursive calls.  /* Maximum number of ints of offset to save on the stack for recursive calls.
86  If the offset vector is bigger, malloc is used. This should be a multiple of 3,  If the offset vector is bigger, malloc is used. This should be a multiple of 3,
87  because the offset vector is always a multiple of 3 long. */  because the offset vector is always a multiple of 3 long. */
# Line 121  Returns:     nothing Line 113  Returns:     nothing
113  */  */
114    
115  static void  static void
116  pchars(const uschar *p, int length, BOOL is_subject, match_data *md)  pchars(const pcre_uchar *p, int length, BOOL is_subject, match_data *md)
117  {  {
118  unsigned int c;  unsigned int c;
119  if (is_subject && length > md->end_subject - p) length = md->end_subject - p;  if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
# Line 152  Returns:      < 0 if not matched, otherw Line 144  Returns:      < 0 if not matched, otherw
144  */  */
145    
146  static int  static int
147  match_ref(int offset, register USPTR eptr, int length, match_data *md,  match_ref(int offset, register PCRE_PUCHAR eptr, int length, match_data *md,
148    BOOL caseless)    BOOL caseless)
149  {  {
150  USPTR eptr_start = eptr;  PCRE_PUCHAR eptr_start = eptr;
151  register USPTR p = md->start_subject + md->offset_vector[offset];  register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset];
152    
153  #ifdef PCRE_DEBUG  #ifdef PCRE_DEBUG
154  if (eptr >= md->end_subject)  if (eptr >= md->end_subject)
# Line 181  ASCII characters. */ Line 173  ASCII characters. */
173    
174  if (caseless)  if (caseless)
175    {    {
176  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
177  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
178    if (md->utf8)    if (md->utf)
179      {      {
180      /* Match characters up to the end of the reference. NOTE: the number of      /* Match characters up to the end of the reference. NOTE: the number of
181      bytes matched may differ, because there are some characters whose upper and      bytes matched may differ, because there are some characters whose upper and
# Line 193  if (caseless) Line 185  if (caseless)
185      the latter. It is important, therefore, to check the length along the      the latter. It is important, therefore, to check the length along the
186      reference, not along the subject (earlier code did this wrong). */      reference, not along the subject (earlier code did this wrong). */
187    
188      USPTR endptr = p + length;      PCRE_PUCHAR endptr = p + length;
189      while (p < endptr)      while (p < endptr)
190        {        {
191        int c, d;        int c, d;
# Line 225  else Line 217  else
217    while (length-- > 0) if (*p++ != *eptr++) return -1;    while (length-- > 0) if (*p++ != *eptr++) return -1;
218    }    }
219    
220  return eptr - eptr_start;  return (int)(eptr - eptr_start);
221  }  }
222    
223    
# Line 290  actually used in this definition. */ Line 282  actually used in this definition. */
282  #define RMATCH(ra,rb,rc,rd,re,rw) \  #define RMATCH(ra,rb,rc,rd,re,rw) \
283    { \    { \
284    printf("match() called in line %d\n", __LINE__); \    printf("match() called in line %d\n", __LINE__); \
285    rrc = match(ra,rb,mstart,markptr,rc,rd,re,rdepth+1); \    rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1); \
286    printf("to line %d\n", __LINE__); \    printf("to line %d\n", __LINE__); \
287    }    }
288  #define RRETURN(ra) \  #define RRETURN(ra) \
# Line 300  actually used in this definition. */ Line 292  actually used in this definition. */
292    }    }
293  #else  #else
294  #define RMATCH(ra,rb,rc,rd,re,rw) \  #define RMATCH(ra,rb,rc,rd,re,rw) \
295    rrc = match(ra,rb,mstart,markptr,rc,rd,re,rdepth+1)    rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1)
296  #define RRETURN(ra) return ra  #define RRETURN(ra) return ra
297  #endif  #endif
298    
# Line 321  argument of match(), which never changes Line 313  argument of match(), which never changes
313    newframe->Xeptr = ra;\    newframe->Xeptr = ra;\
314    newframe->Xecode = rb;\    newframe->Xecode = rb;\
315    newframe->Xmstart = mstart;\    newframe->Xmstart = mstart;\
   newframe->Xmarkptr = markptr;\  
316    newframe->Xoffset_top = rc;\    newframe->Xoffset_top = rc;\
317    newframe->Xeptrb = re;\    newframe->Xeptrb = re;\
318    newframe->Xrdepth = frame->Xrdepth + 1;\    newframe->Xrdepth = frame->Xrdepth + 1;\
# Line 354  typedef struct heapframe { Line 345  typedef struct heapframe {
345    
346    /* Function arguments that may change */    /* Function arguments that may change */
347    
348    USPTR Xeptr;    PCRE_PUCHAR Xeptr;
349    const uschar *Xecode;    const pcre_uchar *Xecode;
350    USPTR Xmstart;    PCRE_PUCHAR Xmstart;
   USPTR Xmarkptr;  
351    int Xoffset_top;    int Xoffset_top;
352    eptrblock *Xeptrb;    eptrblock *Xeptrb;
353    unsigned int Xrdepth;    unsigned int Xrdepth;
354    
355    /* Function local variables */    /* Function local variables */
356    
357    USPTR Xcallpat;    PCRE_PUCHAR Xcallpat;
358  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
359    USPTR Xcharptr;    PCRE_PUCHAR Xcharptr;
360  #endif  #endif
361    USPTR Xdata;    PCRE_PUCHAR Xdata;
362    USPTR Xnext;    PCRE_PUCHAR Xnext;
363    USPTR Xpp;    PCRE_PUCHAR Xpp;
364    USPTR Xprev;    PCRE_PUCHAR Xprev;
365    USPTR Xsaved_eptr;    PCRE_PUCHAR Xsaved_eptr;
366    
367    recursion_info Xnew_recursive;    recursion_info Xnew_recursive;
368    
# Line 385  typedef struct heapframe { Line 375  typedef struct heapframe {
375    int Xprop_value;    int Xprop_value;
376    int Xprop_fail_result;    int Xprop_fail_result;
377    int Xoclength;    int Xoclength;
378    uschar Xocchars[8];    pcre_uchar Xocchars[6];
379  #endif  #endif
380    
381    int Xcodelink;    int Xcodelink;
# Line 427  returns a negative (error) response, the Line 417  returns a negative (error) response, the
417  same response. */  same response. */
418    
419  /* 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
420  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
421  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.
422  something has been matched). For hard partial matching, we then return  something has been matched). For hard partial matching, we then return
423  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 428  the subject. */
428        eptr > md->start_used_ptr) \        eptr > md->start_used_ptr) \
429      { \      { \
430      md->hitend = TRUE; \      md->hitend = TRUE; \
431      if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL); \      if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \
432      }      }
433    
434  #define SCHECK_PARTIAL()\  #define SCHECK_PARTIAL()\
435    if (md->partial != 0 && eptr > md->start_used_ptr) \    if (md->partial != 0 && eptr > md->start_used_ptr) \
436      { \      { \
437      md->hitend = TRUE; \      md->hitend = TRUE; \
438      if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL); \      if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \
439      }      }
440    
441    
442  /* Performance note: It might be tempting to extract commonly used fields from  /* Performance note: It might be tempting to extract commonly used fields from
443  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
444  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
445  made performance worse.  made performance worse.
446    
# Line 459  Arguments: Line 449  Arguments:
449     ecode       pointer to current position in compiled code     ecode       pointer to current position in compiled code
450     mstart      pointer to the current match start position (can be modified     mstart      pointer to the current match start position (can be modified
451                   by encountering \K)                   by encountering \K)
    markptr     pointer to the most recent MARK name, or NULL  
452     offset_top  current top pointer     offset_top  current top pointer
453     md          pointer to "static" info for the match     md          pointer to "static" info for the match
454     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 463  Returns:       MATCH_MATCH if matched
463  */  */
464    
465  static int  static int
466  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,  match(REGISTER PCRE_PUCHAR eptr, REGISTER const pcre_uchar *ecode,
467    const uschar *markptr, int offset_top, match_data *md, eptrblock *eptrb,    PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb,
468    unsigned int rdepth)    unsigned int rdepth)
469  {  {
470  /* 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 474  so they can be ordinary variables in all
474  register int  rrc;         /* Returns from recursive calls */  register int  rrc;         /* Returns from recursive calls */
475  register int  i;           /* Used for loops not involving calls to RMATCH() */  register int  i;           /* Used for loops not involving calls to RMATCH() */
476  register unsigned int c;   /* Character values not kept over RMATCH() calls */  register unsigned int c;   /* Character values not kept over RMATCH() calls */
477  register BOOL utf8;        /* Local copy of UTF-8 flag for speed */  register BOOL utf;         /* Local copy of UTF flag for speed */
478    
479  BOOL minimize, possessive; /* Quantifier options */  BOOL minimize, possessive; /* Quantifier options */
480  BOOL caseless;  BOOL caseless;
# Line 506  frame->Xprevframe = NULL;            /* Line 495  frame->Xprevframe = NULL;            /*
495  frame->Xeptr = eptr;  frame->Xeptr = eptr;
496  frame->Xecode = ecode;  frame->Xecode = ecode;
497  frame->Xmstart = mstart;  frame->Xmstart = mstart;
 frame->Xmarkptr = markptr;  
498  frame->Xoffset_top = offset_top;  frame->Xoffset_top = offset_top;
499  frame->Xeptrb = eptrb;  frame->Xeptrb = eptrb;
500  frame->Xrdepth = rdepth;  frame->Xrdepth = rdepth;
# Line 520  HEAP_RECURSE: Line 508  HEAP_RECURSE:
508  #define eptr               frame->Xeptr  #define eptr               frame->Xeptr
509  #define ecode              frame->Xecode  #define ecode              frame->Xecode
510  #define mstart             frame->Xmstart  #define mstart             frame->Xmstart
 #define markptr            frame->Xmarkptr  
511  #define offset_top         frame->Xoffset_top  #define offset_top         frame->Xoffset_top
512  #define eptrb              frame->Xeptrb  #define eptrb              frame->Xeptrb
513  #define rdepth             frame->Xrdepth  #define rdepth             frame->Xrdepth
514    
515  /* Ditto for the local variables */  /* Ditto for the local variables */
516    
517  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
518  #define charptr            frame->Xcharptr  #define charptr            frame->Xcharptr
519  #endif  #endif
520  #define callpat            frame->Xcallpat  #define callpat            frame->Xcallpat
# Line 585  declarations can be cut out in a block. Line 572  declarations can be cut out in a block.
572  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
573  to RMATCH(). */  to RMATCH(). */
574    
575  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
576  const uschar *charptr;  const pcre_uchar *charptr;
577  #endif  #endif
578  const uschar *callpat;  const pcre_uchar *callpat;
579  const uschar *data;  const pcre_uchar *data;
580  const uschar *next;  const pcre_uchar *next;
581  USPTR         pp;  PCRE_PUCHAR       pp;
582  const uschar *prev;  const pcre_uchar *prev;
583  USPTR         saved_eptr;  PCRE_PUCHAR       saved_eptr;
584    
585  recursion_info new_recursive;  recursion_info new_recursive;
586    
# Line 606  int prop_type; Line 593  int prop_type;
593  int prop_value;  int prop_value;
594  int prop_fail_result;  int prop_fail_result;
595  int oclength;  int oclength;
596  uschar occhars[8];  pcre_uchar occhars[6];
597  #endif  #endif
598    
599  int codelink;  int codelink;
# Line 634  the alternative names that are used. */ Line 621  the alternative names that are used. */
621  #define code_offset   codelink  #define code_offset   codelink
622  #define condassert    condition  #define condassert    condition
623  #define matched_once  prev_is_word  #define matched_once  prev_is_word
624    #define foc           number
625    
626  /* These statements are here to stop the compiler complaining about unitialized  /* These statements are here to stop the compiler complaining about unitialized
627  variables. */  variables. */
# Line 659  defined). However, RMATCH isn't like a f Line 647  defined). However, RMATCH isn't like a f
647  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,
648  however, impact performance when true recursion is being used. */  however, impact performance when true recursion is being used. */
649    
650  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
651  utf8 = md->utf8;       /* Local copy of the flag */  utf = md->utf;       /* Local copy of the flag */
652  #else  #else
653  utf8 = FALSE;  utf = FALSE;
654  #endif  #endif
655    
656  /* 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 689  for (;;)
689    switch(op)    switch(op)
690      {      {
691      case OP_MARK:      case OP_MARK:
692      markptr = ecode + 2;      md->nomatch_mark = ecode + 2;
693      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      md->mark = NULL;    /* In case previously set by assertion */
694        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
695        eptrb, RM55);        eptrb, RM55);
696        if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
697             md->mark == NULL) md->mark = ecode + 2;
698    
699      /* 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
700      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 703  for (;;)
703      position and return MATCH_SKIP. Otherwise, pass back the return code      position and return MATCH_SKIP. Otherwise, pass back the return code
704      unaltered. */      unaltered. */
705    
706      if (rrc == MATCH_SKIP_ARG &&      else if (rrc == MATCH_SKIP_ARG &&
707          strcmp((char *)markptr, (char *)(md->start_match_ptr)) == 0)          STRCMP_UC_UC(ecode + 2, md->start_match_ptr) == 0)
708        {        {
709        md->start_match_ptr = eptr;        md->start_match_ptr = eptr;
710        RRETURN(MATCH_SKIP);        RRETURN(MATCH_SKIP);
711        }        }
   
     if (md->mark == NULL) md->mark = markptr;  
712      RRETURN(rrc);      RRETURN(rrc);
713    
714      case OP_FAIL:      case OP_FAIL:
715      MRRETURN(MATCH_NOMATCH);      RRETURN(MATCH_NOMATCH);
716    
717      /* COMMIT overrides PRUNE, SKIP, and THEN */      /* COMMIT overrides PRUNE, SKIP, and THEN */
718    
719      case OP_COMMIT:      case OP_COMMIT:
720      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
721        eptrb, RM52);        eptrb, RM52);
722      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&
723          rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&          rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&
724          rrc != MATCH_THEN)          rrc != MATCH_THEN)
725        RRETURN(rrc);        RRETURN(rrc);
726      MRRETURN(MATCH_COMMIT);      RRETURN(MATCH_COMMIT);
727    
728      /* PRUNE overrides THEN */      /* PRUNE overrides THEN */
729    
730      case OP_PRUNE:      case OP_PRUNE:
731      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
732        eptrb, RM51);        eptrb, RM51);
733      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
734      MRRETURN(MATCH_PRUNE);      RRETURN(MATCH_PRUNE);
735    
736      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
737      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      md->nomatch_mark = ecode + 2;
738        md->mark = NULL;    /* In case previously set by assertion */
739        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
740        eptrb, RM56);        eptrb, RM56);
741        if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
742             md->mark == NULL) md->mark = ecode + 2;
743      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
     md->mark = ecode + 2;  
744      RRETURN(MATCH_PRUNE);      RRETURN(MATCH_PRUNE);
745    
746      /* SKIP overrides PRUNE and THEN */      /* SKIP overrides PRUNE and THEN */
747    
748      case OP_SKIP:      case OP_SKIP:
749      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
750        eptrb, RM53);        eptrb, RM53);
751      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
752        RRETURN(rrc);        RRETURN(rrc);
753      md->start_match_ptr = eptr;   /* Pass back current position */      md->start_match_ptr = eptr;   /* Pass back current position */
754      MRRETURN(MATCH_SKIP);      RRETURN(MATCH_SKIP);
755    
756        /* Note that, for Perl compatibility, SKIP with an argument does NOT set
757        nomatch_mark. There is a flag that disables this opcode when re-matching a
758        pattern that ended with a SKIP for which there was not a matching MARK. */
759    
760      case OP_SKIP_ARG:      case OP_SKIP_ARG:
761      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      if (md->ignore_skip_arg)
762          {
763          ecode += PRIV(OP_lengths)[*ecode] + ecode[1];
764          break;
765          }
766        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
767        eptrb, RM57);        eptrb, RM57);
768      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
769        RRETURN(rrc);        RRETURN(rrc);
770    
771      /* 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
772      returning the special MATCH_SKIP_ARG return code. This will either be      returning the special MATCH_SKIP_ARG return code. This will either be
773      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
774      as PRUNE. */      with the md->ignore_skip_arg flag set. */
775    
776      md->start_match_ptr = ecode + 2;      md->start_match_ptr = ecode + 2;
777      RRETURN(MATCH_SKIP_ARG);      RRETURN(MATCH_SKIP_ARG);
# Line 780  for (;;) Line 781  for (;;)
781      match pointer to do this. */      match pointer to do this. */
782    
783      case OP_THEN:      case OP_THEN:
784      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
785        eptrb, RM54);        eptrb, RM54);
786      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
787      md->start_match_ptr = ecode;      md->start_match_ptr = ecode;
788      MRRETURN(MATCH_THEN);      RRETURN(MATCH_THEN);
789    
790      case OP_THEN_ARG:      case OP_THEN_ARG:
791      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top,      md->nomatch_mark = ecode + 2;
792        md->mark = NULL;    /* In case previously set by assertion */
793        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top,
794        md, eptrb, RM58);        md, eptrb, RM58);
795        if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
796             md->mark == NULL) md->mark = ecode + 2;
797      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
798      md->start_match_ptr = ecode;      md->start_match_ptr = ecode;
     md->mark = ecode + 2;  
799      RRETURN(MATCH_THEN);      RRETURN(MATCH_THEN);
800    
801      /* Handle an atomic group that does not contain any capturing parentheses.      /* Handle an atomic group that does not contain any capturing parentheses.
802      This can be handled like an assertion. Prior to 8.13, all atomic groups      This can be handled like an assertion. Prior to 8.13, all atomic groups
803      were handled this way. In 8.13, the code was changed as below for ONCE, so      were handled this way. In 8.13, the code was changed as below for ONCE, so
804      that backups pass through the group and thereby reset captured values.      that backups pass through the group and thereby reset captured values.
805      However, this uses a lot more stack, so in 8.20, atomic groups that do not      However, this uses a lot more stack, so in 8.20, atomic groups that do not
806      contain any captures generate OP_ONCE_NC, which can be handled in the old,      contain any captures generate OP_ONCE_NC, which can be handled in the old,
807      less stack intensive way.      less stack intensive way.
808    
809      Check the alternative branches in turn - the matching won't pass the KET      Check the alternative branches in turn - the matching won't pass the KET
# Line 821  for (;;) Line 825  for (;;)
825        if (rrc == MATCH_THEN)        if (rrc == MATCH_THEN)
826          {          {
827          next = ecode + GET(ecode,1);          next = ecode + GET(ecode,1);
828          if (md->start_match_ptr < next &&          if (md->start_match_ptr < next &&
829              (*ecode == OP_ALT || *next == OP_ALT))              (*ecode == OP_ALT || *next == OP_ALT))
830            rrc = MATCH_NOMATCH;            rrc = MATCH_NOMATCH;
831          }          }
832    
833        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
834        ecode += GET(ecode,1);        ecode += GET(ecode,1);
835        }        }
# Line 867  for (;;) Line 871  for (;;)
871        }        }
872      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
873        {        {
874        md->match_function_type = MATCH_CBEGROUP;        md->match_function_type = MATCH_CBEGROUP;
875        RMATCH(eptr, prev, offset_top, md, eptrb, RM66);        RMATCH(eptr, prev, offset_top, md, eptrb, RM66);
876        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
877        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
# Line 915  for (;;) Line 919  for (;;)
919        for (;;)        for (;;)
920          {          {
921          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
922          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
923            eptrb, RM1);            eptrb, RM1);
924          if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */          if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */
925    
926          /* If we backed up to a THEN, check whether it is within the current          /* If we backed up to a THEN, check whether it is within the current
927          branch by comparing the address of the THEN that is passed back with          branch by comparing the address of the THEN that is passed back with
928          the end of the branch. If it is within the current branch, and the          the end of the branch. If it is within the current branch, and the
929          branch is one of two or more alternatives (it either starts or ends          branch is one of two or more alternatives (it either starts or ends
930          with OP_ALT), we have reached the limit of THEN's action, so convert          with OP_ALT), we have reached the limit of THEN's action, so convert
931          the return code to NOMATCH, which will cause normal backtracking to          the return code to NOMATCH, which will cause normal backtracking to
932          happen from now on. Otherwise, THEN is passed back to an outer          happen from now on. Otherwise, THEN is passed back to an outer
933          alternative. This implements Perl's treatment of parenthesized groups,          alternative. This implements Perl's treatment of parenthesized groups,
934          where a group not containing | does not affect the current alternative,          where a group not containing | does not affect the current alternative,
935          that is, (X) is NOT the same as (X|(*F)). */          that is, (X) is NOT the same as (X|(*F)). */
936    
937          if (rrc == MATCH_THEN)          if (rrc == MATCH_THEN)
938            {            {
939            next = ecode + GET(ecode,1);            next = ecode + GET(ecode,1);
940            if (md->start_match_ptr < next &&            if (md->start_match_ptr < next &&
941                (*ecode == OP_ALT || *next == OP_ALT))                (*ecode == OP_ALT || *next == OP_ALT))
942              rrc = MATCH_NOMATCH;              rrc = MATCH_NOMATCH;
943            }            }
944    
945          /* Anything other than NOMATCH is passed back. */          /* Anything other than NOMATCH is passed back. */
946    
947          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
# Line 953  for (;;) Line 957  for (;;)
957    
958        /* 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. */
959    
       if (md->mark == NULL) md->mark = markptr;  
960        RRETURN(rrc);        RRETURN(rrc);
961        }        }
962    
# Line 1003  for (;;) Line 1006  for (;;)
1006    
1007        else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)        else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)
1008          {          {
1009          ecode += _pcre_OP_lengths[*ecode];          ecode += PRIV(OP_lengths)[*ecode];
1010          goto TAIL_RECURSE;          goto TAIL_RECURSE;
1011          }          }
1012    
1013        /* In all other cases, we have to make another call to match(). */        /* In all other cases, we have to make another call to match(). */
1014    
1015        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, eptrb,        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
1016          RM2);          RM2);
1017    
1018        /* See comment in the code for capturing groups above about handling        /* See comment in the code for capturing groups above about handling
1019        THEN. */        THEN. */
1020    
1021        if (rrc == MATCH_THEN)        if (rrc == MATCH_THEN)
1022          {          {
1023          next = ecode + GET(ecode,1);          next = ecode + GET(ecode,1);
1024          if (md->start_match_ptr < next &&          if (md->start_match_ptr < next &&
1025              (*ecode == OP_ALT || *next == OP_ALT))              (*ecode == OP_ALT || *next == OP_ALT))
1026            rrc = MATCH_NOMATCH;            rrc = MATCH_NOMATCH;
1027          }          }
1028    
1029        if (rrc != MATCH_NOMATCH)        if (rrc != MATCH_NOMATCH)
1030          {          {
1031          if (rrc == MATCH_ONCE)          if (rrc == MATCH_ONCE)
1032            {            {
1033            const uschar *scode = ecode;            const pcre_uchar *scode = ecode;
1034            if (*scode != OP_ONCE)           /* If not at start, find it */            if (*scode != OP_ONCE)           /* If not at start, find it */
1035              {              {
1036              while (*scode == OP_ALT) scode += GET(scode, 1);              while (*scode == OP_ALT) scode += GET(scode, 1);
# Line 1040  for (;;) Line 1043  for (;;)
1043        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1044        if (*ecode != OP_ALT) break;        if (*ecode != OP_ALT) break;
1045        }        }
1046    
     if (md->mark == NULL) md->mark = markptr;  
1047      RRETURN(MATCH_NOMATCH);      RRETURN(MATCH_NOMATCH);
1048    
1049      /* Handle possessive capturing brackets with an unlimited repeat. We come      /* Handle possessive capturing brackets with an unlimited repeat. We come
# Line 1070  for (;;) Line 1072  for (;;)
1072      if (offset < md->offset_max)      if (offset < md->offset_max)
1073        {        {
1074        matched_once = FALSE;        matched_once = FALSE;
1075        code_offset = ecode - md->start_code;        code_offset = (int)(ecode - md->start_code);
1076    
1077        save_offset1 = md->offset_vector[offset];        save_offset1 = md->offset_vector[offset];
1078        save_offset2 = md->offset_vector[offset+1];        save_offset2 = md->offset_vector[offset+1];
# Line 1093  for (;;) Line 1095  for (;;)
1095          md->offset_vector[md->offset_end - number] =          md->offset_vector[md->offset_end - number] =
1096            (int)(eptr - md->start_subject);            (int)(eptr - md->start_subject);
1097          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
1098          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
1099            eptrb, RM63);            eptrb, RM63);
1100          if (rrc == MATCH_KETRPOS)          if (rrc == MATCH_KETRPOS)
1101            {            {
# Line 1104  for (;;) Line 1106  for (;;)
1106            matched_once = TRUE;            matched_once = TRUE;
1107            continue;            continue;
1108            }            }
1109    
1110          /* See comment in the code for capturing groups above about handling          /* See comment in the code for capturing groups above about handling
1111          THEN. */          THEN. */
1112    
1113          if (rrc == MATCH_THEN)          if (rrc == MATCH_THEN)
1114            {            {
1115            next = ecode + GET(ecode,1);            next = ecode + GET(ecode,1);
1116            if (md->start_match_ptr < next &&            if (md->start_match_ptr < next &&
1117                (*ecode == OP_ALT || *next == OP_ALT))                (*ecode == OP_ALT || *next == OP_ALT))
1118              rrc = MATCH_NOMATCH;              rrc = MATCH_NOMATCH;
1119            }            }
1120    
1121          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1122          md->capture_last = save_capture_last;          md->capture_last = save_capture_last;
# Line 1129  for (;;) Line 1131  for (;;)
1131          md->offset_vector[md->offset_end - number] = save_offset3;          md->offset_vector[md->offset_end - number] = save_offset3;
1132          }          }
1133    
       if (md->mark == NULL) md->mark = markptr;  
1134        if (allow_zero || matched_once)        if (allow_zero || matched_once)
1135          {          {
1136          ecode += 1 + LINK_SIZE;          ecode += 1 + LINK_SIZE;
# Line 1161  for (;;) Line 1162  for (;;)
1162    
1163      POSSESSIVE_NON_CAPTURE:      POSSESSIVE_NON_CAPTURE:
1164      matched_once = FALSE;      matched_once = FALSE;
1165      code_offset = ecode - md->start_code;      code_offset = (int)(ecode - md->start_code);
1166    
1167      for (;;)      for (;;)
1168        {        {
1169        if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;        if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
1170        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
1171          eptrb, RM48);          eptrb, RM48);
1172        if (rrc == MATCH_KETRPOS)        if (rrc == MATCH_KETRPOS)
1173          {          {
# Line 1176  for (;;) Line 1177  for (;;)
1177          matched_once = TRUE;          matched_once = TRUE;
1178          continue;          continue;
1179          }          }
1180    
1181        /* See comment in the code for capturing groups above about handling        /* See comment in the code for capturing groups above about handling
1182        THEN. */        THEN. */
1183    
1184        if (rrc == MATCH_THEN)        if (rrc == MATCH_THEN)
1185          {          {
1186          next = ecode + GET(ecode,1);          next = ecode + GET(ecode,1);
1187          if (md->start_match_ptr < next &&          if (md->start_match_ptr < next &&
1188              (*ecode == OP_ALT || *next == OP_ALT))              (*ecode == OP_ALT || *next == OP_ALT))
1189            rrc = MATCH_NOMATCH;            rrc = MATCH_NOMATCH;
1190          }          }
1191    
1192        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1193        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
# Line 1231  for (;;) Line 1232  for (;;)
1232          cb.capture_top      = offset_top/2;          cb.capture_top      = offset_top/2;
1233          cb.capture_last     = md->capture_last;          cb.capture_last     = md->capture_last;
1234          cb.callout_data     = md->callout_data;          cb.callout_data     = md->callout_data;
1235          cb.mark             = markptr;          cb.mark             = md->nomatch_mark;
1236          if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);          if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1237          if (rrc < 0) RRETURN(rrc);          if (rrc < 0) RRETURN(rrc);
1238          }          }
1239        ecode += _pcre_OP_lengths[OP_CALLOUT];        ecode += PRIV(OP_lengths)[OP_CALLOUT];
1240        }        }
1241    
1242      condcode = ecode[LINK_SIZE+1];      condcode = ecode[LINK_SIZE+1];
# Line 1252  for (;;) Line 1253  for (;;)
1253        else        else
1254          {          {
1255          int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/          int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/
1256          condition =  (recno == RREF_ANY || recno == md->recursive->group_num);          condition = (recno == RREF_ANY || recno == md->recursive->group_num);
1257    
1258          /* If the test is for recursion into a specific subpattern, and it is          /* If the test is for recursion into a specific subpattern, and it is
1259          false, but the test was set up by name, scan the table to see if the          false, but the test was set up by name, scan the table to see if the
1260          name refers to any other numbers, and test them. The condition is true          name refers to any other numbers, and test them. The condition is true
1261          if any one is set. */          if any one is set. */
1262    
1263          if (!condition && condcode == OP_NRREF && recno != RREF_ANY)          if (!condition && condcode == OP_NRREF)
1264            {            {
1265            uschar *slotA = md->name_table;            pcre_uchar *slotA = md->name_table;
1266            for (i = 0; i < md->name_count; i++)            for (i = 0; i < md->name_count; i++)
1267              {              {
1268              if (GET2(slotA, 0) == recno) break;              if (GET2(slotA, 0) == recno) break;
# Line 1274  for (;;) Line 1275  for (;;)
1275    
1276            if (i < md->name_count)            if (i < md->name_count)
1277              {              {
1278              uschar *slotB = slotA;              pcre_uchar *slotB = slotA;
1279              while (slotB > md->name_table)              while (slotB > md->name_table)
1280                {                {
1281                slotB -= md->name_entry_size;                slotB -= md->name_entry_size;
1282                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1283                  {                  {
1284                  condition = GET2(slotB, 0) == md->recursive->group_num;                  condition = GET2(slotB, 0) == md->recursive->group_num;
1285                  if (condition) break;                  if (condition) break;
# Line 1294  for (;;) Line 1295  for (;;)
1295                for (i++; i < md->name_count; i++)                for (i++; i < md->name_count; i++)
1296                  {                  {
1297                  slotB += md->name_entry_size;                  slotB += md->name_entry_size;
1298                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                  if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1299                    {                    {
1300                    condition = GET2(slotB, 0) == md->recursive->group_num;                    condition = GET2(slotB, 0) == md->recursive->group_num;
1301                    if (condition) break;                    if (condition) break;
# Line 1307  for (;;) Line 1308  for (;;)
1308    
1309          /* Chose branch according to the condition */          /* Chose branch according to the condition */
1310    
1311          ecode += condition? 3 : GET(ecode, 1);          ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
1312          }          }
1313        }        }
1314    
# Line 1324  for (;;) Line 1325  for (;;)
1325        if (!condition && condcode == OP_NCREF)        if (!condition && condcode == OP_NCREF)
1326          {          {
1327          int refno = offset >> 1;          int refno = offset >> 1;
1328          uschar *slotA = md->name_table;          pcre_uchar *slotA = md->name_table;
1329    
1330          for (i = 0; i < md->name_count; i++)          for (i = 0; i < md->name_count; i++)
1331            {            {
# Line 1338  for (;;) Line 1339  for (;;)
1339    
1340          if (i < md->name_count)          if (i < md->name_count)
1341            {            {
1342            uschar *slotB = slotA;            pcre_uchar *slotB = slotA;
1343            while (slotB > md->name_table)            while (slotB > md->name_table)
1344              {              {
1345              slotB -= md->name_entry_size;              slotB -= md->name_entry_size;
1346              if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)              if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1347                {                {
1348                offset = GET2(slotB, 0) << 1;                offset = GET2(slotB, 0) << 1;
1349                condition = offset < offset_top &&                condition = offset < offset_top &&
# Line 1360  for (;;) Line 1361  for (;;)
1361              for (i++; i < md->name_count; i++)              for (i++; i < md->name_count; i++)
1362                {                {
1363                slotB += md->name_entry_size;                slotB += md->name_entry_size;
1364                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1365                  {                  {
1366                  offset = GET2(slotB, 0) << 1;                  offset = GET2(slotB, 0) << 1;
1367                  condition = offset < offset_top &&                  condition = offset < offset_top &&
# Line 1375  for (;;) Line 1376  for (;;)
1376    
1377        /* Chose branch according to the condition */        /* Chose branch according to the condition */
1378    
1379        ecode += condition? 3 : GET(ecode, 1);        ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
1380        }        }
1381    
1382      else if (condcode == OP_DEF)     /* DEFINE - always false */      else if (condcode == OP_DEF)     /* DEFINE - always false */
# Line 1400  for (;;) Line 1401  for (;;)
1401          ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);          ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
1402          while (*ecode == OP_ALT) ecode += GET(ecode, 1);          while (*ecode == OP_ALT) ecode += GET(ecode, 1);
1403          }          }
1404    
1405        /* PCRE doesn't allow the effect of (*THEN) to escape beyond an        /* PCRE doesn't allow the effect of (*THEN) to escape beyond an
1406        assertion; it is therefore treated as NOMATCH. */        assertion; it is therefore treated as NOMATCH. */
1407    
1408        else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)        else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
1409          {          {
1410          RRETURN(rrc);         /* Need braces because of following else */          RRETURN(rrc);         /* Need braces because of following else */
1411          }          }
# Line 1432  for (;;) Line 1433  for (;;)
1433          ecode += 1 + LINK_SIZE;          ecode += 1 + LINK_SIZE;
1434          goto TAIL_RECURSE;          goto TAIL_RECURSE;
1435          }          }
1436    
1437        md->match_function_type = MATCH_CBEGROUP;        md->match_function_type = MATCH_CBEGROUP;
1438        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49);
1439        RRETURN(rrc);        RRETURN(rrc);
# Line 1467  for (;;) Line 1468  for (;;)
1468        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
1469        if (offset_top <= offset) offset_top = offset + 2;        if (offset_top <= offset) offset_top = offset + 2;
1470        }        }
1471      ecode += 3;      ecode += 1 + IMM2_SIZE;
1472      break;      break;
1473    
1474    
# Line 1487  for (;;) Line 1488  for (;;)
1488           (md->notempty ||           (md->notempty ||
1489             (md->notempty_atstart &&             (md->notempty_atstart &&
1490               mstart == md->start_subject + md->start_offset)))               mstart == md->start_subject + md->start_offset)))
1491        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
1492    
1493      /* Otherwise, we have a match. */      /* Otherwise, we have a match. */
1494    
# Line 1496  for (;;) Line 1497  for (;;)
1497      md->start_match_ptr = mstart;       /* and the start (\K can modify) */      md->start_match_ptr = mstart;       /* and the start (\K can modify) */
1498    
1499      /* 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
1500      given as the argument to MRRETURN when the heap is in use. */      given as the argument to RRETURN when the heap is in use. */
1501    
1502      rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;      rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;
1503      MRRETURN(rrc);      RRETURN(rrc);
1504    
1505      /* Assertion brackets. Check the alternative branches in turn - the      /* Assertion brackets. Check the alternative branches in turn - the
1506      matching won't pass the KET for an assertion. If any one branch matches,      matching won't pass the KET for an assertion. If any one branch matches,
# Line 1527  for (;;) Line 1528  for (;;)
1528        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
1529          {          {
1530          mstart = md->start_match_ptr;   /* In case \K reset it */          mstart = md->start_match_ptr;   /* In case \K reset it */
         markptr = md->mark;  
1531          break;          break;
1532          }          }
1533    
1534        /* PCRE does not allow THEN to escape beyond an assertion; it is treated        /* PCRE does not allow THEN to escape beyond an assertion; it is treated
1535        as NOMATCH. */        as NOMATCH. */
1536    
1537        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1538        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1539        }        }
1540      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
1541    
1542      if (*ecode == OP_KET) MRRETURN(MATCH_NOMATCH);      if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);
1543    
1544      /* If checking an assertion for a condition, return MATCH_MATCH. */      /* If checking an assertion for a condition, return MATCH_MATCH. */
1545    
# Line 1569  for (;;) Line 1569  for (;;)
1569      do      do
1570        {        {
1571        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);
1572        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) MRRETURN(MATCH_NOMATCH);        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);
1573        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
1574          {          {
1575          do ecode += GET(ecode,1); while (*ecode == OP_ALT);          do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1576          break;          break;
1577          }          }
1578    
1579        /* PCRE does not allow THEN to escape beyond an assertion; it is treated        /* PCRE does not allow THEN to escape beyond an assertion; it is treated
1580        as NOMATCH. */        as NOMATCH. */
1581    
1582        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
# Line 1595  for (;;) Line 1595  for (;;)
1595      back a number of characters, not bytes. */      back a number of characters, not bytes. */
1596    
1597      case OP_REVERSE:      case OP_REVERSE:
1598  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1599      if (utf8)      if (utf)
1600        {        {
1601        i = GET(ecode, 1);        i = GET(ecode, 1);
1602        while (i-- > 0)        while (i-- > 0)
1603          {          {
1604          eptr--;          eptr--;
1605          if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);          if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
1606          BACKCHAR(eptr);          BACKCHAR(eptr);
1607          }          }
1608        }        }
# Line 1613  for (;;) Line 1613  for (;;)
1613    
1614        {        {
1615        eptr -= GET(ecode, 1);        eptr -= GET(ecode, 1);
1616        if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);        if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
1617        }        }
1618    
1619      /* Save the earliest consulted character, then skip to next op code */      /* Save the earliest consulted character, then skip to next op code */
# Line 1642  for (;;) Line 1642  for (;;)
1642        cb.capture_top      = offset_top/2;        cb.capture_top      = offset_top/2;
1643        cb.capture_last     = md->capture_last;        cb.capture_last     = md->capture_last;
1644        cb.callout_data     = md->callout_data;        cb.callout_data     = md->callout_data;
1645        cb.mark             = markptr;        cb.mark             = md->nomatch_mark;
1646        if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);        if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1647        if (rrc < 0) RRETURN(rrc);        if (rrc < 0) RRETURN(rrc);
1648        }        }
1649      ecode += 2 + 2*LINK_SIZE;      ecode += 2 + 2*LINK_SIZE;
# Line 1717  for (;;) Line 1717  for (;;)
1717        do        do
1718          {          {
1719          if (cbegroup) md->match_function_type = MATCH_CBEGROUP;          if (cbegroup) md->match_function_type = MATCH_CBEGROUP;
1720          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,          RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top,
1721            md, eptrb, RM6);            md, eptrb, RM6);
1722          memcpy(md->offset_vector, new_recursive.offset_save,          memcpy(md->offset_vector, new_recursive.offset_save,
1723              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
# Line 1740  for (;;) Line 1740  for (;;)
1740          /* PCRE does not allow THEN to escape beyond a recursion; it is treated          /* PCRE does not allow THEN to escape beyond a recursion; it is treated
1741          as NOMATCH. */          as NOMATCH. */
1742    
1743          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
1744            {            {
1745            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1746            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
# Line 1757  for (;;) Line 1757  for (;;)
1757        md->recursive = new_recursive.prevrec;        md->recursive = new_recursive.prevrec;
1758        if (new_recursive.offset_save != stacksave)        if (new_recursive.offset_save != stacksave)
1759          (pcre_free)(new_recursive.offset_save);          (pcre_free)(new_recursive.offset_save);
1760        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
1761        }        }
1762    
1763      RECURSION_MATCHED:      RECURSION_MATCHED:
# Line 1826  for (;;) Line 1826  for (;;)
1826        }        }
1827      else saved_eptr = NULL;      else saved_eptr = NULL;
1828    
1829      /* If we are at the end of an assertion group or a non-capturing atomic      /* If we are at the end of an assertion group or a non-capturing atomic
1830      group, stop matching and return MATCH_MATCH, but record the current high      group, stop matching and return MATCH_MATCH, but record the current high
1831      water mark for use by positive assertions. We also need to record the match      water mark for use by positive assertions. We also need to record the match
1832      start in case it was changed by \K. */      start in case it was changed by \K. */
1833    
1834      if ((*prev >= OP_ASSERT && *prev <= OP_ASSERTBACK_NOT) ||      if ((*prev >= OP_ASSERT && *prev <= OP_ASSERTBACK_NOT) ||
1835           *prev == OP_ONCE_NC)           *prev == OP_ONCE_NC)
1836        {        {
1837        md->end_match_ptr = eptr;      /* For ONCE_NC */        md->end_match_ptr = eptr;      /* For ONCE_NC */
1838        md->end_offset_top = offset_top;        md->end_offset_top = offset_top;
1839        md->start_match_ptr = mstart;        md->start_match_ptr = mstart;
1840        MRRETURN(MATCH_MATCH);         /* Sets md->mark */        RRETURN(MATCH_MATCH);         /* Sets md->mark */
1841        }        }
1842    
1843      /* For capturing groups we have to check the group number back at the start      /* For capturing groups we have to check the group number back at the start
# Line 1979  for (;;) Line 1979  for (;;)
1979      /* Not multiline mode: start of subject assertion, unless notbol. */      /* Not multiline mode: start of subject assertion, unless notbol. */
1980    
1981      case OP_CIRC:      case OP_CIRC:
1982      if (md->notbol && eptr == md->start_subject) MRRETURN(MATCH_NOMATCH);      if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
1983    
1984      /* Start of subject assertion */      /* Start of subject assertion */
1985    
1986      case OP_SOD:      case OP_SOD:
1987      if (eptr != md->start_subject) MRRETURN(MATCH_NOMATCH);      if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH);
1988      ecode++;      ecode++;
1989      break;      break;
1990    
1991      /* Multiline mode: start of subject unless notbol, or after any newline. */      /* Multiline mode: start of subject unless notbol, or after any newline. */
1992    
1993      case OP_CIRCM:      case OP_CIRCM:
1994      if (md->notbol && eptr == md->start_subject) MRRETURN(MATCH_NOMATCH);      if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
1995      if (eptr != md->start_subject &&      if (eptr != md->start_subject &&
1996          (eptr == md->end_subject || !WAS_NEWLINE(eptr)))          (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
1997        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
1998      ecode++;      ecode++;
1999      break;      break;
2000    
2001      /* Start of match assertion */      /* Start of match assertion */
2002    
2003      case OP_SOM:      case OP_SOM:
2004      if (eptr != md->start_subject + md->start_offset) MRRETURN(MATCH_NOMATCH);      if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH);
2005      ecode++;      ecode++;
2006      break;      break;
2007    
# Line 2017  for (;;) Line 2017  for (;;)
2017    
2018      case OP_DOLLM:      case OP_DOLLM:
2019      if (eptr < md->end_subject)      if (eptr < md->end_subject)
2020        { if (!IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); }        { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }
2021      else      else
2022        {        {
2023        if (md->noteol) MRRETURN(MATCH_NOMATCH);        if (md->noteol) RRETURN(MATCH_NOMATCH);
2024        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2025        }        }
2026      ecode++;      ecode++;
# Line 2030  for (;;) Line 2030  for (;;)
2030      subject unless noteol is set. */      subject unless noteol is set. */
2031    
2032      case OP_DOLL:      case OP_DOLL:
2033      if (md->noteol) MRRETURN(MATCH_NOMATCH);      if (md->noteol) RRETURN(MATCH_NOMATCH);
2034      if (!md->endonly) goto ASSERT_NL_OR_EOS;      if (!md->endonly) goto ASSERT_NL_OR_EOS;
2035    
2036      /* ... else fall through for endonly */      /* ... else fall through for endonly */
# Line 2038  for (;;) Line 2038  for (;;)
2038      /* End of subject assertion (\z) */      /* End of subject assertion (\z) */
2039    
2040      case OP_EOD:      case OP_EOD:
2041      if (eptr < md->end_subject) MRRETURN(MATCH_NOMATCH);      if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH);
2042      SCHECK_PARTIAL();      SCHECK_PARTIAL();
2043      ecode++;      ecode++;
2044      break;      break;
# Line 2049  for (;;) Line 2049  for (;;)
2049      ASSERT_NL_OR_EOS:      ASSERT_NL_OR_EOS:
2050      if (eptr < md->end_subject &&      if (eptr < md->end_subject &&
2051          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
2052        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2053    
2054      /* Either at end of string or \n before end. */      /* Either at end of string or \n before end. */
2055    
# Line 2068  for (;;) Line 2068  for (;;)
2068        be "non-word" characters. Remember the earliest consulted character for        be "non-word" characters. Remember the earliest consulted character for
2069        partial matching. */        partial matching. */
2070    
2071  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2072        if (utf8)        if (utf)
2073          {          {
2074          /* Get status of previous character */          /* Get status of previous character */
2075    
2076          if (eptr == md->start_subject) prev_is_word = FALSE; else          if (eptr == md->start_subject) prev_is_word = FALSE; else
2077            {            {
2078            USPTR lastptr = eptr - 1;            PCRE_PUCHAR lastptr = eptr - 1;
2079            while((*lastptr & 0xc0) == 0x80) lastptr--;            BACKCHAR(lastptr);
2080            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
2081            GETCHAR(c, lastptr);            GETCHAR(c, lastptr);
2082  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2171  for (;;) Line 2171  for (;;)
2171    
2172        if ((*ecode++ == OP_WORD_BOUNDARY)?        if ((*ecode++ == OP_WORD_BOUNDARY)?
2173             cur_is_word == prev_is_word : cur_is_word != prev_is_word)             cur_is_word == prev_is_word : cur_is_word != prev_is_word)
2174          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2175        }        }
2176      break;      break;
2177    
2178      /* Match a single character type; inline for speed */      /* Match a single character type; inline for speed */
2179    
2180      case OP_ANY:      case OP_ANY:
2181      if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
2182      /* Fall through */      /* Fall through */
2183    
2184      case OP_ALLANY:      case OP_ALLANY:
2185      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 */
2186        {                            /* not be updated before SCHECK_PARTIAL. */        {                            /* not be updated before SCHECK_PARTIAL. */
2187        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2188        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2189        }        }
2190      eptr++;      eptr++;
2191      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;  #ifdef SUPPORT_UTF
2192        if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
2193    #endif
2194      ecode++;      ecode++;
2195      break;      break;
2196    
# Line 2199  for (;;) Line 2201  for (;;)
2201      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 */
2202        {                            /* not be updated before SCHECK_PARTIAL. */        {                            /* not be updated before SCHECK_PARTIAL. */
2203        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2204        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2205        }        }
2206      eptr++;      eptr++;
2207      ecode++;      ecode++;
# Line 2209  for (;;) Line 2211  for (;;)
2211      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2212        {        {
2213        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2214        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2215        }        }
2216      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2217      if (      if (
2218  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2219         c < 256 &&         c < 256 &&
2220  #endif  #endif
2221         (md->ctypes[c] & ctype_digit) != 0         (md->ctypes[c] & ctype_digit) != 0
2222         )         )
2223        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2224      ecode++;      ecode++;
2225      break;      break;
2226    
# Line 2226  for (;;) Line 2228  for (;;)
2228      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2229        {        {
2230        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2231        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2232        }        }
2233      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2234      if (      if (
2235  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2236         c >= 256 ||         c > 255 ||
2237  #endif  #endif
2238         (md->ctypes[c] & ctype_digit) == 0         (md->ctypes[c] & ctype_digit) == 0
2239         )         )
2240        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2241      ecode++;      ecode++;
2242      break;      break;
2243    
# Line 2243  for (;;) Line 2245  for (;;)
2245      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2246        {        {
2247        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2248        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2249        }        }
2250      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2251      if (      if (
2252  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2253         c < 256 &&         c < 256 &&
2254  #endif  #endif
2255         (md->ctypes[c] & ctype_space) != 0         (md->ctypes[c] & ctype_space) != 0
2256         )         )
2257        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2258      ecode++;      ecode++;
2259      break;      break;
2260    
# Line 2260  for (;;) Line 2262  for (;;)
2262      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2263        {        {
2264        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2265        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2266        }        }
2267      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2268      if (      if (
2269  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2270         c >= 256 ||         c > 255 ||
2271  #endif  #endif
2272         (md->ctypes[c] & ctype_space) == 0         (md->ctypes[c] & ctype_space) == 0
2273         )         )
2274        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2275      ecode++;      ecode++;
2276      break;      break;
2277    
# Line 2277  for (;;) Line 2279  for (;;)
2279      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2280        {        {
2281        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2282        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2283        }        }
2284      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2285      if (      if (
2286  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2287         c < 256 &&         c < 256 &&
2288  #endif  #endif
2289         (md->ctypes[c] & ctype_word) != 0         (md->ctypes[c] & ctype_word) != 0
2290         )         )
2291        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2292      ecode++;      ecode++;
2293      break;      break;
2294    
# Line 2294  for (;;) Line 2296  for (;;)
2296      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2297        {        {
2298        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2299        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2300        }        }
2301      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2302      if (      if (
2303  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2304         c >= 256 ||         c > 255 ||
2305  #endif  #endif
2306         (md->ctypes[c] & ctype_word) == 0         (md->ctypes[c] & ctype_word) == 0
2307         )         )
2308        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2309      ecode++;      ecode++;
2310      break;      break;
2311    
# Line 2311  for (;;) Line 2313  for (;;)
2313      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2314        {        {
2315        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2316        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2317        }        }
2318      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2319      switch(c)      switch(c)
2320        {        {
2321        default: MRRETURN(MATCH_NOMATCH);        default: RRETURN(MATCH_NOMATCH);
2322    
2323        case 0x000d:        case 0x000d:
2324        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
# Line 2330  for (;;) Line 2332  for (;;)
2332        case 0x0085:        case 0x0085:
2333        case 0x2028:        case 0x2028:
2334        case 0x2029:        case 0x2029:
2335        if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);        if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
2336        break;        break;
2337        }        }
2338      ecode++;      ecode++;
# Line 2340  for (;;) Line 2342  for (;;)
2342      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2343        {        {
2344        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2345        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2346        }        }
2347      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2348      switch(c)      switch(c)
# Line 2365  for (;;) Line 2367  for (;;)
2367        case 0x202f:    /* NARROW NO-BREAK SPACE */        case 0x202f:    /* NARROW NO-BREAK SPACE */
2368        case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */        case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
2369        case 0x3000:    /* IDEOGRAPHIC SPACE */        case 0x3000:    /* IDEOGRAPHIC SPACE */
2370        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2371        }        }
2372      ecode++;      ecode++;
2373      break;      break;
# Line 2374  for (;;) Line 2376  for (;;)
2376      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2377        {        {
2378        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2379        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2380        }        }
2381      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2382      switch(c)      switch(c)
2383        {        {
2384        default: MRRETURN(MATCH_NOMATCH);        default: RRETURN(MATCH_NOMATCH);
2385        case 0x09:      /* HT */        case 0x09:      /* HT */
2386        case 0x20:      /* SPACE */        case 0x20:      /* SPACE */
2387        case 0xa0:      /* NBSP */        case 0xa0:      /* NBSP */
# Line 2408  for (;;) Line 2410  for (;;)
2410      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2411        {        {
2412        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2413        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2414        }        }
2415      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2416      switch(c)      switch(c)
# Line 2421  for (;;) Line 2423  for (;;)
2423        case 0x85:      /* NEL */        case 0x85:      /* NEL */
2424        case 0x2028:    /* LINE SEPARATOR */        case 0x2028:    /* LINE SEPARATOR */
2425        case 0x2029:    /* PARAGRAPH SEPARATOR */        case 0x2029:    /* PARAGRAPH SEPARATOR */
2426        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2427        }        }
2428      ecode++;      ecode++;
2429      break;      break;
# Line 2430  for (;;) Line 2432  for (;;)
2432      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2433        {        {
2434        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2435        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2436        }        }
2437      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2438      switch(c)      switch(c)
2439        {        {
2440        default: MRRETURN(MATCH_NOMATCH);        default: RRETURN(MATCH_NOMATCH);
2441        case 0x0a:      /* LF */        case 0x0a:      /* LF */
2442        case 0x0b:      /* VT */        case 0x0b:      /* VT */
2443        case 0x0c:      /* FF */        case 0x0c:      /* FF */
# Line 2457  for (;;) Line 2459  for (;;)
2459      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2460        {        {
2461        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2462        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2463        }        }
2464      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2465        {        {
# Line 2466  for (;;) Line 2468  for (;;)
2468        switch(ecode[1])        switch(ecode[1])
2469          {          {
2470          case PT_ANY:          case PT_ANY:
2471          if (op == OP_NOTPROP) MRRETURN(MATCH_NOMATCH);          if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
2472          break;          break;
2473    
2474          case PT_LAMP:          case PT_LAMP:
2475          if ((prop->chartype == ucp_Lu ||          if ((prop->chartype == ucp_Lu ||
2476               prop->chartype == ucp_Ll ||               prop->chartype == ucp_Ll ||
2477               prop->chartype == ucp_Lt) == (op == OP_NOTPROP))               prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
2478            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2479          break;          break;
2480    
2481          case PT_GC:          case PT_GC:
2482          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))          if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP))
2483            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2484          break;          break;
2485    
2486          case PT_PC:          case PT_PC:
2487          if ((ecode[2] != prop->chartype) == (op == OP_PROP))          if ((ecode[2] != prop->chartype) == (op == OP_PROP))
2488            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2489          break;          break;
2490    
2491          case PT_SC:          case PT_SC:
2492          if ((ecode[2] != prop->script) == (op == OP_PROP))          if ((ecode[2] != prop->script) == (op == OP_PROP))
2493            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2494          break;          break;
2495    
2496          /* These are specials */          /* These are specials */
2497    
2498          case PT_ALNUM:          case PT_ALNUM:
2499          if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
2500               _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP))               PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
2501            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2502          break;          break;
2503    
2504          case PT_SPACE:    /* Perl space */          case PT_SPACE:    /* Perl space */
2505          if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
2506               c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)               c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
2507                 == (op == OP_NOTPROP))                 == (op == OP_NOTPROP))
2508            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2509          break;          break;
2510    
2511          case PT_PXSPACE:  /* POSIX space */          case PT_PXSPACE:  /* POSIX space */
2512          if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
2513               c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||               c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
2514               c == CHAR_FF || c == CHAR_CR)               c == CHAR_FF || c == CHAR_CR)
2515                 == (op == OP_NOTPROP))                 == (op == OP_NOTPROP))
2516            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2517          break;          break;
2518    
2519          case PT_WORD:          case PT_WORD:
2520          if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
2521               _pcre_ucp_gentype[prop->chartype] == ucp_N ||               PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
2522               c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))               c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
2523            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2524          break;          break;
2525    
2526          /* This should never occur */          /* This should never occur */
# Line 2538  for (;;) Line 2540  for (;;)
2540      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2541        {        {
2542        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2543        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2544        }        }
2545      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2546      if (UCD_CATEGORY(c) == ucp_M) MRRETURN(MATCH_NOMATCH);      if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
2547      while (eptr < md->end_subject)      while (eptr < md->end_subject)
2548        {        {
2549        int len = 1;        int len = 1;
2550        if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }        if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
2551        if (UCD_CATEGORY(c) != ucp_M) break;        if (UCD_CATEGORY(c) != ucp_M) break;
2552        eptr += len;        eptr += len;
2553        }        }
# Line 2566  for (;;) Line 2568  for (;;)
2568      case OP_REFI:      case OP_REFI:
2569      caseless = op == OP_REFI;      caseless = op == OP_REFI;
2570      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */
2571      ecode += 3;      ecode += 1 + IMM2_SIZE;
2572    
2573      /* If the reference is unset, there are two possibilities:      /* If the reference is unset, there are two possibilities:
2574    
# Line 2606  for (;;) Line 2608  for (;;)
2608        case OP_CRMINRANGE:        case OP_CRMINRANGE:
2609        minimize = (*ecode == OP_CRMINRANGE);        minimize = (*ecode == OP_CRMINRANGE);
2610        min = GET2(ecode, 1);        min = GET2(ecode, 1);
2611        max = GET2(ecode, 3);        max = GET2(ecode, 1 + IMM2_SIZE);
2612        if (max == 0) max = INT_MAX;        if (max == 0) max = INT_MAX;
2613        ecode += 5;        ecode += 1 + 2 * IMM2_SIZE;
2614        break;        break;
2615    
2616        default:               /* No repeat follows */        default:               /* No repeat follows */
2617        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)
2618          {          {
2619          CHECK_PARTIAL();          CHECK_PARTIAL();
2620          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2621          }          }
2622        eptr += length;        eptr += length;
2623        continue;              /* With the main loop */        continue;              /* With the main loop */
# Line 2636  for (;;) Line 2638  for (;;)
2638        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2639          {          {
2640          CHECK_PARTIAL();          CHECK_PARTIAL();
2641          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2642          }          }
2643        eptr += slength;        eptr += slength;
2644        }        }
# Line 2655  for (;;) Line 2657  for (;;)
2657          int slength;          int slength;
2658          RMATCH(eptr, ecode, offset_top, md, eptrb, RM14);          RMATCH(eptr, ecode, offset_top, md, eptrb, RM14);
2659          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2660          if (fi >= max) MRRETURN(MATCH_NOMATCH);          if (fi >= max) RRETURN(MATCH_NOMATCH);
2661          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2662            {            {
2663            CHECK_PARTIAL();            CHECK_PARTIAL();
2664            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2665            }            }
2666          eptr += slength;          eptr += slength;
2667          }          }
# Line 2687  for (;;) Line 2689  for (;;)
2689          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2690          eptr -= length;          eptr -= length;
2691          }          }
2692        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2693        }        }
2694      /* Control never gets here */      /* Control never gets here */
2695    
# Line 2705  for (;;) Line 2707  for (;;)
2707      case OP_NCLASS:      case OP_NCLASS:
2708      case OP_CLASS:      case OP_CLASS:
2709        {        {
2710          /* The data variable is saved across frames, so the byte map needs to
2711          be stored there. */
2712    #define BYTE_MAP ((pcre_uint8 *)data)
2713        data = ecode + 1;                /* Save for matching */        data = ecode + 1;                /* Save for matching */
2714        ecode += 33;                     /* Advance past the item */        ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */
2715    
2716        switch (*ecode)        switch (*ecode)
2717          {          {
# Line 2727  for (;;) Line 2732  for (;;)
2732          case OP_CRMINRANGE:          case OP_CRMINRANGE:
2733          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
2734          min = GET2(ecode, 1);          min = GET2(ecode, 1);
2735          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
2736          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
2737          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
2738          break;          break;
2739    
2740          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2739  for (;;) Line 2744  for (;;)
2744    
2745        /* First, ensure the minimum number of matches are present. */        /* First, ensure the minimum number of matches are present. */
2746    
2747  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2748        /* UTF-8 mode */        if (utf)
       if (utf8)  
2749          {          {
2750          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2751            {            {
2752            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2753              {              {
2754              SCHECK_PARTIAL();              SCHECK_PARTIAL();
2755              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2756              }              }
2757            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
2758            if (c > 255)            if (c > 255)
2759              {              {
2760              if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2761              }              }
2762            else            else
2763              {              if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
             if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);  
             }  
2764            }            }
2765          }          }
2766        else        else
2767  #endif  #endif
2768        /* Not UTF-8 mode */        /* Not UTF mode */
2769          {          {
2770          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2771            {            {
2772            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2773              {              {
2774              SCHECK_PARTIAL();              SCHECK_PARTIAL();
2775              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2776              }              }
2777            c = *eptr++;            c = *eptr++;
2778            if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2779              if (c > 255)
2780                {
2781                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2782                }
2783              else
2784    #endif
2785                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2786            }            }
2787          }          }
2788    
# Line 2787  for (;;) Line 2796  for (;;)
2796    
2797        if (minimize)        if (minimize)
2798          {          {
2799  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2800          /* UTF-8 mode */          if (utf)
         if (utf8)  
2801            {            {
2802            for (fi = min;; fi++)            for (fi = min;; fi++)
2803              {              {
2804              RMATCH(eptr, ecode, offset_top, md, eptrb, RM16);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM16);
2805              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2806              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
2807              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
2808                {                {
2809                SCHECK_PARTIAL();                SCHECK_PARTIAL();
2810                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
2811                }                }
2812              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
2813              if (c > 255)              if (c > 255)
2814                {                {
2815                if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2816                }                }
2817              else              else
2818                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
               if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);  
               }  
2819              }              }
2820            }            }
2821          else          else
2822  #endif  #endif
2823          /* Not UTF-8 mode */          /* Not UTF mode */
2824            {            {
2825            for (fi = min;; fi++)            for (fi = min;; fi++)
2826              {              {
2827              RMATCH(eptr, ecode, offset_top, md, eptrb, RM17);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM17);
2828              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2829              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
2830              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
2831                {                {
2832                SCHECK_PARTIAL();                SCHECK_PARTIAL();
2833                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
2834                }                }
2835              c = *eptr++;              c = *eptr++;
2836              if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2837                if (c > 255)
2838                  {
2839                  if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2840                  }
2841                else
2842    #endif
2843                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2844              }              }
2845            }            }
2846          /* Control never gets here */          /* Control never gets here */
# Line 2839  for (;;) Line 2852  for (;;)
2852          {          {
2853          pp = eptr;          pp = eptr;
2854    
2855  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2856          /* UTF-8 mode */          if (utf)
         if (utf8)  
2857            {            {
2858            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2859              {              {
# Line 2857  for (;;) Line 2869  for (;;)
2869                if (op == OP_CLASS) break;                if (op == OP_CLASS) break;
2870                }                }
2871              else              else
2872                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
               if ((data[c/8] & (1 << (c&7))) == 0) break;  
               }  
2873              eptr += len;              eptr += len;
2874              }              }
2875            for (;;)            for (;;)
# Line 2872  for (;;) Line 2882  for (;;)
2882            }            }
2883          else          else
2884  #endif  #endif
2885            /* Not UTF-8 mode */            /* Not UTF mode */
2886            {            {
2887            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2888              {              {
# Line 2882  for (;;) Line 2892  for (;;)
2892                break;                break;
2893                }                }
2894              c = *eptr;              c = *eptr;
2895              if ((data[c/8] & (1 << (c&7))) == 0) break;  #ifndef COMPILE_PCRE8
2896                if (c > 255)
2897                  {
2898                  if (op == OP_CLASS) break;
2899                  }
2900                else
2901    #endif
2902                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
2903              eptr++;              eptr++;
2904              }              }
2905            while (eptr >= pp)            while (eptr >= pp)
# Line 2893  for (;;) Line 2910  for (;;)
2910              }              }
2911            }            }
2912    
2913          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2914          }          }
2915    #undef BYTE_MAP
2916        }        }
2917      /* Control never gets here */      /* Control never gets here */
2918    
# Line 2903  for (;;) Line 2921  for (;;)
2921      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
2922      mode, because Unicode properties are supported in non-UTF-8 mode. */      mode, because Unicode properties are supported in non-UTF-8 mode. */
2923    
2924  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2925      case OP_XCLASS:      case OP_XCLASS:
2926        {        {
2927        data = ecode + 1 + LINK_SIZE;                /* Save for matching */        data = ecode + 1 + LINK_SIZE;                /* Save for matching */
# Line 2928  for (;;) Line 2946  for (;;)
2946          case OP_CRMINRANGE:          case OP_CRMINRANGE:
2947          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
2948          min = GET2(ecode, 1);          min = GET2(ecode, 1);
2949          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
2950          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
2951          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
2952          break;          break;
2953    
2954          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2945  for (;;) Line 2963  for (;;)
2963          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
2964            {            {
2965            SCHECK_PARTIAL();            SCHECK_PARTIAL();
2966            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2967            }            }
2968          GETCHARINCTEST(c, eptr);          GETCHARINCTEST(c, eptr);
2969          if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);          if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
2970          }          }
2971    
2972        /* If max == min we can continue with the main loop without the        /* If max == min we can continue with the main loop without the
# Line 2965  for (;;) Line 2983  for (;;)
2983            {            {
2984            RMATCH(eptr, ecode, offset_top, md, eptrb, RM20);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM20);
2985            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2986            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
2987            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2988              {              {
2989              SCHECK_PARTIAL();              SCHECK_PARTIAL();
2990              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2991              }              }
2992            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
2993            if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);            if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
2994            }            }
2995          /* Control never gets here */          /* Control never gets here */
2996          }          }
# Line 2990  for (;;) Line 3008  for (;;)
3008              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3009              break;              break;
3010              }              }
3011    #ifdef SUPPORT_UTF
3012            GETCHARLENTEST(c, eptr, len);            GETCHARLENTEST(c, eptr, len);
3013            if (!_pcre_xclass(c, data)) break;  #else
3014              c = *eptr;
3015    #endif
3016              if (!PRIV(xclass)(c, data, utf)) break;
3017            eptr += len;            eptr += len;
3018            }            }
3019          for(;;)          for(;;)
# Line 2999  for (;;) Line 3021  for (;;)
3021            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
3022            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3023            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
3024            if (utf8) BACKCHAR(eptr);  #ifdef SUPPORT_UTF
3025              if (utf) BACKCHAR(eptr);
3026    #endif
3027            }            }
3028          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3029          }          }
3030    
3031        /* Control never gets here */        /* Control never gets here */
# Line 3011  for (;;) Line 3035  for (;;)
3035      /* Match a single character, casefully */      /* Match a single character, casefully */
3036    
3037      case OP_CHAR:      case OP_CHAR:
3038  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3039      if (utf8)      if (utf)
3040        {        {
3041        length = 1;        length = 1;
3042        ecode++;        ecode++;
# Line 3020  for (;;) Line 3044  for (;;)
3044        if (length > md->end_subject - eptr)        if (length > md->end_subject - eptr)
3045          {          {
3046          CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */          CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
3047          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3048          }          }
3049        while (length-- > 0) if (*ecode++ != *eptr++) MRRETURN(MATCH_NOMATCH);        while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);
3050        }        }
3051      else      else
3052  #endif  #endif
3053        /* Not UTF mode */
     /* Non-UTF-8 mode */  
3054        {        {
3055        if (md->end_subject - eptr < 1)        if (md->end_subject - eptr < 1)
3056          {          {
3057          SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */          SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
3058          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3059          }          }
3060        if (ecode[1] != *eptr++) MRRETURN(MATCH_NOMATCH);        if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);
3061        ecode += 2;        ecode += 2;
3062        }        }
3063      break;      break;
3064    
3065      /* Match a single character, caselessly */      /* Match a single character, caselessly. If we are at the end of the
3066        subject, give up immediately. */
3067    
3068      case OP_CHARI:      case OP_CHARI:
3069  #ifdef SUPPORT_UTF8      if (eptr >= md->end_subject)
3070      if (utf8)        {
3071          SCHECK_PARTIAL();
3072          RRETURN(MATCH_NOMATCH);
3073          }
3074    
3075    #ifdef SUPPORT_UTF
3076        if (utf)
3077        {        {
3078        length = 1;        length = 1;
3079        ecode++;        ecode++;
3080        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
3081    
       if (length > md->end_subject - eptr)  
         {  
         CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */  
         MRRETURN(MATCH_NOMATCH);  
         }  
   
3082        /* 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
3083        can use the fast lookup table. */        we know that its other case must also be one byte long, so we can use the
3084          fast lookup table. We know that there is at least one byte left in the
3085          subject. */
3086    
3087        if (fc < 128)        if (fc < 128)
3088          {          {
3089          if (md->lcc[*ecode++] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);          if (md->lcc[fc]
3090                != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3091            ecode++;
3092            eptr++;
3093          }          }
3094    
3095        /* Otherwise we must pick up the subject character */        /* Otherwise we must pick up the subject character. Note that we cannot
3096          use the value of "length" to check for sufficient bytes left, because the
3097          other case of the character may have more or fewer bytes.  */
3098    
3099        else        else
3100          {          {
# Line 3079  for (;;) Line 3110  for (;;)
3110  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3111            if (dc != UCD_OTHERCASE(fc))            if (dc != UCD_OTHERCASE(fc))
3112  #endif  #endif
3113              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3114            }            }
3115          }          }
3116        }        }
3117      else      else
3118  #endif   /* SUPPORT_UTF8 */  #endif   /* SUPPORT_UTF */
3119    
3120      /* Non-UTF-8 mode */      /* Not UTF mode */
3121        {        {
3122        if (md->end_subject - eptr < 1)        if (TABLE_GET(ecode[1], md->lcc, ecode[1])
3123          {            != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3124          SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */        eptr++;
         MRRETURN(MATCH_NOMATCH);  
         }  
       if (md->lcc[ecode[1]] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);  
3125        ecode += 2;        ecode += 2;
3126        }        }
3127      break;      break;
# Line 3103  for (;;) Line 3131  for (;;)
3131      case OP_EXACT:      case OP_EXACT:
3132      case OP_EXACTI:      case OP_EXACTI:
3133      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3134      ecode += 3;      ecode += 1 + IMM2_SIZE;
3135      goto REPEATCHAR;      goto REPEATCHAR;
3136    
3137      case OP_POSUPTO:      case OP_POSUPTO:
# Line 3118  for (;;) Line 3146  for (;;)
3146      min = 0;      min = 0;
3147      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3148      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;
3149      ecode += 3;      ecode += 1 + IMM2_SIZE;
3150      goto REPEATCHAR;      goto REPEATCHAR;
3151    
3152      case OP_POSSTAR:      case OP_POSSTAR:
# Line 3166  for (;;) Line 3194  for (;;)
3194      /* Common code for all repeated single-character matches. */      /* Common code for all repeated single-character matches. */
3195    
3196      REPEATCHAR:      REPEATCHAR:
3197  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3198      if (utf8)      if (utf)
3199        {        {
3200        length = 1;        length = 1;
3201        charptr = ecode;        charptr = ecode;
# Line 3183  for (;;) Line 3211  for (;;)
3211          unsigned int othercase;          unsigned int othercase;
3212          if (op >= OP_STARI &&     /* Caseless */          if (op >= OP_STARI &&     /* Caseless */
3213              (othercase = UCD_OTHERCASE(fc)) != fc)              (othercase = UCD_OTHERCASE(fc)) != fc)
3214            oclength = _pcre_ord2utf8(othercase, occhars);            oclength = PRIV(ord2utf)(othercase, occhars);
3215          else oclength = 0;          else oclength = 0;
3216  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3217    
3218          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3219            {            {
3220            if (eptr <= md->end_subject - length &&            if (eptr <= md->end_subject - length &&
3221              memcmp(eptr, charptr, length) == 0) eptr += length;              memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3222  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3223            else if (oclength > 0 &&            else if (oclength > 0 &&
3224                     eptr <= md->end_subject - oclength &&                     eptr <= md->end_subject - oclength &&
3225                     memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                     memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3226  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3227            else            else
3228              {              {
3229              CHECK_PARTIAL();              CHECK_PARTIAL();
3230              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3231              }              }
3232            }            }
3233    
# Line 3211  for (;;) Line 3239  for (;;)
3239              {              {
3240              RMATCH(eptr, ecode, offset_top, md, eptrb, RM22);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM22);
3241              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3242              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3243              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3244                memcmp(eptr, charptr, length) == 0) eptr += length;                memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3245  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3246              else if (oclength > 0 &&              else if (oclength > 0 &&
3247                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3248                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3249  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3250              else              else
3251                {                {
3252                CHECK_PARTIAL();                CHECK_PARTIAL();
3253                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3254                }                }
3255              }              }
3256            /* Control never gets here */            /* Control never gets here */
# Line 3234  for (;;) Line 3262  for (;;)
3262            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3263              {              {
3264              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3265                  memcmp(eptr, charptr, length) == 0) eptr += length;                  memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3266  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3267              else if (oclength > 0 &&              else if (oclength > 0 &&
3268                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3269                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3270  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3271              else              else
3272                {                {
# Line 3253  for (;;) Line 3281  for (;;)
3281              {              {
3282              RMATCH(eptr, ecode, offset_top, md, eptrb, RM23);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM23);
3283              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3284              if (eptr == pp) { MRRETURN(MATCH_NOMATCH); }              if (eptr == pp) { RRETURN(MATCH_NOMATCH); }
3285  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3286              eptr--;              eptr--;
3287              BACKCHAR(eptr);              BACKCHAR(eptr);
# Line 3270  for (;;) Line 3298  for (;;)
3298        value of fc will always be < 128. */        value of fc will always be < 128. */
3299        }        }
3300      else      else
3301  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
3302          /* When not in UTF-8 mode, load a single-byte character. */
3303          fc = *ecode++;
3304    
3305      /* When not in UTF-8 mode, load a single-byte character. */      /* The value of fc at this point is always one character, though we may
3306        or may not be in UTF mode. The code is duplicated for the caseless and
     fc = *ecode++;  
   
     /* 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  
3307      caseful cases, for speed, since matching characters is likely to be quite      caseful cases, for speed, since matching characters is likely to be quite
3308      common. First, ensure the minimum number of matches are present. If min =      common. First, ensure the minimum number of matches are present. If min =
3309      max, continue at the same level without recursing. Otherwise, if      max, continue at the same level without recursing. Otherwise, if
# Line 3290  for (;;) Line 3316  for (;;)
3316    
3317      if (op >= OP_STARI)  /* Caseless */      if (op >= OP_STARI)  /* Caseless */
3318        {        {
3319        fc = md->lcc[fc];  #ifdef COMPILE_PCRE8
3320          /* fc must be < 128 if UTF is enabled. */
3321          foc = md->fcc[fc];
3322    #else
3323    #ifdef SUPPORT_UTF
3324    #ifdef SUPPORT_UCP
3325          if (utf && fc > 127)
3326            foc = UCD_OTHERCASE(fc);
3327    #else
3328          if (utf && fc > 127)
3329            foc = fc;
3330    #endif /* SUPPORT_UCP */
3331          else
3332    #endif /* SUPPORT_UTF */
3333            foc = TABLE_GET(fc, md->fcc, fc);
3334    #endif /* COMPILE_PCRE8 */
3335    
3336        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
3337          {          {
3338          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
3339            {            {
3340            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3341            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3342            }            }
3343          if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);          if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
3344            eptr++;
3345          }          }
3346        if (min == max) continue;        if (min == max) continue;
3347        if (minimize)        if (minimize)
# Line 3307  for (;;) Line 3350  for (;;)
3350            {            {
3351            RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);
3352            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3353            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
3354            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3355              {              {
3356              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3357              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3358              }              }
3359            if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);            if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
3360              eptr++;
3361            }            }
3362          /* Control never gets here */          /* Control never gets here */
3363          }          }
# Line 3327  for (;;) Line 3371  for (;;)
3371              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3372              break;              break;
3373              }              }
3374            if (fc != md->lcc[*eptr]) break;            if (fc != *eptr && foc != *eptr) break;
3375            eptr++;            eptr++;
3376            }            }
3377    
# Line 3339  for (;;) Line 3383  for (;;)
3383            eptr--;            eptr--;
3384            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3385            }            }
3386          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3387          }          }
3388        /* Control never gets here */        /* Control never gets here */
3389        }        }
# Line 3353  for (;;) Line 3397  for (;;)
3397          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
3398            {            {
3399            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3400            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3401            }            }
3402          if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);          if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
3403          }          }
3404    
3405        if (min == max) continue;        if (min == max) continue;
# Line 3366  for (;;) Line 3410  for (;;)
3410            {            {
3411            RMATCH(eptr, ecode, offset_top, md, eptrb, RM26);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM26);
3412            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3413            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
3414            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3415              {              {
3416              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3417              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3418              }              }
3419            if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);            if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
3420            }            }
3421          /* Control never gets here */          /* Control never gets here */
3422          }          }
# Line 3397  for (;;) Line 3441  for (;;)
3441            eptr--;            eptr--;
3442            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3443            }            }
3444          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3445          }          }
3446        }        }
3447      /* Control never gets here */      /* Control never gets here */
# Line 3410  for (;;) Line 3454  for (;;)
3454      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
3455        {        {
3456        SCHECK_PARTIAL();        SCHECK_PARTIAL();
3457        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
3458        }        }
3459      ecode++;      ecode++;
3460      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
3461      if (op == OP_NOTI)         /* The caseless case */      if (op == OP_NOTI)         /* The caseless case */
3462        {        {
3463  #ifdef SUPPORT_UTF8        register int ch, och;
3464        if (c < 256)        ch = *ecode++;
3465  #endif  #ifdef COMPILE_PCRE8
3466        c = md->lcc[c];        /* ch must be < 128 if UTF is enabled. */
3467        if (md->lcc[*ecode++] == c) MRRETURN(MATCH_NOMATCH);        och = md->fcc[ch];
3468    #else
3469    #ifdef SUPPORT_UTF
3470    #ifdef SUPPORT_UCP
3471          if (utf && ch > 127)
3472            och = UCD_OTHERCASE(ch);
3473    #else
3474          if (utf && ch > 127)
3475            och = ch;
3476    #endif /* SUPPORT_UCP */
3477          else
3478    #endif /* SUPPORT_UTF */
3479            och = TABLE_GET(ch, md->fcc, ch);
3480    #endif /* COMPILE_PCRE8 */
3481          if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
3482        }        }
3483      else    /* Caseful */      else    /* Caseful */
3484        {        {
3485        if (*ecode++ == c) MRRETURN(MATCH_NOMATCH);        if (*ecode++ == c) RRETURN(MATCH_NOMATCH);
3486        }        }
3487      break;      break;
3488    
# Line 3438  for (;;) Line 3496  for (;;)
3496      case OP_NOTEXACT:      case OP_NOTEXACT:
3497      case OP_NOTEXACTI:      case OP_NOTEXACTI:
3498      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3499      ecode += 3;      ecode += 1 + IMM2_SIZE;
3500      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3501    
3502      case OP_NOTUPTO:      case OP_NOTUPTO:
# Line 3448  for (;;) Line 3506  for (;;)
3506      min = 0;      min = 0;
3507      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3508      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;
3509      ecode += 3;      ecode += 1 + IMM2_SIZE;
3510      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3511    
3512      case OP_NOTPOSSTAR:      case OP_NOTPOSSTAR:
# Line 3480  for (;;) Line 3538  for (;;)
3538      possessive = TRUE;      possessive = TRUE;
3539      min = 0;      min = 0;
3540      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3541      ecode += 3;      ecode += 1 + IMM2_SIZE;
3542      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3543    
3544      case OP_NOTSTAR:      case OP_NOTSTAR:
# Line 3519  for (;;) Line 3577  for (;;)
3577    
3578      if (op >= OP_NOTSTARI)     /* Caseless */      if (op >= OP_NOTSTARI)     /* Caseless */
3579        {        {
3580        fc = md->lcc[fc];  #ifdef COMPILE_PCRE8
3581          /* fc must be < 128 if UTF is enabled. */
3582          foc = md->fcc[fc];
3583    #else
3584    #ifdef SUPPORT_UTF
3585    #ifdef SUPPORT_UCP
3586          if (utf && fc > 127)
3587            foc = UCD_OTHERCASE(fc);
3588    #else
3589          if (utf && fc > 127)
3590            foc = fc;
3591    #endif /* SUPPORT_UCP */
3592          else
3593    #endif /* SUPPORT_UTF */
3594            foc = TABLE_GET(fc, md->fcc, fc);
3595    #endif /* COMPILE_PCRE8 */
3596    
3597  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3598        /* UTF-8 mode */        if (utf)
       if (utf8)  
3599          {          {
3600          register unsigned int d;          register unsigned int d;
3601          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 3531  for (;;) Line 3603  for (;;)
3603            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3604              {              {
3605              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3606              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3607              }              }
3608            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3609            if (d < 256) d = md->lcc[d];            if (fc == d || foc == d) RRETURN(MATCH_NOMATCH);
           if (fc == d) MRRETURN(MATCH_NOMATCH);  
3610            }            }
3611          }          }
3612        else        else
3613  #endif  #endif
3614          /* Not UTF mode */
       /* Not UTF-8 mode */  
3615          {          {
3616          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3617            {            {
3618            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3619              {              {
3620              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3621              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3622              }              }
3623            if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);            if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3624              eptr++;
3625            }            }
3626          }          }
3627    
# Line 3558  for (;;) Line 3629  for (;;)
3629    
3630        if (minimize)        if (minimize)
3631          {          {
3632  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3633          /* UTF-8 mode */          if (utf)
         if (utf8)  
3634            {            {
3635            register unsigned int d;            register unsigned int d;
3636            for (fi = min;; fi++)            for (fi = min;; fi++)
3637              {              {
3638              RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);
3639              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3640              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3641              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3642                {                {
3643                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3644                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3645                }                }
3646              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3647              if (d < 256) d = md->lcc[d];              if (fc == d || foc == d) RRETURN(MATCH_NOMATCH);
             if (fc == d) MRRETURN(MATCH_NOMATCH);  
3648              }              }
3649            }            }
3650          else          else
3651  #endif  #endif
3652          /* Not UTF-8 mode */          /* Not UTF mode */
3653            {            {
3654            for (fi = min;; fi++)            for (fi = min;; fi++)
3655              {              {
3656              RMATCH(eptr, ecode, offset_top, md, eptrb, RM29);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM29);
3657              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3658              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3659              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3660                {                {
3661                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3662                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3663                }                }
3664              if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);              if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3665                eptr++;
3666              }              }
3667            }            }
3668          /* Control never gets here */          /* Control never gets here */
# Line 3604  for (;;) Line 3674  for (;;)
3674          {          {
3675          pp = eptr;          pp = eptr;
3676    
3677  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3678          /* UTF-8 mode */          if (utf)
         if (utf8)  
3679            {            {
3680            register unsigned int d;            register unsigned int d;
3681            for (i = min; i < max; i++)            for (i = min; i < max; i++)
# Line 3618  for (;;) Line 3687  for (;;)
3687                break;                break;
3688                }                }
3689              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3690              if (d < 256) d = md->lcc[d];              if (fc == d || foc == d) break;
             if (fc == d) break;  
3691              eptr += len;              eptr += len;
3692              }              }
3693          if (possessive) continue;          if (possessive) continue;
# Line 3633  for (;;) Line 3701  for (;;)
3701            }            }
3702          else          else
3703  #endif  #endif
3704          /* Not UTF-8 mode */          /* Not UTF mode */
3705            {            {
3706            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3707              {              {
# Line 3642  for (;;) Line 3710  for (;;)
3710                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3711                break;                break;
3712                }                }
3713              if (fc == md->lcc[*eptr]) break;              if (fc == *eptr || foc == *eptr) break;
3714              eptr++;              eptr++;
3715              }              }
3716            if (possessive) continue;            if (possessive) continue;
# Line 3654  for (;;) Line 3722  for (;;)
3722              }              }
3723            }            }
3724    
3725          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3726          }          }
3727        /* Control never gets here */        /* Control never gets here */
3728        }        }
# Line 3663  for (;;) Line 3731  for (;;)
3731    
3732      else      else
3733        {        {
3734  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3735        /* UTF-8 mode */        if (utf)
       if (utf8)  
3736          {          {
3737          register unsigned int d;          register unsigned int d;
3738          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 3673  for (;;) Line 3740  for (;;)
3740            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3741              {              {
3742              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3743              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3744              }              }
3745            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3746            if (fc == d) MRRETURN(MATCH_NOMATCH);            if (fc == d) RRETURN(MATCH_NOMATCH);
3747            }            }
3748          }          }
3749        else        else
3750  #endif  #endif
3751        /* Not UTF-8 mode */        /* Not UTF mode */
3752          {          {
3753          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3754            {            {
3755            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3756              {              {
3757              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3758              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3759              }              }
3760            if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);            if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
3761            }            }
3762          }          }
3763    
# Line 3698  for (;;) Line 3765  for (;;)
3765    
3766        if (minimize)        if (minimize)
3767          {          {
3768  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3769          /* UTF-8 mode */          if (utf)
         if (utf8)  
3770            {            {
3771            register unsigned int d;            register unsigned int d;
3772            for (fi = min;; fi++)            for (fi = min;; fi++)
3773              {              {
3774              RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);
3775              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3776              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3777              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3778                {                {
3779                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3780                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3781                }                }
3782              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3783              if (fc == d) MRRETURN(MATCH_NOMATCH);              if (fc == d) RRETURN(MATCH_NOMATCH);
3784              }              }
3785            }            }
3786          else          else
3787  #endif  #endif
3788          /* Not UTF-8 mode */          /* Not UTF mode */
3789            {            {
3790            for (fi = min;; fi++)            for (fi = min;; fi++)
3791              {              {
3792              RMATCH(eptr, ecode, offset_top, md, eptrb, RM33);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM33);
3793              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3794              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3795              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3796                {                {
3797                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3798                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3799                }                }
3800              if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);              if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
3801              }              }
3802            }            }
3803          /* Control never gets here */          /* Control never gets here */
# Line 3743  for (;;) Line 3809  for (;;)
3809          {          {
3810          pp = eptr;          pp = eptr;
3811    
3812  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3813          /* UTF-8 mode */          if (utf)
         if (utf8)  
3814            {            {
3815            register unsigned int d;            register unsigned int d;
3816            for (i = min; i < max; i++)            for (i = min; i < max; i++)
# Line 3771  for (;;) Line 3836  for (;;)
3836            }            }
3837          else          else
3838  #endif  #endif
3839          /* Not UTF-8 mode */          /* Not UTF mode */
3840            {            {
3841            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3842              {              {
# Line 3792  for (;;) Line 3857  for (;;)
3857              }              }
3858            }            }
3859    
3860          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3861          }          }
3862        }        }
3863      /* Control never gets here */      /* Control never gets here */
# Line 3804  for (;;) Line 3869  for (;;)
3869      case OP_TYPEEXACT:      case OP_TYPEEXACT:
3870      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3871      minimize = TRUE;      minimize = TRUE;
3872      ecode += 3;      ecode += 1 + IMM2_SIZE;
3873      goto REPEATTYPE;      goto REPEATTYPE;
3874    
3875      case OP_TYPEUPTO:      case OP_TYPEUPTO:
# Line 3812  for (;;) Line 3877  for (;;)
3877      min = 0;      min = 0;
3878      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3879      minimize = *ecode == OP_TYPEMINUPTO;      minimize = *ecode == OP_TYPEMINUPTO;
3880      ecode += 3;      ecode += 1 + IMM2_SIZE;
3881      goto REPEATTYPE;      goto REPEATTYPE;
3882    
3883      case OP_TYPEPOSSTAR:      case OP_TYPEPOSSTAR:
# Line 3840  for (;;) Line 3905  for (;;)
3905      possessive = TRUE;      possessive = TRUE;
3906      min = 0;      min = 0;
3907      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3908      ecode += 3;      ecode += 1 + IMM2_SIZE;
3909      goto REPEATTYPE;      goto REPEATTYPE;
3910    
3911      case OP_TYPESTAR:      case OP_TYPESTAR:
# Line 3886  for (;;) Line 3951  for (;;)
3951          switch(prop_type)          switch(prop_type)
3952            {            {
3953            case PT_ANY:            case PT_ANY:
3954            if (prop_fail_result) MRRETURN(MATCH_NOMATCH);            if (prop_fail_result) RRETURN(MATCH_NOMATCH);
3955            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3956              {              {
3957              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3958                {                {
3959                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3960                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3961                }                }
3962              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3963              }              }
# Line 3905  for (;;) Line 3970  for (;;)
3970              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3971                {                {
3972                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3973                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3974                }                }
3975              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3976              chartype = UCD_CHARTYPE(c);              chartype = UCD_CHARTYPE(c);
3977              if ((chartype == ucp_Lu ||              if ((chartype == ucp_Lu ||
3978                   chartype == ucp_Ll ||                   chartype == ucp_Ll ||
3979                   chartype == ucp_Lt) == prop_fail_result)                   chartype == ucp_Lt) == prop_fail_result)
3980                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3981              }              }
3982            break;            break;
3983    
# Line 3922  for (;;) Line 3987  for (;;)
3987              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3988                {                {
3989                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3990                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3991                }                }
3992              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3993              if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)              if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
3994                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3995              }              }
3996            break;            break;
3997    
# Line 3936  for (;;) Line 4001  for (;;)
4001              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4002                {                {
4003                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4004                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4005                }                }
4006              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4007              if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)              if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
4008                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4009              }              }
4010            break;            break;
4011    
# Line 3950  for (;;) Line 4015  for (;;)
4015              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4016                {                {
4017                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4018                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4019                }                }
4020              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4021              if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)              if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
4022                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4023              }              }
4024            break;            break;
4025    
# Line 3965  for (;;) Line 4030  for (;;)
4030              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4031                {                {
4032                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4033                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4034                }                }
4035              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4036              category = UCD_CATEGORY(c);              category = UCD_CATEGORY(c);
4037              if ((category == ucp_L || category == ucp_N) == prop_fail_result)              if ((category == ucp_L || category == ucp_N) == prop_fail_result)
4038                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4039              }              }
4040            break;            break;
4041    
# Line 3980  for (;;) Line 4045  for (;;)
4045              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4046                {                {
4047                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4048                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4049                }                }
4050              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4051              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4052                   c == CHAR_FF || c == CHAR_CR)                   c == CHAR_FF || c == CHAR_CR)
4053                     == prop_fail_result)                     == prop_fail_result)
4054                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4055              }              }
4056            break;            break;
4057    
# Line 3996  for (;;) Line 4061  for (;;)
4061              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4062                {                {
4063                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4064                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4065                }                }
4066              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4067              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4068                   c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)                   c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
4069                     == prop_fail_result)                     == prop_fail_result)
4070                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4071              }              }
4072            break;            break;
4073    
# Line 4013  for (;;) Line 4078  for (;;)
4078              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4079                {                {
4080                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4081                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4082                }                }
4083              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4084              category = UCD_CATEGORY(c);              category = UCD_CATEGORY(c);
4085              if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE)              if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE)
4086                     == prop_fail_result)                     == prop_fail_result)
4087                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4088              }              }
4089            break;            break;
4090    
# Line 4040  for (;;) Line 4105  for (;;)
4105            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4106              {              {
4107              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4108              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4109              }              }
4110            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
4111            if (UCD_CATEGORY(c) == ucp_M) MRRETURN(MATCH_NOMATCH);            if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
4112            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4113              {              {
4114              int len = 1;              int len = 1;
4115              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
4116              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
4117              eptr += len;              eptr += len;
4118              }              }
# Line 4059  for (;;) Line 4124  for (;;)
4124    
4125  /* Handle all other cases when the coding is UTF-8 */  /* Handle all other cases when the coding is UTF-8 */
4126    
4127  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4128        if (utf8) switch(ctype)        if (utf) switch(ctype)
4129          {          {
4130          case OP_ANY:          case OP_ANY:
4131          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 4068  for (;;) Line 4133  for (;;)
4133            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4134              {              {
4135              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4136              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4137              }              }
4138            if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4139            eptr++;            eptr++;
4140            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4141            }            }
4142          break;          break;
4143    
# Line 4082  for (;;) Line 4147  for (;;)
4147            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4148              {              {
4149              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4150              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4151              }              }
4152            eptr++;            eptr++;
4153            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4154            }            }
4155          break;          break;
4156    
4157          case OP_ANYBYTE:          case OP_ANYBYTE:
4158          if (eptr > md->end_subject - min) MRRETURN(MATCH_NOMATCH);          if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);
4159          eptr += min;          eptr += min;
4160          break;          break;
4161    
# Line 4100  for (;;) Line 4165  for (;;)
4165            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4166              {              {
4167              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4168              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4169              }              }
4170            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4171            switch(c)            switch(c)
4172              {              {
4173              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4174    
4175              case 0x000d:              case 0x000d:
4176              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
# Line 4119  for (;;) Line 4184  for (;;)
4184              case 0x0085:              case 0x0085:
4185              case 0x2028:              case 0x2028:
4186              case 0x2029:              case 0x2029:
4187              if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4188              break;              break;
4189              }              }
4190            }            }
# Line 4131  for (;;) Line 4196  for (;;)
4196            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4197              {              {
4198              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4199              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4200              }              }
4201            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4202            switch(c)            switch(c)
# Line 4156  for (;;) Line 4221  for (;;)
4221              case 0x202f:    /* NARROW NO-BREAK SPACE */              case 0x202f:    /* NARROW NO-BREAK SPACE */
4222              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4223              case 0x3000:    /* IDEOGRAPHIC SPACE */              case 0x3000:    /* IDEOGRAPHIC SPACE */
4224              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4225              }              }
4226            }            }
4227          break;          break;
# Line 4167  for (;;) Line 4232  for (;;)
4232            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4233              {              {
4234              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4235              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4236              }              }
4237            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4238            switch(c)            switch(c)
4239              {              {
4240              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4241              case 0x09:      /* HT */              case 0x09:      /* HT */
4242              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4243              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
# Line 4203  for (;;) Line 4268  for (;;)
4268            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4269              {              {
4270              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4271              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4272              }              }
4273            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4274            switch(c)            switch(c)
# Line 4216  for (;;) Line 4281  for (;;)
4281              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4282              case 0x2028:    /* LINE SEPARATOR */              case 0x2028:    /* LINE SEPARATOR */
4283              case 0x2029:    /* PARAGRAPH SEPARATOR */              case 0x2029:    /* PARAGRAPH SEPARATOR */
4284              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4285              }              }
4286            }            }
4287          break;          break;
# Line 4227  for (;;) Line 4292  for (;;)
4292            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4293              {              {
4294              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4295              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4296              }              }
4297            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4298            switch(c)            switch(c)
4299              {              {
4300              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4301              case 0x0a:      /* LF */              case 0x0a:      /* LF */
4302              case 0x0b:      /* VT */              case 0x0b:      /* VT */
4303              case 0x0c:      /* FF */              case 0x0c:      /* FF */
# Line 4251  for (;;) Line 4316  for (;;)
4316            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4317              {              {
4318              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4319              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4320              }              }
4321            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4322            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
4323              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4324            }            }
4325          break;          break;
4326    
# Line 4265  for (;;) Line 4330  for (;;)
4330            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4331              {              {
4332              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4333              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4334              }              }
4335            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)
4336              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4337            /* 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 */
4338            }            }
4339          break;          break;
# Line 4279  for (;;) Line 4344  for (;;)
4344            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4345              {              {
4346              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4347              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4348              }              }
4349            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
4350              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4351            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4352              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4353            }            }
4354          break;          break;
4355    
# Line 4293  for (;;) Line 4359  for (;;)
4359            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4360              {              {
4361              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4362              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4363              }              }
4364            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)
4365              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4366            /* 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 */
4367            }            }
4368          break;          break;
# Line 4307  for (;;) Line 4373  for (;;)
4373            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4374              {              {
4375              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4376              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4377              }              }
4378            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
4379              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4380            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4381              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4382            }            }
4383          break;          break;
4384    
# Line 4321  for (;;) Line 4388  for (;;)
4388            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4389              {              {
4390              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4391              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4392              }              }
4393            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)
4394              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4395            /* 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 */
4396            }            }
4397          break;          break;
# Line 4334  for (;;) Line 4401  for (;;)
4401          }  /* End switch(ctype) */          }  /* End switch(ctype) */
4402    
4403        else        else
4404  #endif     /* SUPPORT_UTF8 */  #endif     /* SUPPORT_UTF */
4405    
4406        /* 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
4407        than OP_PROP and OP_NOTPROP. */        than OP_PROP and OP_NOTPROP. */
# Line 4347  for (;;) Line 4414  for (;;)
4414            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4415              {              {
4416              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4417              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4418              }              }
4419            if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4420            eptr++;            eptr++;
4421            }            }
4422          break;          break;
# Line 4358  for (;;) Line 4425  for (;;)
4425          if (eptr > md->end_subject - min)          if (eptr > md->end_subject - min)
4426            {            {
4427            SCHECK_PARTIAL();            SCHECK_PARTIAL();
4428            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
4429            }            }
4430          eptr += min;          eptr += min;
4431          break;          break;
# Line 4367  for (;;) Line 4434  for (;;)
4434          if (eptr > md->end_subject - min)          if (eptr > md->end_subject - min)
4435            {            {
4436            SCHECK_PARTIAL();            SCHECK_PARTIAL();
4437            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
4438            }            }
4439          eptr += min;          eptr += min;
4440          break;          break;
# Line 4378  for (;;) Line 4445  for (;;)
4445            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4446              {              {
4447              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4448              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4449              }              }
4450            switch(*eptr++)            switch(*eptr++)
4451              {              {
4452              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4453    
4454              case 0x000d:              case 0x000d:
4455              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
# Line 4394  for (;;) Line 4461  for (;;)
4461              case 0x000b:              case 0x000b:
4462              case 0x000c:              case 0x000c:
4463              case 0x0085:              case 0x0085:
4464              if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4465              break;              break;
4466              }              }
4467            }            }
# Line 4406  for (;;) Line 4473  for (;;)
4473            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4474              {              {
4475              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4476              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4477              }              }
4478            switch(*eptr++)            switch(*eptr++)
4479              {              {
# Line 4414  for (;;) Line 4481  for (;;)
4481              case 0x09:      /* HT */              case 0x09:      /* HT */
4482              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4483              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
4484              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4485              }              }
4486            }            }
4487          break;          break;
# Line 4425  for (;;) Line 4492  for (;;)
4492            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4493              {              {
4494              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4495              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4496              }              }
4497            switch(*eptr++)            switch(*eptr++)
4498              {              {
4499              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4500              case 0x09:      /* HT */              case 0x09:      /* HT */
4501              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4502              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
# Line 4444  for (;;) Line 4511  for (;;)
4511            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4512              {              {
4513              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4514              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4515              }              }
4516            switch(*eptr++)            switch(*eptr++)
4517              {              {
# Line 4454  for (;;) Line 4521  for (;;)
4521              case 0x0c:      /* FF */              case 0x0c:      /* FF */
4522              case 0x0d:      /* CR */              case 0x0d:      /* CR */
4523              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4524              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4525              }              }
4526            }            }
4527          break;          break;
# Line 4465  for (;;) Line 4532  for (;;)
4532            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4533              {              {
4534              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4535              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4536              }              }
4537            switch(*eptr++)            switch(*eptr++)
4538              {              {
4539              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4540              case 0x0a:      /* LF */              case 0x0a:      /* LF */
4541              case 0x0b:      /* VT */              case 0x0b:      /* VT */
4542              case 0x0c:      /* FF */              case 0x0c:      /* FF */
# Line 4486  for (;;) Line 4553  for (;;)
4553            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4554              {              {
4555              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4556              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4557              }              }
4558            if ((md->ctypes[*eptr++] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
4559            }            }
4560          break;          break;
4561    
# Line 4498  for (;;) Line 4565  for (;;)
4565            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4566              {              {
4567              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4568              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4569              }              }
4570            if ((md->ctypes[*eptr++] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
4571            }            }
4572          break;          break;
4573    
# Line 4510  for (;;) Line 4577  for (;;)
4577            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4578              {              {
4579              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4580              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4581              }              }
4582            if ((md->ctypes[*eptr++] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
4583            }            }
4584          break;          break;
4585    
# Line 4522  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            if ((md->ctypes[*eptr++] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
4595            }            }
4596          break;          break;
4597    
# Line 4534  for (;;) Line 4601  for (;;)
4601            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4602              {              {
4603              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4604              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4605              }              }
4606            if ((md->ctypes[*eptr++] & ctype_word) != 0)            if ((md->ctypes[*eptr++] & ctype_word) != 0)
4607              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4608            }            }
4609          break;          break;
4610    
# Line 4547  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_word) == 0)            if ((md->ctypes[*eptr++] & ctype_word) == 0)
4620              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4621            }            }
4622          break;          break;
4623    
# Line 4579  for (;;) Line 4646  for (;;)
4646              {              {
4647              RMATCH(eptr, ecode, offset_top, md, eptrb, RM36);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM36);
4648              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4649              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4650              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4651                {                {
4652                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4653                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4654                }                }
4655              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4656              if (prop_fail_result) MRRETURN(MATCH_NOMATCH);              if (prop_fail_result) RRETURN(MATCH_NOMATCH);
4657              }              }
4658            /* Control never gets here */            /* Control never gets here */
4659    
# Line 4596  for (;;) Line 4663  for (;;)
4663              int chartype;              int chartype;
4664              RMATCH(eptr, ecode, offset_top, md, eptrb, RM37);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM37);
4665              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4666              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4667              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4668                {                {
4669                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4670                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4671                }                }
4672              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4673              chartype = UCD_CHARTYPE(c);              chartype = UCD_CHARTYPE(c);
4674              if ((chartype == ucp_Lu ||              if ((chartype == ucp_Lu ||
4675                   chartype == ucp_Ll ||                   chartype == ucp_Ll ||
4676                   chartype == ucp_Lt) == prop_fail_result)                   chartype == ucp_Lt) == prop_fail_result)
4677                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4678              }              }
4679            /* Control never gets here */            /* Control never gets here */
4680    
# Line 4616  for (;;) Line 4683  for (;;)
4683              {              {
4684              RMATCH(eptr, ecode, offset_top, md, eptrb, RM38);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM38);
4685              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4686              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4687              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4688                {                {
4689                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4690                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4691                }                }
4692              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4693              if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)              if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
4694                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4695              }              }
4696            /* Control never gets here */            /* Control never gets here */
4697    
# Line 4633  for (;;) Line 4700  for (;;)
4700              {              {
4701              RMATCH(eptr, ecode, offset_top, md, eptrb, RM39);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM39);
4702              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4703              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4704              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4705                {                {
4706                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4707                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4708                }                }
4709              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4710              if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)              if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
4711                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4712              }              }
4713            /* Control never gets here */            /* Control never gets here */
4714    
# Line 4650  for (;;) Line 4717  for (;;)
4717              {              {
4718              RMATCH(eptr, ecode, offset_top, md, eptrb, RM40);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM40);
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 ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)              if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
4728                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4729              }              }
4730            /* Control never gets here */            /* Control never gets here */
4731    
# Line 4668  for (;;) Line 4735  for (;;)
4735              int category;              int category;
4736              RMATCH(eptr, ecode, offset_top, md, eptrb, RM59);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM59);
4737              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4738              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4739              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4740                {                {
4741                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4742                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4743                }                }
4744              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4745              category = UCD_CATEGORY(c);              category = UCD_CATEGORY(c);
4746              if ((category == ucp_L || category == ucp_N) == prop_fail_result)              if ((category == ucp_L || category == ucp_N) == prop_fail_result)
4747                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4748              }              }
4749            /* Control never gets here */            /* Control never gets here */
4750    
# Line 4686  for (;;) Line 4753  for (;;)
4753              {              {
4754              RMATCH(eptr, ecode, offset_top, md, eptrb, RM60);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM60);
4755              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4756              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4757              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4758                {                {
4759                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4760                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4761                }                }
4762              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4763              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4764                   c == CHAR_FF || c == CHAR_CR)                   c == CHAR_FF || c == CHAR_CR)
4765                     == prop_fail_result)                     == prop_fail_result)
4766                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4767              }              }
4768            /* Control never gets here */            /* Control never gets here */
4769    
# Line 4705  for (;;) Line 4772  for (;;)
4772              {              {
4773              RMATCH(eptr, ecode, offset_top, md, eptrb, RM61);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM61);
4774              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4775              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4776              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4777                {                {
4778                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4779                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4780                }                }
4781              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4782              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4783                   c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)                   c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
4784                     == prop_fail_result)                     == prop_fail_result)
4785                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4786              }              }
4787            /* Control never gets here */            /* Control never gets here */
4788    
# Line 4725  for (;;) Line 4792  for (;;)
4792              int category;              int category;
4793              RMATCH(eptr, ecode, offset_top, md, eptrb, RM62);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM62);
4794              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4795              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4796              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4797                {                {
4798                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4799                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4800                }                }
4801              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4802              category = UCD_CATEGORY(c);              category = UCD_CATEGORY(c);
# Line 4737  for (;;) Line 4804  for (;;)
4804                   category == ucp_N ||                   category == ucp_N ||
4805                   c == CHAR_UNDERSCORE)                   c == CHAR_UNDERSCORE)
4806                     == prop_fail_result)                     == prop_fail_result)
4807                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4808              }              }
4809            /* Control never gets here */            /* Control never gets here */
4810    
# Line 4757  for (;;) Line 4824  for (;;)
4824            {            {
4825            RMATCH(eptr, ecode, offset_top, md, eptrb, RM41);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM41);
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_M) MRRETURN(MATCH_NOMATCH);            if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
4835            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4836              {              {
4837              int len = 1;              int len = 1;
4838              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
4839              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
4840              eptr += len;              eptr += len;
4841              }              }
# Line 4777  for (;;) Line 4844  for (;;)
4844        else        else
4845  #endif     /* SUPPORT_UCP */  #endif     /* SUPPORT_UCP */
4846    
4847  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4848        /* UTF-8 mode */        if (utf)
       if (utf8)  
4849          {          {
4850          for (fi = min;; fi++)          for (fi = min;; fi++)
4851            {            {
4852            RMATCH(eptr, ecode, offset_top, md, eptrb, RM42);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM42);
4853            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4854            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
4855            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4856              {              {
4857              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4858              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4859              }              }
4860            if (ctype == OP_ANY && IS_NEWLINE(eptr))            if (ctype == OP_ANY && IS_NEWLINE(eptr))
4861              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4862            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4863            switch(ctype)            switch(ctype)
4864              {              {
# Line 4804  for (;;) Line 4870  for (;;)
4870              case OP_ANYNL:              case OP_ANYNL:
4871              switch(c)              switch(c)
4872                {                {
4873                default: MRRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
4874                case 0x000d:                case 0x000d:
4875                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
4876                break;                break;
# Line 4816  for (;;) Line 4882  for (;;)
4882                case 0x0085:                case 0x0085:
4883                case 0x2028:                case 0x2028:
4884                case 0x2029:                case 0x2029:
4885                if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4886                break;                break;
4887                }                }
4888              break;              break;
# Line 4844  for (;;) Line 4910  for (;;)
4910                case 0x202f:    /* NARROW NO-BREAK SPACE */                case 0x202f:    /* NARROW NO-BREAK SPACE */
4911                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4912                case 0x3000:    /* IDEOGRAPHIC SPACE */                case 0x3000:    /* IDEOGRAPHIC SPACE */
4913                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4914                }                }
4915              break;              break;
4916    
4917              case OP_HSPACE:              case OP_HSPACE:
4918              switch(c)              switch(c)
4919                {                {
4920                default: MRRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
4921                case 0x09:      /* HT */                case 0x09:      /* HT */
4922                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
4923                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
# Line 4886  for (;;) Line 4952  for (;;)
4952                case 0x85:      /* NEL */                case 0x85:      /* NEL */
4953                case 0x2028:    /* LINE SEPARATOR */                case 0x2028:    /* LINE SEPARATOR */
4954                case 0x2029:    /* PARAGRAPH SEPARATOR */                case 0x2029:    /* PARAGRAPH SEPARATOR */
4955                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4956                }                }
4957              break;              break;
4958    
4959              case OP_VSPACE:              case OP_VSPACE:
4960              switch(c)              switch(c)
4961                {                {
4962                default: MRRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
4963                case 0x0a:      /* LF */                case 0x0a:      /* LF */
4964                case 0x0b:      /* VT */                case 0x0b:      /* VT */
4965                case 0x0c:      /* FF */                case 0x0c:      /* FF */
# Line 4907  for (;;) Line 4973  for (;;)
4973    
4974              case OP_NOT_DIGIT:              case OP_NOT_DIGIT:
4975              if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)              if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)
4976                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4977              break;              break;
4978    
4979              case OP_DIGIT:              case OP_DIGIT:
4980              if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)
4981                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4982              break;              break;
4983    
4984              case OP_NOT_WHITESPACE:              case OP_NOT_WHITESPACE:
4985              if (c < 256 && (md->ctypes[c] & ctype_space) != 0)              if (c < 256 && (md->ctypes[c] & ctype_space) != 0)
4986                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4987              break;              break;
4988    
4989              case OP_WHITESPACE:              case OP_WHITESPACE:
4990              if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)              if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
4991                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4992              break;              break;
4993    
4994              case OP_NOT_WORDCHAR:              case OP_NOT_WORDCHAR:
4995              if (c < 256 && (md->ctypes[c] & ctype_word) != 0)              if (c < 256 && (md->ctypes[c] & ctype_word) != 0)
4996                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4997              break;              break;
4998    
4999              case OP_WORDCHAR:              case OP_WORDCHAR:
5000              if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)
5001                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5002              break;              break;
5003    
5004              default:              default:
# Line 4942  for (;;) Line 5008  for (;;)
5008          }          }
5009        else        else
5010  #endif  #endif
5011        /* Not UTF-8 mode */        /* Not UTF mode */
5012          {          {
5013          for (fi = min;; fi++)          for (fi = min;; fi++)
5014            {            {
5015            RMATCH(eptr, ecode, offset_top, md, eptrb, RM43);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM43);
5016            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5017            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
5018            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
5019              {              {
5020              SCHECK_PARTIAL();              SCHECK_PARTIAL();
5021              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
5022              }              }
5023            if (ctype == OP_ANY && IS_NEWLINE(eptr))            if (ctype == OP_ANY && IS_NEWLINE(eptr))
5024              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
5025            c = *eptr++;            c = *eptr++;
5026            switch(ctype)            switch(ctype)
5027              {              {
# Line 4967  for (;;) Line 5033  for (;;)
5033              case OP_ANYNL:              case OP_ANYNL:
5034              switch(c)              switch(c)
5035                {                {
5036                default: MRRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5037                case 0x000d:                case 0x000d:
5038                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
5039                break;                break;
# Line 4978  for (;;) Line 5044  for (;;)
5044                case 0x000b:                case 0x000b:
5045                case 0x000c:                case 0x000c:
5046                case 0x0085:                case 0x0085:
5047                if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
5048                break;                break;
5049                }                }
5050              break;              break;
# Line 4990  for (;;) Line 5056  for (;;)
5056                case 0x09:      /* HT */                case 0x09:      /* HT */
5057                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
5058                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
5059                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5060                }                }
5061              break;              break;
5062    
5063              case OP_HSPACE:              case OP_HSPACE:
5064              switch(c)              switch(c)
5065                {                {
5066                default: MRRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5067                case 0x09:      /* HT */                case 0x09:      /* HT */
5068                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
5069                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
# Line 5014  for (;;) Line 5080  for (;;)
5080                case 0x0c:      /* FF */                case 0x0c:      /* FF */
5081                case 0x0d:      /* CR */                case 0x0d:      /* CR */
5082                case 0x85:      /* NEL */                case 0x85:      /* NEL */
5083                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5084                }                }
5085              break;              break;
5086    
5087              case OP_VSPACE:              case OP_VSPACE:
5088              switch(c)              switch(c)
5089                {                {
5090                default: MRRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5091                case 0x0a:      /* LF */                case 0x0a:      /* LF */
5092                case 0x0b:      /* VT */                case 0x0b:      /* VT */
5093                case 0x0c:      /* FF */                case 0x0c:      /* FF */
# Line 5032  for (;;) Line 5098  for (;;)
5098              break;              break;
5099    
5100              case OP_NOT_DIGIT:              case OP_NOT_DIGIT:
5101              if ((md->ctypes[c] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH);              if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
5102              break;              break;
5103    
5104              case OP_DIGIT:              case OP_DIGIT:
5105              if ((md->ctypes[c] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH);              if ((md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
5106              break;              break;
5107    
5108              case OP_NOT_WHITESPACE:              case OP_NOT_WHITESPACE:
5109              if ((md->ctypes[c] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH);              if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
5110              break;              break;
5111    
5112              case OP_WHITESPACE:              case OP_WHITESPACE:
5113              if  ((md->ctypes[c] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH);              if  ((md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
5114              break;              break;
5115    
5116              case OP_NOT_WORDCHAR:              case OP_NOT_WORDCHAR:
5117              if ((md->ctypes[c] & ctype_word) != 0) MRRETURN(MATCH_NOMATCH);              if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
5118              break;              break;
5119    
5120              case OP_WORDCHAR:              case OP_WORDCHAR:
5121              if ((md->ctypes[c] & ctype_word) == 0) MRRETURN(MATCH_NOMATCH);              if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
5122              break;              break;
5123    
5124              default:              default:
# Line 5241  for (;;) Line 5307  for (;;)
5307            RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);
5308            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5309            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
5310            if (utf8) BACKCHAR(eptr);            if (utf) BACKCHAR(eptr);
5311            }            }
5312          }          }
5313    
# Line 5258  for (;;) Line 5324  for (;;)
5324              SCHECK_PARTIAL();              SCHECK_PARTIAL();
5325              break;              break;
5326              }   &