[Pcre-svn] [771] code/trunk: Update *MARK handling to be mor…

Top Page
Delete this message
Author: Subversion repository
Date:  
To: pcre-svn
Subject: [Pcre-svn] [771] code/trunk: Update *MARK handling to be more like Perl.
Revision: 771
          http://vcs.pcre.org/viewvc?view=rev&revision=771
Author:   ph10
Date:     2011-11-29 15:34:12 +0000 (Tue, 29 Nov 2011)


Log Message:
-----------
Update *MARK handling to be more like Perl.

Modified Paths:
--------------
    code/trunk/ChangeLog
    code/trunk/doc/pcrepattern.3
    code/trunk/pcre_exec.c
    code/trunk/pcre_internal.h
    code/trunk/perltest.pl
    code/trunk/testdata/testinput11
    code/trunk/testdata/testinput2
    code/trunk/testdata/testoutput11
    code/trunk/testdata/testoutput2


Modified: code/trunk/ChangeLog
===================================================================
--- code/trunk/ChangeLog    2011-11-28 20:39:30 UTC (rev 770)
+++ code/trunk/ChangeLog    2011-11-29 15:34:12 UTC (rev 771)
@@ -61,6 +61,23 @@


 16. A repeated forward reference in a pattern such as (a)(?2){2}(.) was
     incorrectly expecting the subject to contain another "a" after the start.
+    
+17. When (*SKIP:name) is activated without a corresponding (*MARK:name) earlier 
+    in the match, the SKIP should be ignored. This was not happening; instead 
+    the SKIP was being treated as NOMATCH. For patterns such as 
+    /A(*MARK:A)A+(*SKIP:B)Z|AAC/ this meant that the AAC branch was never 
+    tested. 
+    
+18. The behaviour of (*MARK), (*PRUNE), and (*THEN) has been reworked and is
+    now much more compatible with Perl, in particular in cases where the result
+    is a non-match for a non-anchored pattern. For example, if
+    /b(*:m)f|a(*:n)w/ is matched against "abc", the non-match returns the name
+    "m", where previously it did not return a name. A side effect of this 
+    change is that for partial matches, the last encountered mark name is 
+    returned, as for non matches. A number of tests that were previously not
+    Perl-compatible have been moved into the Perl-compatible test files. The
+    refactoring has had the pleasing side effect of removing one argument from
+    the match() function, thus reducing its stack requirements.



Version 8.20 21-Oct-2011

Modified: code/trunk/doc/pcrepattern.3
===================================================================
--- code/trunk/doc/pcrepattern.3    2011-11-28 20:39:30 UTC (rev 770)
+++ code/trunk/doc/pcrepattern.3    2011-11-29 15:34:12 UTC (rev 771)
@@ -2569,10 +2569,11 @@
 If any of these verbs are used in an assertion or in a subpattern that is
 called as a subroutine (whether or not recursively), their effect is confined
 to that subpattern; it does not extend to the surrounding pattern, with one
-exception: a *MARK that is encountered in a positive assertion \fIis\fP passed
-back (compare capturing parentheses in assertions). Note that such subpatterns
-are processed as anchored at the point where they are tested. Note also that
-Perl's treatment of subroutines is different in some cases.
+exception: the name from a *(MARK), (*PRUNE), or (*THEN) that is encountered in
+a successful positive assertion \fIis\fP passed back when a match succeeds
+(compare capturing parentheses in assertions). Note that such subpatterns are
+processed as anchored at the point where they are tested. Note also that Perl's
+treatment of subroutines is different in some cases.
 .P
 The new verbs make use of what was previously invalid syntax: an opening
 parenthesis followed by an asterisk. They are generally of the form
@@ -2591,6 +2592,9 @@
 the start-of-match optimizations by setting the PCRE_NO_START_OPTIMIZE option
 when calling \fBpcre_compile()\fP or \fBpcre_exec()\fP, or by starting the
 pattern with (*NO_START_OPT).
+.P
+Experiments with Perl suggest that it too has similar optimizations, sometimes 
+leading to anomalous results.
 .
 .
 .SS "Verbs that act immediately"
@@ -2638,8 +2642,9 @@
 A name is always required with this verb. There may be as many instances of
 (*MARK) as you like in a pattern, and their names do not have to be unique.
 .P
-When a match succeeds, the name of the last-encountered (*MARK) is passed back
-to the caller via the \fIpcre_extra\fP data structure, as described in the
+When a match succeeds, the name of the last-encountered (*MARK) on the matching 
+path is passed back to the caller via the \fIpcre_extra\fP data structure, as
+described in the
 .\" HTML <a href="pcreapi.html#extradata">
 .\" </a>
 section on \fIpcre_extra\fP
@@ -2648,12 +2653,11 @@
 .\" HREF
 \fBpcreapi\fP
 .\"
-documentation. No data is returned for a partial match. Here is an example of
-\fBpcretest\fP output, where the /K modifier requests the retrieval and
-outputting of (*MARK) data:
+documentation. Here is an example of \fBpcretest\fP output, where the /K
+modifier requests the retrieval and outputting of (*MARK) data:
 .sp
-  /X(*MARK:A)Y|X(*MARK:B)Z/K
-  XY
+    re> /X(*MARK:A)Y|X(*MARK:B)Z/K
+  data> XY
    0: XY
   MK: A
   XZ
@@ -2669,31 +2673,17 @@
 passed back if it is the last-encountered. This does not happen for negative
 assertions.
 .P
-A name may also be returned after a failed match if the final path through the
-pattern involves (*MARK). However, unless (*MARK) used in conjunction with
-(*COMMIT), this is unlikely to happen for an unanchored pattern because, as the
-starting point for matching is advanced, the final check is often with an empty
-string, causing a failure before (*MARK) is reached. For example:
+After a partial match or a failed match, the name of the last encountered
+(*MARK) in the entire match process is returned. For example:
 .sp
-  /X(*MARK:A)Y|X(*MARK:B)Z/K
-  XP
-  No match
-.sp
-There are three potential starting points for this match (starting with X,
-starting with P, and with an empty string). If the pattern is anchored, the
-result is different:
-.sp
-  /^X(*MARK:A)Y|^X(*MARK:B)Z/K
-  XP
+    re> /X(*MARK:A)Y|X(*MARK:B)Z/K
+  data> XP
   No match, mark = B
 .sp
-PCRE's start-of-match optimizations can also interfere with this. For example,
-if, as a result of a call to \fBpcre_study()\fP, it knows the minimum
-subject length for a match, a shorter subject will not be scanned at all.
-.P
-Note that similar anomalies (though different in detail) exist in Perl, no
-doubt for the same reasons. The use of (*MARK) data after a failed match of an
-unanchored pattern is not recommended, unless (*COMMIT) is involved.
+Note that in this unanchored example the mark is retained from the match
+attempt that started at the letter "X". Subsequent match attempts starting at 
+"P" and then with an empty string do not get as far as the (*MARK) item, but 
+nevertheless do not reset it.
 .
 .
 .SS "Verbs that act after backtracking"
@@ -2730,8 +2720,8 @@
 unless PCRE's start-of-match optimizations are turned off, as shown in this
 \fBpcretest\fP example:
 .sp
-  /(*COMMIT)abc/
-  xyzabc
+    re> /(*COMMIT)abc/
+  data> xyzabc
    0: abc
   xyzabc\eY
   No match
@@ -2752,10 +2742,8 @@
 the right, backtracking cannot cross (*PRUNE). In simple cases, the use of
 (*PRUNE) is just an alternative to an atomic group or possessive quantifier,
 but there are some uses of (*PRUNE) that cannot be expressed in any other way.
-The behaviour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE) when the
-match fails completely; the name is passed back if this is the final attempt.
-(*PRUNE:NAME) does not pass back a name if the match succeeds. In an anchored
-pattern (*PRUNE) has the same effect as (*COMMIT).
+The behaviour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE). In an
+anchored pattern (*PRUNE) has the same effect as (*COMMIT).
 .sp
   (*SKIP)
 .sp
@@ -2781,8 +2769,7 @@
 searched for the most recent (*MARK) that has the same name. If one is found,
 the "bumpalong" advance is to the subject position that corresponds to that
 (*MARK) instead of to where (*SKIP) was encountered. If no (*MARK) with a
-matching name is found, normal "bumpalong" of one character happens (that is,
-the (*SKIP) is ignored).
+matching name is found, the (*SKIP) is ignored.
 .sp
   (*THEN) or (*THEN:NAME)
 .sp
@@ -2796,9 +2783,8 @@
 If the COND1 pattern matches, FOO is tried (and possibly further items after
 the end of the group if FOO succeeds); on failure, the matcher skips to the
 second alternative and tries COND2, without backtracking into COND1. The
-behaviour of (*THEN:NAME) is exactly the same as (*MARK:NAME)(*THEN) if the
-overall match fails. If (*THEN) is not inside an alternation, it acts like
-(*PRUNE).
+behaviour of (*THEN:NAME) is exactly the same as (*MARK:NAME)(*THEN).
+If (*THEN) is not inside an alternation, it acts like (*PRUNE).
 .P
 Note that a subpattern that does not contain a | character is just a part of
 the enclosing alternative; it is not a nested alternation with only one
@@ -2876,6 +2862,6 @@
 .rs
 .sp
 .nf
-Last updated: 19 November 2011
+Last updated: 29 November 2011
 Copyright (c) 1997-2011 University of Cambridge.
 .fi


Modified: code/trunk/pcre_exec.c
===================================================================
--- code/trunk/pcre_exec.c    2011-11-28 20:39:30 UTC (rev 770)
+++ code/trunk/pcre_exec.c    2011-11-29 15:34:12 UTC (rev 771)
@@ -82,14 +82,6 @@
 #define MATCH_SKIP_ARG     (-993)
 #define MATCH_THEN         (-992)


-/* This is a convenience macro for code that occurs many times. */
-
-#define MRRETURN(ra) \
- { \
- md->mark = markptr; \
- RRETURN(ra); \
- }
-
/* Maximum number of ints of offset to save on the stack for recursive calls.
If the offset vector is bigger, malloc is used. This should be a multiple of 3,
because the offset vector is always a multiple of 3 long. */
@@ -290,7 +282,7 @@
#define RMATCH(ra,rb,rc,rd,re,rw) \
{ \
printf("match() called in line %d\n", __LINE__); \
- rrc = match(ra,rb,mstart,markptr,rc,rd,re,rdepth+1); \
+ rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1); \
printf("to line %d\n", __LINE__); \
}
#define RRETURN(ra) \
@@ -300,7 +292,7 @@
}
#else
#define RMATCH(ra,rb,rc,rd,re,rw) \
- rrc = match(ra,rb,mstart,markptr,rc,rd,re,rdepth+1)
+ rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1)
#define RRETURN(ra) return ra
#endif

@@ -321,7 +313,6 @@
   newframe->Xeptr = ra;\
   newframe->Xecode = rb;\
   newframe->Xmstart = mstart;\
-  newframe->Xmarkptr = markptr;\
   newframe->Xoffset_top = rc;\
   newframe->Xeptrb = re;\
   newframe->Xrdepth = frame->Xrdepth + 1;\
@@ -357,7 +348,6 @@
   USPTR Xeptr;
   const uschar *Xecode;
   USPTR Xmstart;
-  USPTR Xmarkptr;
   int Xoffset_top;
   eptrblock *Xeptrb;
   unsigned int Xrdepth;
@@ -438,14 +428,14 @@
       eptr > md->start_used_ptr) \
     { \
     md->hitend = TRUE; \
-    if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL); \
+    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \
     }


 #define SCHECK_PARTIAL()\
   if (md->partial != 0 && eptr > md->start_used_ptr) \
     { \
     md->hitend = TRUE; \
-    if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL); \
+    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \
     }



@@ -459,7 +449,6 @@
    ecode       pointer to current position in compiled code
    mstart      pointer to the current match start position (can be modified
                  by encountering \K)
-   markptr     pointer to the most recent MARK name, or NULL
    offset_top  current top pointer
    md          pointer to "static" info for the match
    eptrb       pointer to chain of blocks containing eptr at start of
@@ -475,8 +464,7 @@


 static int
 match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,
-  const uschar *markptr, int offset_top, match_data *md, eptrblock *eptrb,
-  unsigned int rdepth)
+  int offset_top, match_data *md, eptrblock *eptrb, unsigned int rdepth)
 {
 /* These variables do not need to be preserved over recursion in this function,
 so they can be ordinary variables in all cases. Mark some of them with
@@ -506,7 +494,6 @@
 frame->Xeptr = eptr;
 frame->Xecode = ecode;
 frame->Xmstart = mstart;
-frame->Xmarkptr = markptr;
 frame->Xoffset_top = offset_top;
 frame->Xeptrb = eptrb;
 frame->Xrdepth = rdepth;
@@ -520,7 +507,6 @@
 #define eptr               frame->Xeptr
 #define ecode              frame->Xecode
 #define mstart             frame->Xmstart
-#define markptr            frame->Xmarkptr
 #define offset_top         frame->Xoffset_top
 #define eptrb              frame->Xeptrb
 #define rdepth             frame->Xrdepth
@@ -701,9 +687,12 @@
   switch(op)
     {
     case OP_MARK:
-    markptr = ecode + 2;
+    md->nomatch_mark = ecode + 2;
+    md->mark = NULL;    /* In case previously set by assertion */
     RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
       eptrb, RM55);
+    if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
+         md->mark == NULL) md->mark = ecode + 2;


     /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
     argument, and we must check whether that argument matches this MARK's
@@ -712,18 +701,16 @@
     position and return MATCH_SKIP. Otherwise, pass back the return code
     unaltered. */


-    if (rrc == MATCH_SKIP_ARG &&
-        strcmp((char *)markptr, (char *)(md->start_match_ptr)) == 0)
+    else if (rrc == MATCH_SKIP_ARG &&
+        strcmp((char *)(ecode + 2), (char *)(md->start_match_ptr)) == 0)
       {
       md->start_match_ptr = eptr;
       RRETURN(MATCH_SKIP);
       }
-
-    if (md->mark == NULL) md->mark = markptr;
     RRETURN(rrc);


     case OP_FAIL:
-    MRRETURN(MATCH_NOMATCH);
+    RRETURN(MATCH_NOMATCH);


     /* COMMIT overrides PRUNE, SKIP, and THEN */


@@ -734,7 +721,7 @@
         rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&
         rrc != MATCH_THEN)
       RRETURN(rrc);
-    MRRETURN(MATCH_COMMIT);
+    RRETURN(MATCH_COMMIT);


     /* PRUNE overrides THEN */


@@ -742,13 +729,16 @@
     RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
       eptrb, RM51);
     if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
-    MRRETURN(MATCH_PRUNE);
+    RRETURN(MATCH_PRUNE);


     case OP_PRUNE_ARG:
+    md->nomatch_mark = ecode + 2;
+    md->mark = NULL;    /* In case previously set by assertion */
     RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
       eptrb, RM56);
+    if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
+         md->mark == NULL) md->mark = ecode + 2;
     if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
-    md->mark = ecode + 2;
     RRETURN(MATCH_PRUNE);


     /* SKIP overrides PRUNE and THEN */
@@ -759,9 +749,18 @@
     if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
       RRETURN(rrc);
     md->start_match_ptr = eptr;   /* Pass back current position */
-    MRRETURN(MATCH_SKIP);
+    RRETURN(MATCH_SKIP);


+    /* Note that, for Perl compatibility, SKIP with an argument does NOT set
+    nomatch_mark. There is a flag that disables this opcode when re-matching a 
+    pattern that ended with a SKIP for which there was not a matching MARK. */
+     
     case OP_SKIP_ARG:
+    if (md->ignore_skip_arg) 
+      {
+      ecode += _pcre_OP_lengths[*ecode] + ecode[1]; 
+      break;
+      } 
     RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
       eptrb, RM57);
     if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
@@ -769,8 +768,8 @@


     /* Pass back the current skip name by overloading md->start_match_ptr and
     returning the special MATCH_SKIP_ARG return code. This will either be
-    caught by a matching MARK, or get to the top, where it is treated the same
-    as PRUNE. */
+    caught by a matching MARK, or get to the top, where it causes a rematch 
+    with the md->ignore_skip_arg flag set. */


     md->start_match_ptr = ecode + 2;
     RRETURN(MATCH_SKIP_ARG);
@@ -784,14 +783,17 @@
       eptrb, RM54);
     if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     md->start_match_ptr = ecode;
-    MRRETURN(MATCH_THEN);
+    RRETURN(MATCH_THEN);


     case OP_THEN_ARG:
+    md->nomatch_mark = ecode + 2;
+    md->mark = NULL;    /* In case previously set by assertion */
     RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top,
       md, eptrb, RM58);
+    if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
+         md->mark == NULL) md->mark = ecode + 2;
     if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     md->start_match_ptr = ecode;
-    md->mark = ecode + 2;
     RRETURN(MATCH_THEN);


     /* Handle an atomic group that does not contain any capturing parentheses.
@@ -816,7 +818,6 @@
       if (rrc == MATCH_MATCH)  /* Note: _not_ MATCH_ACCEPT */
         {
         mstart = md->start_match_ptr;
-        markptr = md->mark;
         break;
         }
       if (rrc == MATCH_THEN)
@@ -954,7 +955,6 @@


       /* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */


-      if (md->mark == NULL) md->mark = markptr;
       RRETURN(rrc);
       }


@@ -1042,7 +1042,6 @@
       if (*ecode != OP_ALT) break;
       }


-    if (md->mark == NULL) md->mark = markptr;
     RRETURN(MATCH_NOMATCH);


     /* Handle possessive capturing brackets with an unlimited repeat. We come
@@ -1130,7 +1129,6 @@
         md->offset_vector[md->offset_end - number] = save_offset3;
         }


-      if (md->mark == NULL) md->mark = markptr;
       if (allow_zero || matched_once)
         {
         ecode += 1 + LINK_SIZE;
@@ -1232,8 +1230,8 @@
         cb.capture_top      = offset_top/2;
         cb.capture_last     = md->capture_last;
         cb.callout_data     = md->callout_data;
-        cb.mark             = markptr;
-        if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);
+        cb.mark             = md->nomatch_mark;
+        if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);
         if (rrc < 0) RRETURN(rrc);
         }
       ecode += _pcre_OP_lengths[OP_CALLOUT];
@@ -1488,7 +1486,7 @@
          (md->notempty ||
            (md->notempty_atstart &&
              mstart == md->start_subject + md->start_offset)))
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);


     /* Otherwise, we have a match. */


@@ -1497,10 +1495,10 @@
     md->start_match_ptr = mstart;       /* and the start (\K can modify) */


     /* For some reason, the macros don't work properly if an expression is
-    given as the argument to MRRETURN when the heap is in use. */
+    given as the argument to RRETURN when the heap is in use. */


     rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;
-    MRRETURN(rrc);
+    RRETURN(rrc);


     /* Assertion brackets. Check the alternative branches in turn - the
     matching won't pass the KET for an assertion. If any one branch matches,
@@ -1528,7 +1526,6 @@
       if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
         {
         mstart = md->start_match_ptr;   /* In case \K reset it */
-        markptr = md->mark;
         break;
         }


@@ -1540,7 +1537,7 @@
       }
     while (*ecode == OP_ALT);


-    if (*ecode == OP_KET) MRRETURN(MATCH_NOMATCH);
+    if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);


     /* If checking an assertion for a condition, return MATCH_MATCH. */


@@ -1570,7 +1567,7 @@
     do
       {
       RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);
-      if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) MRRETURN(MATCH_NOMATCH);
+      if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);
       if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
         {
         do ecode += GET(ecode,1); while (*ecode == OP_ALT);
@@ -1603,7 +1600,7 @@
       while (i-- > 0)
         {
         eptr--;
-        if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);
+        if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
         BACKCHAR(eptr);
         }
       }
@@ -1614,7 +1611,7 @@


       {
       eptr -= GET(ecode, 1);
-      if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);
+      if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
       }


     /* Save the earliest consulted character, then skip to next op code */
@@ -1643,8 +1640,8 @@
       cb.capture_top      = offset_top/2;
       cb.capture_last     = md->capture_last;
       cb.callout_data     = md->callout_data;
-      cb.mark             = markptr;
-      if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);
+      cb.mark             = md->nomatch_mark;
+      if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);
       if (rrc < 0) RRETURN(rrc);
       }
     ecode += 2 + 2*LINK_SIZE;
@@ -1758,7 +1755,7 @@
       md->recursive = new_recursive.prevrec;
       if (new_recursive.offset_save != stacksave)
         (pcre_free)(new_recursive.offset_save);
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }


     RECURSION_MATCHED:
@@ -1838,7 +1835,7 @@
       md->end_match_ptr = eptr;      /* For ONCE_NC */
       md->end_offset_top = offset_top;
       md->start_match_ptr = mstart;
-      MRRETURN(MATCH_MATCH);         /* Sets md->mark */
+      RRETURN(MATCH_MATCH);         /* Sets md->mark */
       }


     /* For capturing groups we have to check the group number back at the start
@@ -1980,29 +1977,29 @@
     /* Not multiline mode: start of subject assertion, unless notbol. */


     case OP_CIRC:
-    if (md->notbol && eptr == md->start_subject) MRRETURN(MATCH_NOMATCH);
+    if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);


     /* Start of subject assertion */


     case OP_SOD:
-    if (eptr != md->start_subject) MRRETURN(MATCH_NOMATCH);
+    if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH);
     ecode++;
     break;


     /* Multiline mode: start of subject unless notbol, or after any newline. */


     case OP_CIRCM:
-    if (md->notbol && eptr == md->start_subject) MRRETURN(MATCH_NOMATCH);
+    if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
     if (eptr != md->start_subject &&
         (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
     ecode++;
     break;


     /* Start of match assertion */


     case OP_SOM:
-    if (eptr != md->start_subject + md->start_offset) MRRETURN(MATCH_NOMATCH);
+    if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH);
     ecode++;
     break;


@@ -2018,10 +2015,10 @@

     case OP_DOLLM:
     if (eptr < md->end_subject)
-      { if (!IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); }
+      { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }
     else
       {
-      if (md->noteol) MRRETURN(MATCH_NOMATCH);
+      if (md->noteol) RRETURN(MATCH_NOMATCH);
       SCHECK_PARTIAL();
       }
     ecode++;
@@ -2031,7 +2028,7 @@
     subject unless noteol is set. */


     case OP_DOLL:
-    if (md->noteol) MRRETURN(MATCH_NOMATCH);
+    if (md->noteol) RRETURN(MATCH_NOMATCH);
     if (!md->endonly) goto ASSERT_NL_OR_EOS;


     /* ... else fall through for endonly */
@@ -2039,7 +2036,7 @@
     /* End of subject assertion (\z) */


     case OP_EOD:
-    if (eptr < md->end_subject) MRRETURN(MATCH_NOMATCH);
+    if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH);
     SCHECK_PARTIAL();
     ecode++;
     break;
@@ -2050,7 +2047,7 @@
     ASSERT_NL_OR_EOS:
     if (eptr < md->end_subject &&
         (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);


     /* Either at end of string or \n before end. */


@@ -2172,21 +2169,21 @@

       if ((*ecode++ == OP_WORD_BOUNDARY)?
            cur_is_word == prev_is_word : cur_is_word != prev_is_word)
-        MRRETURN(MATCH_NOMATCH);
+        RRETURN(MATCH_NOMATCH);
       }
     break;


     /* Match a single character type; inline for speed */


     case OP_ANY:
-    if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
+    if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
     /* Fall through */


     case OP_ALLANY:
     if (eptr >= md->end_subject)   /* DO NOT merge the eptr++ here; it must */
       {                            /* not be updated before SCHECK_PARTIAL. */
       SCHECK_PARTIAL();
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     eptr++;
     if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
@@ -2200,7 +2197,7 @@
     if (eptr >= md->end_subject)   /* DO NOT merge the eptr++ here; it must */
       {                            /* not be updated before SCHECK_PARTIAL. */
       SCHECK_PARTIAL();
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     eptr++;
     ecode++;
@@ -2210,7 +2207,7 @@
     if (eptr >= md->end_subject)
       {
       SCHECK_PARTIAL();
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     GETCHARINCTEST(c, eptr);
     if (
@@ -2219,7 +2216,7 @@
 #endif
        (md->ctypes[c] & ctype_digit) != 0
        )
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
     ecode++;
     break;


@@ -2227,7 +2224,7 @@
     if (eptr >= md->end_subject)
       {
       SCHECK_PARTIAL();
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     GETCHARINCTEST(c, eptr);
     if (
@@ -2236,7 +2233,7 @@
 #endif
        (md->ctypes[c] & ctype_digit) == 0
        )
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
     ecode++;
     break;


@@ -2244,7 +2241,7 @@
     if (eptr >= md->end_subject)
       {
       SCHECK_PARTIAL();
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     GETCHARINCTEST(c, eptr);
     if (
@@ -2253,7 +2250,7 @@
 #endif
        (md->ctypes[c] & ctype_space) != 0
        )
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
     ecode++;
     break;


@@ -2261,7 +2258,7 @@
     if (eptr >= md->end_subject)
       {
       SCHECK_PARTIAL();
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     GETCHARINCTEST(c, eptr);
     if (
@@ -2270,7 +2267,7 @@
 #endif
        (md->ctypes[c] & ctype_space) == 0
        )
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
     ecode++;
     break;


@@ -2278,7 +2275,7 @@
     if (eptr >= md->end_subject)
       {
       SCHECK_PARTIAL();
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     GETCHARINCTEST(c, eptr);
     if (
@@ -2287,7 +2284,7 @@
 #endif
        (md->ctypes[c] & ctype_word) != 0
        )
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
     ecode++;
     break;


@@ -2295,7 +2292,7 @@
     if (eptr >= md->end_subject)
       {
       SCHECK_PARTIAL();
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     GETCHARINCTEST(c, eptr);
     if (
@@ -2304,7 +2301,7 @@
 #endif
        (md->ctypes[c] & ctype_word) == 0
        )
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
     ecode++;
     break;


@@ -2312,12 +2309,12 @@
     if (eptr >= md->end_subject)
       {
       SCHECK_PARTIAL();
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     GETCHARINCTEST(c, eptr);
     switch(c)
       {
-      default: MRRETURN(MATCH_NOMATCH);
+      default: RRETURN(MATCH_NOMATCH);


       case 0x000d:
       if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
@@ -2331,7 +2328,7 @@
       case 0x0085:
       case 0x2028:
       case 0x2029:
-      if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
+      if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
       break;
       }
     ecode++;
@@ -2341,7 +2338,7 @@
     if (eptr >= md->end_subject)
       {
       SCHECK_PARTIAL();
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     GETCHARINCTEST(c, eptr);
     switch(c)
@@ -2366,7 +2363,7 @@
       case 0x202f:    /* NARROW NO-BREAK SPACE */
       case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
       case 0x3000:    /* IDEOGRAPHIC SPACE */
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     ecode++;
     break;
@@ -2375,12 +2372,12 @@
     if (eptr >= md->end_subject)
       {
       SCHECK_PARTIAL();
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     GETCHARINCTEST(c, eptr);
     switch(c)
       {
-      default: MRRETURN(MATCH_NOMATCH);
+      default: RRETURN(MATCH_NOMATCH);
       case 0x09:      /* HT */
       case 0x20:      /* SPACE */
       case 0xa0:      /* NBSP */
@@ -2409,7 +2406,7 @@
     if (eptr >= md->end_subject)
       {
       SCHECK_PARTIAL();
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     GETCHARINCTEST(c, eptr);
     switch(c)
@@ -2422,7 +2419,7 @@
       case 0x85:      /* NEL */
       case 0x2028:    /* LINE SEPARATOR */
       case 0x2029:    /* PARAGRAPH SEPARATOR */
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     ecode++;
     break;
@@ -2431,12 +2428,12 @@
     if (eptr >= md->end_subject)
       {
       SCHECK_PARTIAL();
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     GETCHARINCTEST(c, eptr);
     switch(c)
       {
-      default: MRRETURN(MATCH_NOMATCH);
+      default: RRETURN(MATCH_NOMATCH);
       case 0x0a:      /* LF */
       case 0x0b:      /* VT */
       case 0x0c:      /* FF */
@@ -2458,7 +2455,7 @@
     if (eptr >= md->end_subject)
       {
       SCHECK_PARTIAL();
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     GETCHARINCTEST(c, eptr);
       {
@@ -2467,29 +2464,29 @@
       switch(ecode[1])
         {
         case PT_ANY:
-        if (op == OP_NOTPROP) MRRETURN(MATCH_NOMATCH);
+        if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
         break;


         case PT_LAMP:
         if ((prop->chartype == ucp_Lu ||
              prop->chartype == ucp_Ll ||
              prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
-          MRRETURN(MATCH_NOMATCH);
+          RRETURN(MATCH_NOMATCH);
         break;


         case PT_GC:
         if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))
-          MRRETURN(MATCH_NOMATCH);
+          RRETURN(MATCH_NOMATCH);
         break;


         case PT_PC:
         if ((ecode[2] != prop->chartype) == (op == OP_PROP))
-          MRRETURN(MATCH_NOMATCH);
+          RRETURN(MATCH_NOMATCH);
         break;


         case PT_SC:
         if ((ecode[2] != prop->script) == (op == OP_PROP))
-          MRRETURN(MATCH_NOMATCH);
+          RRETURN(MATCH_NOMATCH);
         break;


         /* These are specials */
@@ -2497,14 +2494,14 @@
         case PT_ALNUM:
         if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||
              _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
-          MRRETURN(MATCH_NOMATCH);
+          RRETURN(MATCH_NOMATCH);
         break;


         case PT_SPACE:    /* Perl space */
         if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
              c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
                == (op == OP_NOTPROP))
-          MRRETURN(MATCH_NOMATCH);
+          RRETURN(MATCH_NOMATCH);
         break;


         case PT_PXSPACE:  /* POSIX space */
@@ -2512,14 +2509,14 @@
              c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
              c == CHAR_FF || c == CHAR_CR)
                == (op == OP_NOTPROP))
-          MRRETURN(MATCH_NOMATCH);
+          RRETURN(MATCH_NOMATCH);
         break;


         case PT_WORD:
         if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||
              _pcre_ucp_gentype[prop->chartype] == ucp_N ||
              c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
-          MRRETURN(MATCH_NOMATCH);
+          RRETURN(MATCH_NOMATCH);
         break;


         /* This should never occur */
@@ -2539,10 +2536,10 @@
     if (eptr >= md->end_subject)
       {
       SCHECK_PARTIAL();
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     GETCHARINCTEST(c, eptr);
-    if (UCD_CATEGORY(c) == ucp_M) MRRETURN(MATCH_NOMATCH);
+    if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
     while (eptr < md->end_subject)
       {
       int len = 1;
@@ -2616,7 +2613,7 @@
       if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)
         {
         CHECK_PARTIAL();
-        MRRETURN(MATCH_NOMATCH);
+        RRETURN(MATCH_NOMATCH);
         }
       eptr += length;
       continue;              /* With the main loop */
@@ -2637,7 +2634,7 @@
       if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
         {
         CHECK_PARTIAL();
-        MRRETURN(MATCH_NOMATCH);
+        RRETURN(MATCH_NOMATCH);
         }
       eptr += slength;
       }
@@ -2656,11 +2653,11 @@
         int slength;
         RMATCH(eptr, ecode, offset_top, md, eptrb, RM14);
         if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-        if (fi >= max) MRRETURN(MATCH_NOMATCH);
+        if (fi >= max) RRETURN(MATCH_NOMATCH);
         if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
           {
           CHECK_PARTIAL();
-          MRRETURN(MATCH_NOMATCH);
+          RRETURN(MATCH_NOMATCH);
           }
         eptr += slength;
         }
@@ -2688,7 +2685,7 @@
         if (rrc != MATCH_NOMATCH) RRETURN(rrc);
         eptr -= length;
         }
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     /* Control never gets here */


@@ -2749,16 +2746,16 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           GETCHARINC(c, eptr);
           if (c > 255)
             {
-            if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);
+            if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
             }
           else
             {
-            if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
+            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
             }
           }
         }
@@ -2771,10 +2768,10 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           c = *eptr++;
-          if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
+          if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
           }
         }


@@ -2796,20 +2793,20 @@
             {
             RMATCH(eptr, ecode, offset_top, md, eptrb, RM16);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) MRRETURN(MATCH_NOMATCH);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINC(c, eptr);
             if (c > 255)
               {
-              if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);
+              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
               }
             else
               {
-              if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
+              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
               }
             }
           }
@@ -2821,14 +2818,14 @@
             {
             RMATCH(eptr, ecode, offset_top, md, eptrb, RM17);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) MRRETURN(MATCH_NOMATCH);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             c = *eptr++;
-            if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
+            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
             }
           }
         /* Control never gets here */
@@ -2894,7 +2891,7 @@
             }
           }


-        MRRETURN(MATCH_NOMATCH);
+        RRETURN(MATCH_NOMATCH);
         }
       }
     /* Control never gets here */
@@ -2946,10 +2943,10 @@
         if (eptr >= md->end_subject)
           {
           SCHECK_PARTIAL();
-          MRRETURN(MATCH_NOMATCH);
+          RRETURN(MATCH_NOMATCH);
           }
         GETCHARINCTEST(c, eptr);
-        if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);
+        if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);
         }


       /* If max == min we can continue with the main loop without the
@@ -2966,14 +2963,14 @@
           {
           RMATCH(eptr, ecode, offset_top, md, eptrb, RM20);
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          if (fi >= max) MRRETURN(MATCH_NOMATCH);
+          if (fi >= max) RRETURN(MATCH_NOMATCH);
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           GETCHARINCTEST(c, eptr);
-          if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);
+          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);
           }
         /* Control never gets here */
         }
@@ -3002,7 +2999,7 @@
           if (eptr-- == pp) break;        /* Stop if tried at original pos */
           if (utf8) BACKCHAR(eptr);
           }
-        MRRETURN(MATCH_NOMATCH);
+        RRETURN(MATCH_NOMATCH);
         }


       /* Control never gets here */
@@ -3021,9 +3018,9 @@
       if (length > md->end_subject - eptr)
         {
         CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
-        MRRETURN(MATCH_NOMATCH);
+        RRETURN(MATCH_NOMATCH);
         }
-      while (length-- > 0) if (*ecode++ != *eptr++) MRRETURN(MATCH_NOMATCH);
+      while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);
       }
     else
 #endif
@@ -3033,9 +3030,9 @@
       if (md->end_subject - eptr < 1)
         {
         SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
-        MRRETURN(MATCH_NOMATCH);
+        RRETURN(MATCH_NOMATCH);
         }
-      if (ecode[1] != *eptr++) MRRETURN(MATCH_NOMATCH);
+      if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);
       ecode += 2;
       }
     break;
@@ -3053,7 +3050,7 @@
       if (length > md->end_subject - eptr)
         {
         CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
-        MRRETURN(MATCH_NOMATCH);
+        RRETURN(MATCH_NOMATCH);
         }


       /* If the pattern character's value is < 128, we have only one byte, and
@@ -3061,7 +3058,7 @@


       if (fc < 128)
         {
-        if (md->lcc[*ecode++] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
+        if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
         }


       /* Otherwise we must pick up the subject character */
@@ -3080,7 +3077,7 @@
 #ifdef SUPPORT_UCP
           if (dc != UCD_OTHERCASE(fc))
 #endif
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
           }
         }
       }
@@ -3092,9 +3089,9 @@
       if (md->end_subject - eptr < 1)
         {
         SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
-        MRRETURN(MATCH_NOMATCH);
+        RRETURN(MATCH_NOMATCH);
         }
-      if (md->lcc[ecode[1]] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
+      if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
       ecode += 2;
       }
     break;
@@ -3200,7 +3197,7 @@
           else
             {
             CHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           }


@@ -3212,7 +3209,7 @@
             {
             RMATCH(eptr, ecode, offset_top, md, eptrb, RM22);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) MRRETURN(MATCH_NOMATCH);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
             if (eptr <= md->end_subject - length &&
               memcmp(eptr, charptr, length) == 0) eptr += length;
 #ifdef SUPPORT_UCP
@@ -3223,7 +3220,7 @@
             else
               {
               CHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             }
           /* Control never gets here */
@@ -3254,7 +3251,7 @@
             {
             RMATCH(eptr, ecode, offset_top, md, eptrb, RM23);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (eptr == pp) { MRRETURN(MATCH_NOMATCH); }
+            if (eptr == pp) { RRETURN(MATCH_NOMATCH); }
 #ifdef SUPPORT_UCP
             eptr--;
             BACKCHAR(eptr);
@@ -3297,9 +3294,9 @@
         if (eptr >= md->end_subject)
           {
           SCHECK_PARTIAL();
-          MRRETURN(MATCH_NOMATCH);
+          RRETURN(MATCH_NOMATCH);
           }
-        if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
+        if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
         }
       if (min == max) continue;
       if (minimize)
@@ -3308,13 +3305,13 @@
           {
           RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          if (fi >= max) MRRETURN(MATCH_NOMATCH);
+          if (fi >= max) RRETURN(MATCH_NOMATCH);
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
-          if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
+          if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
           }
         /* Control never gets here */
         }
@@ -3340,7 +3337,7 @@
           eptr--;
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
           }
-        MRRETURN(MATCH_NOMATCH);
+        RRETURN(MATCH_NOMATCH);
         }
       /* Control never gets here */
       }
@@ -3354,9 +3351,9 @@
         if (eptr >= md->end_subject)
           {
           SCHECK_PARTIAL();
-          MRRETURN(MATCH_NOMATCH);
+          RRETURN(MATCH_NOMATCH);
           }
-        if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);
+        if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
         }


       if (min == max) continue;
@@ -3367,13 +3364,13 @@
           {
           RMATCH(eptr, ecode, offset_top, md, eptrb, RM26);
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          if (fi >= max) MRRETURN(MATCH_NOMATCH);
+          if (fi >= max) RRETURN(MATCH_NOMATCH);
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
-          if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);
+          if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
           }
         /* Control never gets here */
         }
@@ -3398,7 +3395,7 @@
           eptr--;
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
           }
-        MRRETURN(MATCH_NOMATCH);
+        RRETURN(MATCH_NOMATCH);
         }
       }
     /* Control never gets here */
@@ -3411,7 +3408,7 @@
     if (eptr >= md->end_subject)
       {
       SCHECK_PARTIAL();
-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     ecode++;
     GETCHARINCTEST(c, eptr);
@@ -3421,11 +3418,11 @@
       if (c < 256)
 #endif
       c = md->lcc[c];
-      if (md->lcc[*ecode++] == c) MRRETURN(MATCH_NOMATCH);
+      if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH);
       }
     else    /* Caseful */
       {
-      if (*ecode++ == c) MRRETURN(MATCH_NOMATCH);
+      if (*ecode++ == c) RRETURN(MATCH_NOMATCH);
       }
     break;


@@ -3532,11 +3529,11 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           GETCHARINC(d, eptr);
           if (d < 256) d = md->lcc[d];
-          if (fc == d) MRRETURN(MATCH_NOMATCH);
+          if (fc == d) RRETURN(MATCH_NOMATCH);
           }
         }
       else
@@ -3549,9 +3546,9 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
-          if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
+          if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
           }
         }


@@ -3568,15 +3565,15 @@
             {
             RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) MRRETURN(MATCH_NOMATCH);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINC(d, eptr);
             if (d < 256) d = md->lcc[d];
-            if (fc == d) MRRETURN(MATCH_NOMATCH);
+            if (fc == d) RRETURN(MATCH_NOMATCH);
             }
           }
         else
@@ -3587,13 +3584,13 @@
             {
             RMATCH(eptr, ecode, offset_top, md, eptrb, RM29);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) MRRETURN(MATCH_NOMATCH);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
-            if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
+            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
             }
           }
         /* Control never gets here */
@@ -3655,7 +3652,7 @@
             }
           }


-        MRRETURN(MATCH_NOMATCH);
+        RRETURN(MATCH_NOMATCH);
         }
       /* Control never gets here */
       }
@@ -3674,10 +3671,10 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           GETCHARINC(d, eptr);
-          if (fc == d) MRRETURN(MATCH_NOMATCH);
+          if (fc == d) RRETURN(MATCH_NOMATCH);
           }
         }
       else
@@ -3689,9 +3686,9 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
-          if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);
+          if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
           }
         }


@@ -3708,14 +3705,14 @@
             {
             RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) MRRETURN(MATCH_NOMATCH);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINC(d, eptr);
-            if (fc == d) MRRETURN(MATCH_NOMATCH);
+            if (fc == d) RRETURN(MATCH_NOMATCH);
             }
           }
         else
@@ -3726,13 +3723,13 @@
             {
             RMATCH(eptr, ecode, offset_top, md, eptrb, RM33);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) MRRETURN(MATCH_NOMATCH);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
-            if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);
+            if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
             }
           }
         /* Control never gets here */
@@ -3793,7 +3790,7 @@
             }
           }


-        MRRETURN(MATCH_NOMATCH);
+        RRETURN(MATCH_NOMATCH);
         }
       }
     /* Control never gets here */
@@ -3887,13 +3884,13 @@
         switch(prop_type)
           {
           case PT_ANY:
-          if (prop_fail_result) MRRETURN(MATCH_NOMATCH);
+          if (prop_fail_result) RRETURN(MATCH_NOMATCH);
           for (i = 1; i <= min; i++)
             {
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINCTEST(c, eptr);
             }
@@ -3906,14 +3903,14 @@
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINCTEST(c, eptr);
             chartype = UCD_CHARTYPE(c);
             if ((chartype == ucp_Lu ||
                  chartype == ucp_Ll ||
                  chartype == ucp_Lt) == prop_fail_result)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             }
           break;


@@ -3923,11 +3920,11 @@
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINCTEST(c, eptr);
             if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             }
           break;


@@ -3937,11 +3934,11 @@
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINCTEST(c, eptr);
             if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             }
           break;


@@ -3951,11 +3948,11 @@
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINCTEST(c, eptr);
             if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             }
           break;


@@ -3966,12 +3963,12 @@
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINCTEST(c, eptr);
             category = UCD_CATEGORY(c);
             if ((category == ucp_L || category == ucp_N) == prop_fail_result)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             }
           break;


@@ -3981,13 +3978,13 @@
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINCTEST(c, eptr);
             if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
                  c == CHAR_FF || c == CHAR_CR)
                    == prop_fail_result)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             }
           break;


@@ -3997,13 +3994,13 @@
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINCTEST(c, eptr);
             if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
                  c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
                    == prop_fail_result)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             }
           break;


@@ -4014,13 +4011,13 @@
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINCTEST(c, eptr);
             category = UCD_CATEGORY(c);
             if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE)
                    == prop_fail_result)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             }
           break;


@@ -4041,10 +4038,10 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           GETCHARINCTEST(c, eptr);
-          if (UCD_CATEGORY(c) == ucp_M) MRRETURN(MATCH_NOMATCH);
+          if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
           while (eptr < md->end_subject)
             {
             int len = 1;
@@ -4069,9 +4066,9 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
-          if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
+          if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
           eptr++;
           while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
           }
@@ -4083,7 +4080,7 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           eptr++;
           while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
@@ -4091,7 +4088,7 @@
         break;


         case OP_ANYBYTE:
-        if (eptr > md->end_subject - min) MRRETURN(MATCH_NOMATCH);
+        if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);
         eptr += min;
         break;


@@ -4101,12 +4098,12 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           GETCHARINC(c, eptr);
           switch(c)
             {
-            default: MRRETURN(MATCH_NOMATCH);
+            default: RRETURN(MATCH_NOMATCH);


             case 0x000d:
             if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
@@ -4120,7 +4117,7 @@
             case 0x0085:
             case 0x2028:
             case 0x2029:
-            if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
+            if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
             break;
             }
           }
@@ -4132,7 +4129,7 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           GETCHARINC(c, eptr);
           switch(c)
@@ -4157,7 +4154,7 @@
             case 0x202f:    /* NARROW NO-BREAK SPACE */
             case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
             case 0x3000:    /* IDEOGRAPHIC SPACE */
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           }
         break;
@@ -4168,12 +4165,12 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           GETCHARINC(c, eptr);
           switch(c)
             {
-            default: MRRETURN(MATCH_NOMATCH);
+            default: RRETURN(MATCH_NOMATCH);
             case 0x09:      /* HT */
             case 0x20:      /* SPACE */
             case 0xa0:      /* NBSP */
@@ -4204,7 +4201,7 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           GETCHARINC(c, eptr);
           switch(c)
@@ -4217,7 +4214,7 @@
             case 0x85:      /* NEL */
             case 0x2028:    /* LINE SEPARATOR */
             case 0x2029:    /* PARAGRAPH SEPARATOR */
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           }
         break;
@@ -4228,12 +4225,12 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           GETCHARINC(c, eptr);
           switch(c)
             {
-            default: MRRETURN(MATCH_NOMATCH);
+            default: RRETURN(MATCH_NOMATCH);
             case 0x0a:      /* LF */
             case 0x0b:      /* VT */
             case 0x0c:      /* FF */
@@ -4252,11 +4249,11 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           GETCHARINC(c, eptr);
           if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
           }
         break;


@@ -4266,10 +4263,10 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
           /* No need to skip more bytes - we know it's a 1-byte character */
           }
         break;
@@ -4280,10 +4277,10 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
           while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
           }
         break;
@@ -4294,10 +4291,10 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
           /* No need to skip more bytes - we know it's a 1-byte character */
           }
         break;
@@ -4308,10 +4305,10 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
           while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
           }
         break;
@@ -4322,10 +4319,10 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
           /* No need to skip more bytes - we know it's a 1-byte character */
           }
         break;
@@ -4348,9 +4345,9 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
-          if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
+          if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
           eptr++;
           }
         break;
@@ -4359,7 +4356,7 @@
         if (eptr > md->end_subject - min)
           {
           SCHECK_PARTIAL();
-          MRRETURN(MATCH_NOMATCH);
+          RRETURN(MATCH_NOMATCH);
           }
         eptr += min;
         break;
@@ -4368,7 +4365,7 @@
         if (eptr > md->end_subject - min)
           {
           SCHECK_PARTIAL();
-          MRRETURN(MATCH_NOMATCH);
+          RRETURN(MATCH_NOMATCH);
           }
         eptr += min;
         break;
@@ -4379,11 +4376,11 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           switch(*eptr++)
             {
-            default: MRRETURN(MATCH_NOMATCH);
+            default: RRETURN(MATCH_NOMATCH);


             case 0x000d:
             if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
@@ -4395,7 +4392,7 @@
             case 0x000b:
             case 0x000c:
             case 0x0085:
-            if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
+            if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
             break;
             }
           }
@@ -4407,7 +4404,7 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           switch(*eptr++)
             {
@@ -4415,7 +4412,7 @@
             case 0x09:      /* HT */
             case 0x20:      /* SPACE */
             case 0xa0:      /* NBSP */
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           }
         break;
@@ -4426,11 +4423,11 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           switch(*eptr++)
             {
-            default: MRRETURN(MATCH_NOMATCH);
+            default: RRETURN(MATCH_NOMATCH);
             case 0x09:      /* HT */
             case 0x20:      /* SPACE */
             case 0xa0:      /* NBSP */
@@ -4445,7 +4442,7 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           switch(*eptr++)
             {
@@ -4455,7 +4452,7 @@
             case 0x0c:      /* FF */
             case 0x0d:      /* CR */
             case 0x85:      /* NEL */
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           }
         break;
@@ -4466,11 +4463,11 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           switch(*eptr++)
             {
-            default: MRRETURN(MATCH_NOMATCH);
+            default: RRETURN(MATCH_NOMATCH);
             case 0x0a:      /* LF */
             case 0x0b:      /* VT */
             case 0x0c:      /* FF */
@@ -4487,9 +4484,9 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
-          if ((md->ctypes[*eptr++] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH);
+          if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
           }
         break;


@@ -4499,9 +4496,9 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
-          if ((md->ctypes[*eptr++] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH);
+          if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
           }
         break;


@@ -4511,9 +4508,9 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
-          if ((md->ctypes[*eptr++] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH);
+          if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
           }
         break;


@@ -4523,9 +4520,9 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
-          if ((md->ctypes[*eptr++] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH);
+          if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
           }
         break;


@@ -4535,10 +4532,10 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           if ((md->ctypes[*eptr++] & ctype_word) != 0)
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
           }
         break;


@@ -4548,10 +4545,10 @@
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           if ((md->ctypes[*eptr++] & ctype_word) == 0)
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
           }
         break;


@@ -4580,14 +4577,14 @@
             {
             RMATCH(eptr, ecode, offset_top, md, eptrb, RM36);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) MRRETURN(MATCH_NOMATCH);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINCTEST(c, eptr);
-            if (prop_fail_result) MRRETURN(MATCH_NOMATCH);
+            if (prop_fail_result) RRETURN(MATCH_NOMATCH);
             }
           /* Control never gets here */


@@ -4597,18 +4594,18 @@
             int chartype;
             RMATCH(eptr, ecode, offset_top, md, eptrb, RM37);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) MRRETURN(MATCH_NOMATCH);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINCTEST(c, eptr);
             chartype = UCD_CHARTYPE(c);
             if ((chartype == ucp_Lu ||
                  chartype == ucp_Ll ||
                  chartype == ucp_Lt) == prop_fail_result)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             }
           /* Control never gets here */


@@ -4617,15 +4614,15 @@
             {
             RMATCH(eptr, ecode, offset_top, md, eptrb, RM38);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) MRRETURN(MATCH_NOMATCH);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINCTEST(c, eptr);
             if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             }
           /* Control never gets here */


@@ -4634,15 +4631,15 @@
             {
             RMATCH(eptr, ecode, offset_top, md, eptrb, RM39);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) MRRETURN(MATCH_NOMATCH);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINCTEST(c, eptr);
             if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             }
           /* Control never gets here */


@@ -4651,15 +4648,15 @@
             {
             RMATCH(eptr, ecode, offset_top, md, eptrb, RM40);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) MRRETURN(MATCH_NOMATCH);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINCTEST(c, eptr);
             if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             }
           /* Control never gets here */


@@ -4669,16 +4666,16 @@
             int category;
             RMATCH(eptr, ecode, offset_top, md, eptrb, RM59);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) MRRETURN(MATCH_NOMATCH);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINCTEST(c, eptr);
             category = UCD_CATEGORY(c);
             if ((category == ucp_L || category == ucp_N) == prop_fail_result)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             }
           /* Control never gets here */


@@ -4687,17 +4684,17 @@
             {
             RMATCH(eptr, ecode, offset_top, md, eptrb, RM60);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) MRRETURN(MATCH_NOMATCH);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINCTEST(c, eptr);
             if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
                  c == CHAR_FF || c == CHAR_CR)
                    == prop_fail_result)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             }
           /* Control never gets here */


@@ -4706,17 +4703,17 @@
             {
             RMATCH(eptr, ecode, offset_top, md, eptrb, RM61);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) MRRETURN(MATCH_NOMATCH);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINCTEST(c, eptr);
             if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
                  c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
                    == prop_fail_result)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             }
           /* Control never gets here */


@@ -4726,11 +4723,11 @@
             int category;
             RMATCH(eptr, ecode, offset_top, md, eptrb, RM62);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) MRRETURN(MATCH_NOMATCH);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
             if (eptr >= md->end_subject)
               {
               SCHECK_PARTIAL();
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             GETCHARINCTEST(c, eptr);
             category = UCD_CATEGORY(c);
@@ -4738,7 +4735,7 @@
                  category == ucp_N ||
                  c == CHAR_UNDERSCORE)
                    == prop_fail_result)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             }
           /* Control never gets here */


@@ -4758,14 +4755,14 @@
           {
           RMATCH(eptr, ecode, offset_top, md, eptrb, RM41);
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          if (fi >= max) MRRETURN(MATCH_NOMATCH);
+          if (fi >= max) RRETURN(MATCH_NOMATCH);
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           GETCHARINCTEST(c, eptr);
-          if (UCD_CATEGORY(c) == ucp_M) MRRETURN(MATCH_NOMATCH);
+          if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
           while (eptr < md->end_subject)
             {
             int len = 1;
@@ -4786,14 +4783,14 @@
           {
           RMATCH(eptr, ecode, offset_top, md, eptrb, RM42);
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          if (fi >= max) MRRETURN(MATCH_NOMATCH);
+          if (fi >= max) RRETURN(MATCH_NOMATCH);
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           if (ctype == OP_ANY && IS_NEWLINE(eptr))
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
           GETCHARINC(c, eptr);
           switch(ctype)
             {
@@ -4805,7 +4802,7 @@
             case OP_ANYNL:
             switch(c)
               {
-              default: MRRETURN(MATCH_NOMATCH);
+              default: RRETURN(MATCH_NOMATCH);
               case 0x000d:
               if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
               break;
@@ -4817,7 +4814,7 @@
               case 0x0085:
               case 0x2028:
               case 0x2029:
-              if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
+              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
               break;
               }
             break;
@@ -4845,14 +4842,14 @@
               case 0x202f:    /* NARROW NO-BREAK SPACE */
               case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
               case 0x3000:    /* IDEOGRAPHIC SPACE */
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             break;


             case OP_HSPACE:
             switch(c)
               {
-              default: MRRETURN(MATCH_NOMATCH);
+              default: RRETURN(MATCH_NOMATCH);
               case 0x09:      /* HT */
               case 0x20:      /* SPACE */
               case 0xa0:      /* NBSP */
@@ -4887,14 +4884,14 @@
               case 0x85:      /* NEL */
               case 0x2028:    /* LINE SEPARATOR */
               case 0x2029:    /* PARAGRAPH SEPARATOR */
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             break;


             case OP_VSPACE:
             switch(c)
               {
-              default: MRRETURN(MATCH_NOMATCH);
+              default: RRETURN(MATCH_NOMATCH);
               case 0x0a:      /* LF */
               case 0x0b:      /* VT */
               case 0x0c:      /* FF */
@@ -4908,32 +4905,32 @@


             case OP_NOT_DIGIT:
             if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             break;


             case OP_DIGIT:
             if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             break;


             case OP_NOT_WHITESPACE:
             if (c < 256 && (md->ctypes[c] & ctype_space) != 0)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             break;


             case OP_WHITESPACE:
             if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             break;


             case OP_NOT_WORDCHAR:
             if (c < 256 && (md->ctypes[c] & ctype_word) != 0)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             break;


             case OP_WORDCHAR:
             if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
             break;


             default:
@@ -4949,14 +4946,14 @@
           {
           RMATCH(eptr, ecode, offset_top, md, eptrb, RM43);
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          if (fi >= max) MRRETURN(MATCH_NOMATCH);
+          if (fi >= max) RRETURN(MATCH_NOMATCH);
           if (eptr >= md->end_subject)
             {
             SCHECK_PARTIAL();
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
             }
           if (ctype == OP_ANY && IS_NEWLINE(eptr))
-            MRRETURN(MATCH_NOMATCH);
+            RRETURN(MATCH_NOMATCH);
           c = *eptr++;
           switch(ctype)
             {
@@ -4968,7 +4965,7 @@
             case OP_ANYNL:
             switch(c)
               {
-              default: MRRETURN(MATCH_NOMATCH);
+              default: RRETURN(MATCH_NOMATCH);
               case 0x000d:
               if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
               break;
@@ -4979,7 +4976,7 @@
               case 0x000b:
               case 0x000c:
               case 0x0085:
-              if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
+              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
               break;
               }
             break;
@@ -4991,14 +4988,14 @@
               case 0x09:      /* HT */
               case 0x20:      /* SPACE */
               case 0xa0:      /* NBSP */
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             break;


             case OP_HSPACE:
             switch(c)
               {
-              default: MRRETURN(MATCH_NOMATCH);
+              default: RRETURN(MATCH_NOMATCH);
               case 0x09:      /* HT */
               case 0x20:      /* SPACE */
               case 0xa0:      /* NBSP */
@@ -5015,14 +5012,14 @@
               case 0x0c:      /* FF */
               case 0x0d:      /* CR */
               case 0x85:      /* NEL */
-              MRRETURN(MATCH_NOMATCH);
+              RRETURN(MATCH_NOMATCH);
               }
             break;


             case OP_VSPACE:
             switch(c)
               {
-              default: MRRETURN(MATCH_NOMATCH);
+              default: RRETURN(MATCH_NOMATCH);
               case 0x0a:      /* LF */
               case 0x0b:      /* VT */
               case 0x0c:      /* FF */
@@ -5033,27 +5030,27 @@
             break;


             case OP_NOT_DIGIT:
-            if ((md->ctypes[c] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH);
+            if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
             break;


             case OP_DIGIT:
-            if ((md->ctypes[c] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH);
+            if ((md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
             break;


             case OP_NOT_WHITESPACE:
-            if ((md->ctypes[c] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH);
+            if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
             break;


             case OP_WHITESPACE:
-            if  ((md->ctypes[c] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH);
+            if  ((md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
             break;


             case OP_NOT_WORDCHAR:
-            if ((md->ctypes[c] & ctype_word) != 0) MRRETURN(MATCH_NOMATCH);
+            if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
             break;


             case OP_WORDCHAR:
-            if ((md->ctypes[c] & ctype_word) == 0) MRRETURN(MATCH_NOMATCH);
+            if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
             break;


             default:
@@ -5795,7 +5792,7 @@


       /* Get here if we can't make it match with any permitted repetitions */


-      MRRETURN(MATCH_NOMATCH);
+      RRETURN(MATCH_NOMATCH);
       }
     /* Control never gets here */


@@ -6090,6 +6087,7 @@
md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
md->use_ucp = (re->options & PCRE_UCP) != 0;
md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
+md->ignore_skip_arg = FALSE;

/* Some options are unpacked into BOOL variables in the hope that testing
them will be faster than individual option bits. */
@@ -6100,7 +6098,7 @@
md->notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;

 md->hitend = FALSE;
-md->mark = NULL;                        /* In case never set */
+md->mark = md->nomatch_mark = NULL;     /* In case never set */


 md->recursive = NULL;                   /* No recursion at top level */
 md->hasthen = (re->flags & PCRE_HASTHEN) != 0;
@@ -6452,11 +6450,23 @@
   md->match_call_count = 0;
   md->match_function_type = 0;
   md->end_offset_top = 0;
-  rc = match(start_match, md->start_code, start_match, NULL, 2, md, NULL, 0);
+  rc = match(start_match, md->start_code, start_match, 2, md, NULL, 0);
   if (md->hitend && start_partial == NULL) start_partial = md->start_used_ptr;


   switch(rc)
     {
+    /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched
+    the SKIP's arg was not found. In this circumstance, Perl ignores the SKIP 
+    entirely. The only way we can do that is to re-do the match at the same 
+    point, with a flag to force SKIP with an argument to be ignored. Just 
+    treating this case as NOMATCH does not work because it does not check other 
+    alternatives in patterns such as A(*SKIP:A)B|AC when the subject is AC. */
+
+    case MATCH_SKIP_ARG:
+    new_start_match = start_match;
+    md->ignore_skip_arg = TRUE;
+    break; 
+
     /* SKIP passes back the next starting point explicitly, but if it is the
     same as the match we have just done, treat it as NOMATCH. */


@@ -6468,18 +6478,13 @@
       }
     /* Fall through */


-    /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched
-    the SKIP's arg was not found. We also treat this as NOMATCH. */
-
-    case MATCH_SKIP_ARG:
-    /* Fall through */
-
     /* NOMATCH and PRUNE advance by one character. THEN at this level acts
-    exactly like PRUNE. */
+    exactly like PRUNE. Unset the ignore SKIP-with-argument flag. */


     case MATCH_NOMATCH:
     case MATCH_PRUNE:
     case MATCH_THEN:
+    md->ignore_skip_arg = FALSE;
     new_start_match = start_match + 1;
 #ifdef SUPPORT_UTF8
     if (utf8)
@@ -6608,8 +6613,12 @@
     offsets[1] = (int)(md->end_match_ptr - md->start_subject);
     }


+  /* Return MARK data if requested */
+   
+  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
+    *(extra_data->mark) = (unsigned char *)(md->mark);
   DPRINTF((">>>> returning %d\n", rc));
-  goto RETURN_MARK;
+  return rc;
   }


/* Control gets here if there has been an error, or if the overall match
@@ -6653,10 +6662,8 @@

/* Return the MARK data if it has been requested. */

-RETURN_MARK:
-
if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
- *(extra_data->mark) = (unsigned char *)(md->mark);
+ *(extra_data->mark) = (unsigned char *)(md->nomatch_mark);
return rc;
}


Modified: code/trunk/pcre_internal.h
===================================================================
--- code/trunk/pcre_internal.h    2011-11-28 20:39:30 UTC (rev 770)
+++ code/trunk/pcre_internal.h    2011-11-29 15:34:12 UTC (rev 771)
@@ -1824,6 +1824,7 @@
   BOOL   hitend;                /* Hit the end of the subject at some point */
   BOOL   bsr_anycrlf;           /* \R is just any CRLF, not full Unicode */
   BOOL   hasthen;               /* Pattern contains (*THEN) */
+  BOOL   ignore_skip_arg;       /* For re-run when SKIP name not found */ 
   const  uschar *start_code;    /* For use when recursing */
   USPTR  start_subject;         /* Start of the subject string */
   USPTR  end_subject;           /* End of the subject string */
@@ -1839,7 +1840,8 @@
   int    eptrn;                 /* Next free eptrblock */
   recursion_info *recursive;    /* Linked list of recursion data */
   void  *callout_data;          /* To pass back to callouts */
-  const  uschar *mark;          /* Mark pointer to pass back */
+  const  uschar *mark;          /* Mark pointer to pass back on success */
+  const  uschar *nomatch_mark;  /* Mark pointer to pass back on failure */ 
   const  uschar *once_target;   /* Where to back up to for atomic groups */
 } match_data;



Modified: code/trunk/perltest.pl
===================================================================
--- code/trunk/perltest.pl    2011-11-28 20:39:30 UTC (rev 770)
+++ code/trunk/perltest.pl    2011-11-29 15:34:12 UTC (rev 771)
@@ -111,6 +111,10 @@


$pattern =~ s/S(?=[a-zA-Z]*$)//g;

+ # Remove /Y from a pattern (asks pcretest to disable PCRE optimization)
+
+ $pattern =~ s/Y(?=[a-zA-Z]*$)//;
+
# Check that the pattern is valid

eval "\$_ =~ ${pattern}";

Modified: code/trunk/testdata/testinput11
===================================================================
--- code/trunk/testdata/testinput11    2011-11-28 20:39:30 UTC (rev 770)
+++ code/trunk/testdata/testinput11    2011-11-29 15:34:12 UTC (rev 771)
@@ -452,20 +452,6 @@
 /A(*MARK:A)A+(*SKIP:B)(B|Z) | AC(*:B)/xK
     AAAC


-/--- We use something more complicated than individual letters here, because
-that causes different behaviour in Perl. Perhaps it disables some optimization;
-anyway, the result now matches PCRE in that no tag is passed back for the 
-failures. ---/
-    
-/(A|P)(*:A)(B|P) | (X|P)(X|P)(*:B)(Y|P)/xK
-    AABC
-    XXYZ 
-    ** Failers
-    XAQQ  
-    XAQQXZZ  
-    AXQQQ 
-    AXXQQQ 
-    
 /--- COMMIT at the start of a pattern should act like an anchor. Again, 
 however, we need the complication for Perl. ---/


@@ -803,4 +789,140 @@
 /(a)(?2){2}(.)/
     abcd


+/(*MARK:A)(*PRUNE:B)(C|X)/KS
+    C
+    D 
+
+/(*MARK:A)(*PRUNE:B)(C|X)/KSS
+    C
+    D 
+
+/(*MARK:A)(*THEN:B)(C|X)/KS
+    C
+    D 
+
+/(*MARK:A)(*THEN:B)(C|X)/KSY
+    C
+    D 
+
+/(*MARK:A)(*THEN:B)(C|X)/KSS
+    C
+    D 
+
+/--- This should fail, as the skip causes a bump to offset 3 (the skip) ---/
+
+/A(*MARK:A)A+(*SKIP)(B|Z) | AC/xK
+    AAAC
+
+/--- Same --/
+
+/A(*MARK:A)A+(*MARK:B)(*SKIP:B)(B|Z) | AC/xK
+    AAAC
+
+/A(*:A)A+(*SKIP)(B|Z) | AC/xK
+    AAAC
+
+/--- This should fail, as a null name is the same as no name ---/
+
+/A(*MARK:A)A+(*SKIP:)(B|Z) | AC/xK
+    AAAC
+
+/--- A check on what happens after hitting a mark and them bumping along to
+something that does not even start. Perl reports tags after the failures here, 
+though it does not when the individual letters are made into something 
+more complicated. ---/
+
+/A(*:A)B|XX(*:B)Y/K
+    AABC
+    XXYZ 
+    ** Failers
+    XAQQ  
+    XAQQXZZ  
+    AXQQQ 
+    AXXQQQ 
+    
+/^(A(*THEN:A)B|C(*THEN:B)D)/K
+    AB
+    CD
+    ** Failers
+    AC
+    CB    
+    
+/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/K
+    AB
+    CD
+    ** Failers
+    AC
+    CB    
+    
+/--- An empty name does not pass back an empty string. It is the same as if no
+name were given. ---/ 
+
+/^(A(*PRUNE:)B|C(*PRUNE:B)D)/K
+    AB
+    CD 
+
+/--- PRUNE goes to next bumpalong; COMMIT does not. ---/
+    
+/A(*PRUNE:A)B/K
+    ACAB
+
+/--- Mark names can be duplicated ---/
+
+/A(*:A)B|X(*:A)Y/K
+    AABC
+    XXYZ 
+    
+/b(*:m)f|a(*:n)w/K
+    aw 
+    ** Failers 
+    abc
+
+/b(*:m)f|aw/K
+    abaw
+    ** Failers 
+    abc
+    abax 
+
+/A(*MARK:A)A+(*SKIP:B)(B|Z) | AAC/xK
+    AAAC
+
+/a(*PRUNE:X)bc|qq/KY
+    ** Failers
+    axy
+
+/a(*THEN:X)bc|qq/KY
+    ** Failers
+    axy
+
+/(?=a(*MARK:A)b)..x/K
+    abxy
+    ** Failers
+    abpq  
+
+/(?=a(*MARK:A)b)..(*:Y)x/K
+    abxy
+    ** Failers
+    abpq  
+
+/(?=a(*PRUNE:A)b)..x/K
+    abxy
+    ** Failers
+    abpq  
+
+/(?=a(*PRUNE:A)b)..(*:Y)x/K
+    abxy
+    ** Failers
+    abpq  
+
+/(?=a(*THEN:A)b)..x/K
+    abxy
+    ** Failers
+    abpq  
+
+/(?=a(*THEN:A)b)..(*:Y)x/K
+    abxy
+    ** Failers
+    abpq  
+
 /-- End of testinput11 --/


Modified: code/trunk/testdata/testinput2
===================================================================
--- code/trunk/testdata/testinput2    2011-11-28 20:39:30 UTC (rev 770)
+++ code/trunk/testdata/testinput2    2011-11-29 15:34:12 UTC (rev 771)
@@ -3325,116 +3325,19 @@
 /A(*PRUNE)B|A(*PRUNE)C/K
     AC


-/--- A whole lot of tests of verbs with arguments are here rather than in test
-     11 because Perl doesn't seem to follow its specification entirely 
-     correctly. ---/
-
-/--- Perl 5.11 sets $REGERROR on the AC failure case here; PCRE does not. It is
-     not clear how Perl defines "involved in the failure of the match". ---/ 
-
-/^(A(*THEN:A)B|C(*THEN:B)D)/K
-    AB
-    CD
-    ** Failers
-    AC
-    CB    
-    
-/--- Check the use of names for success and failure. PCRE doesn't show these 
-names for success, though Perl does, contrary to its spec. ---/
-
-/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/K
-    AB
-    CD
-    ** Failers
-    AC
-    CB    
-    
-/--- An empty name does not pass back an empty string. It is the same as if no
-name were given. ---/ 
-
-/^(A(*PRUNE:)B|C(*PRUNE:B)D)/K
-    AB
-    CD 
-
-/--- PRUNE goes to next bumpalong; COMMIT does not. ---/
-    
-/A(*PRUNE:A)B/K
-    ACAB
-
-/(*MARK:A)(*PRUNE:B)(C|X)/KS
-    C
-    D 
-
-/(*MARK:A)(*PRUNE:B)(C|X)/KSS
-    C
-    D 
-
-/(*MARK:A)(*THEN:B)(C|X)/KS
-    C
-    D 
-
-/(*MARK:A)(*THEN:B)(C|X)/KSY
-    C
-    D 
-
-/(*MARK:A)(*THEN:B)(C|X)/KSS
-    C
-    D 
-
-/--- This should fail, as the skip causes a bump to offset 3 (the skip) ---/
-
-/A(*MARK:A)A+(*SKIP)(B|Z) | AC/xK
-    AAAC
-
-/--- Same --/
-
-/A(*MARK:A)A+(*MARK:B)(*SKIP:B)(B|Z) | AC/xK
-    AAAC
-
 /--- This should fail; the SKIP advances by one, but when we get to AC, the
-     PRUNE kills it. ---/ 
+     PRUNE kills it. Perl behaves differently. ---/ 


 /A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xK
     AAAC


-/A(*:A)A+(*SKIP)(B|Z) | AC/xK
-    AAAC
+/--- Mark names can be duplicated. Perl doesn't give a mark for this one,
+though PCRE does. ---/


-/--- This should fail, as a null name is the same as no name ---/
-
-/A(*MARK:A)A+(*SKIP:)(B|Z) | AC/xK
-    AAAC
-
-/--- This fails in PCRE, and I think that is in accordance with Perl's 
-     documentation, though in Perl it succeeds. ---/
-    
-/A(*MARK:A)A+(*SKIP:B)(B|Z) | AAC/xK
-    AAAC
-
-/--- Mark names can be duplicated ---/
-
-/A(*:A)B|X(*:A)Y/K
-    AABC
-    XXYZ 
-    
 /^A(*:A)B|^X(*:A)Y/K
     ** Failers
     XAQQ


-/--- A check on what happens after hitting a mark and them bumping along to
-something that does not even start. Perl reports tags after the failures here, 
-though it does not when the individual letters are made into something 
-more complicated. ---/
-
-/A(*:A)B|XX(*:B)Y/K
-    AABC
-    XXYZ 
-    ** Failers
-    XAQQ  
-    XAQQXZZ  
-    AXQQQ 
-    AXXQQQ 
-    
 /--- COMMIT at the start of a pattern should be the same as an anchor. Perl 
 optimizations defeat this. So does the PCRE optimization unless we disable it 
 with \Y. ---/
@@ -3444,78 +3347,6 @@
     ** Failers
     DEFGABC\Y  


-/--- Repeat some tests with added studying. ---/
-
-/A(*COMMIT)B/+KS
-    ACABX
- 
-/A(*THEN)B|A(*THEN)C/KS
-    AC
-
-/A(*PRUNE)B|A(*PRUNE)C/KS
-    AC
-
-/^(A(*THEN:A)B|C(*THEN:B)D)/KS
-    AB
-    CD
-    ** Failers
-    AC
-    CB    
-
-/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/KS
-    AB
-    CD
-    ** Failers
-    AC
-    CB    
-
-/^(A(*PRUNE:)B|C(*PRUNE:B)D)/KS
-    AB
-    CD 
-
-/A(*PRUNE:A)B/KS
-    ACAB
-
-/(*MARK:A)(*PRUNE:B)(C|X)/KS
-    C
-    D 
-
-/(*MARK:A)(*THEN:B)(C|X)/KS
-    C
-    D 
-
-/A(*MARK:A)A+(*SKIP)(B|Z) | AC/xKS
-    AAAC
-
-/A(*MARK:A)A+(*MARK:B)(*SKIP:B)(B|Z) | AC/xKS
-    AAAC
-    
-/A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xKS
-    AAAC
-
-/A(*:A)A+(*SKIP)(B|Z) | AC/xKS
-    AAAC
-
-/A(*MARK:A)A+(*SKIP:)(B|Z) | AC/xKS
-    AAAC
-
-/A(*MARK:A)A+(*SKIP:B)(B|Z) | AAC/xKS
-    AAAC
-
-/A(*:A)B|XX(*:B)Y/KS
-    AABC
-    XXYZ 
-    ** Failers
-    XAQQ  
-    XAQQXZZ  
-    AXQQQ 
-    AXXQQQ 
-    
-/(*COMMIT)ABC/
-    ABCDEFG
-    ** Failers
-    DEFGABC\Y  
-
 /^(ab (c+(*THEN)cd) | xyz)/x
     abcccd  


@@ -4014,4 +3845,35 @@

/(a)(?(DEFINE)(b))(?2){0,1999}?(?2)/

+/--- This test, with something more complicated than individual letters, causes
+different behaviour in Perl. Perhaps it disables some optimization; no tag is
+passed back for the failures, whereas in PCRE there is a tag. ---/
+    
+/(A|P)(*:A)(B|P) | (X|P)(X|P)(*:B)(Y|P)/xK
+    AABC
+    XXYZ 
+    ** Failers
+    XAQQ  
+    XAQQXZZ  
+    AXQQQ 
+    AXXQQQ 
+
+/-- Perl doesn't give marks for these, though it does if the alternatives are
+replaced by single letters. --/
+    
+/(b|q)(*:m)f|a(*:n)w/K
+    aw 
+    ** Failers 
+    abc
+
+/(q|b)(*:m)f|a(*:n)w/K
+    aw 
+    ** Failers 
+    abc
+
+/-- After a partial match, the behaviour is as for a failure. --/
+
+/^a(*:X)bcde/K
+   abc\P
+
 /-- End of testinput2 --/


Modified: code/trunk/testdata/testoutput11
===================================================================
--- code/trunk/testdata/testoutput11    2011-11-28 20:39:30 UTC (rev 770)
+++ code/trunk/testdata/testoutput11    2011-11-29 15:34:12 UTC (rev 771)
@@ -888,36 +888,6 @@
  0: AC
 MK: B


-/--- We use something more complicated than individual letters here, because
-that causes different behaviour in Perl. Perhaps it disables some optimization;
-anyway, the result now matches PCRE in that no tag is passed back for the 
-failures. ---/
-    
-/(A|P)(*:A)(B|P) | (X|P)(X|P)(*:B)(Y|P)/xK
-    AABC
- 0: AB
- 1: A
- 2: B
-MK: A
-    XXYZ 
- 0: XXY
- 1: <unset>
- 2: <unset>
- 3: X
- 4: X
- 5: Y
-MK: B
-    ** Failers
-No match
-    XAQQ  
-No match
-    XAQQXZZ  
-No match
-    AXQQQ 
-No match
-    AXXQQQ 
-No match
-    
 /--- COMMIT at the start of a pattern should act like an anchor. Again, 
 however, we need the complication for Perl. ---/


@@ -1447,4 +1417,239 @@
1: a
2: d

+/(*MARK:A)(*PRUNE:B)(C|X)/KS
+    C
+ 0: C
+ 1: C
+MK: B
+    D 
+No match, mark = B
+
+/(*MARK:A)(*PRUNE:B)(C|X)/KSS
+    C
+ 0: C
+ 1: C
+MK: B
+    D 
+No match, mark = B
+
+/(*MARK:A)(*THEN:B)(C|X)/KS
+    C
+ 0: C
+ 1: C
+MK: B
+    D 
+No match, mark = B
+
+/(*MARK:A)(*THEN:B)(C|X)/KSY
+    C
+ 0: C
+ 1: C
+MK: B
+    D 
+No match, mark = B
+
+/(*MARK:A)(*THEN:B)(C|X)/KSS
+    C
+ 0: C
+ 1: C
+MK: B
+    D 
+No match, mark = B
+
+/--- This should fail, as the skip causes a bump to offset 3 (the skip) ---/
+
+/A(*MARK:A)A+(*SKIP)(B|Z) | AC/xK
+    AAAC
+No match, mark = A
+
+/--- Same --/
+
+/A(*MARK:A)A+(*MARK:B)(*SKIP:B)(B|Z) | AC/xK
+    AAAC
+No match, mark = B
+
+/A(*:A)A+(*SKIP)(B|Z) | AC/xK
+    AAAC
+No match, mark = A
+
+/--- This should fail, as a null name is the same as no name ---/
+
+/A(*MARK:A)A+(*SKIP:)(B|Z) | AC/xK
+    AAAC
+No match, mark = A
+
+/--- A check on what happens after hitting a mark and them bumping along to
+something that does not even start. Perl reports tags after the failures here, 
+though it does not when the individual letters are made into something 
+more complicated. ---/
+
+/A(*:A)B|XX(*:B)Y/K
+    AABC
+ 0: AB
+MK: A
+    XXYZ 
+ 0: XXY
+MK: B
+    ** Failers
+No match
+    XAQQ  
+No match, mark = A
+    XAQQXZZ  
+No match, mark = A
+    AXQQQ 
+No match, mark = A
+    AXXQQQ 
+No match, mark = B
+    
+/^(A(*THEN:A)B|C(*THEN:B)D)/K
+    AB
+ 0: AB
+ 1: AB
+MK: A
+    CD
+ 0: CD
+ 1: CD
+MK: B
+    ** Failers
+No match
+    AC
+No match, mark = A
+    CB    
+No match, mark = B
+    
+/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/K
+    AB
+ 0: AB
+ 1: AB
+MK: A
+    CD
+ 0: CD
+ 1: CD
+MK: B
+    ** Failers
+No match
+    AC
+No match, mark = A
+    CB    
+No match, mark = B
+    
+/--- An empty name does not pass back an empty string. It is the same as if no
+name were given. ---/ 
+
+/^(A(*PRUNE:)B|C(*PRUNE:B)D)/K
+    AB
+ 0: AB
+ 1: AB
+    CD 
+ 0: CD
+ 1: CD
+MK: B
+
+/--- PRUNE goes to next bumpalong; COMMIT does not. ---/
+    
+/A(*PRUNE:A)B/K
+    ACAB
+ 0: AB
+MK: A
+
+/--- Mark names can be duplicated ---/
+
+/A(*:A)B|X(*:A)Y/K
+    AABC
+ 0: AB
+MK: A
+    XXYZ 
+ 0: XY
+MK: A
+    
+/b(*:m)f|a(*:n)w/K
+    aw 
+ 0: aw
+MK: n
+    ** Failers 
+No match, mark = n
+    abc
+No match, mark = m
+
+/b(*:m)f|aw/K
+    abaw
+ 0: aw
+    ** Failers 
+No match
+    abc
+No match, mark = m
+    abax 
+No match, mark = m
+
+/A(*MARK:A)A+(*SKIP:B)(B|Z) | AAC/xK
+    AAAC
+ 0: AAC
+
+/a(*PRUNE:X)bc|qq/KY
+    ** Failers
+No match, mark = X
+    axy
+No match, mark = X
+
+/a(*THEN:X)bc|qq/KY
+    ** Failers
+No match, mark = X
+    axy
+No match, mark = X
+
+/(?=a(*MARK:A)b)..x/K
+    abxy
+ 0: abx
+MK: A
+    ** Failers
+No match
+    abpq  
+No match
+
+/(?=a(*MARK:A)b)..(*:Y)x/K
+    abxy
+ 0: abx
+MK: Y
+    ** Failers
+No match
+    abpq  
+No match
+
+/(?=a(*PRUNE:A)b)..x/K
+    abxy
+ 0: abx
+MK: A
+    ** Failers
+No match
+    abpq  
+No match
+
+/(?=a(*PRUNE:A)b)..(*:Y)x/K
+    abxy
+ 0: abx
+MK: Y
+    ** Failers
+No match
+    abpq  
+No match
+
+/(?=a(*THEN:A)b)..x/K
+    abxy
+ 0: abx
+MK: A
+    ** Failers
+No match
+    abpq  
+No match
+
+/(?=a(*THEN:A)b)..(*:Y)x/K
+    abxy
+ 0: abx
+MK: Y
+    ** Failers
+No match
+    abpq  
+No match
+
 /-- End of testinput11 --/


Modified: code/trunk/testdata/testoutput2
===================================================================
--- code/trunk/testdata/testoutput2    2011-11-28 20:39:30 UTC (rev 770)
+++ code/trunk/testdata/testoutput2    2011-11-29 15:34:12 UTC (rev 771)
@@ -10992,176 +10992,22 @@
     AC
 No match


-/--- A whole lot of tests of verbs with arguments are here rather than in test
-     11 because Perl doesn't seem to follow its specification entirely 
-     correctly. ---/
-
-/--- Perl 5.11 sets $REGERROR on the AC failure case here; PCRE does not. It is
-     not clear how Perl defines "involved in the failure of the match". ---/ 
-
-/^(A(*THEN:A)B|C(*THEN:B)D)/K
-    AB
- 0: AB
- 1: AB
-    CD
- 0: CD
- 1: CD
-    ** Failers
-No match
-    AC
-No match
-    CB    
-No match, mark = B
-    
-/--- Check the use of names for success and failure. PCRE doesn't show these 
-names for success, though Perl does, contrary to its spec. ---/
-
-/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/K
-    AB
- 0: AB
- 1: AB
-    CD
- 0: CD
- 1: CD
-    ** Failers
-No match
-    AC
-No match, mark = A
-    CB    
-No match, mark = B
-    
-/--- An empty name does not pass back an empty string. It is the same as if no
-name were given. ---/ 
-
-/^(A(*PRUNE:)B|C(*PRUNE:B)D)/K
-    AB
- 0: AB
- 1: AB
-    CD 
- 0: CD
- 1: CD
-
-/--- PRUNE goes to next bumpalong; COMMIT does not. ---/
-    
-/A(*PRUNE:A)B/K
-    ACAB
- 0: AB
-
-/(*MARK:A)(*PRUNE:B)(C|X)/KS
-    C
- 0: C
- 1: C
-MK: A
-    D 
-No match
-
-/(*MARK:A)(*PRUNE:B)(C|X)/KSS
-    C
- 0: C
- 1: C
-MK: A
-    D 
-No match, mark = B
-
-/(*MARK:A)(*THEN:B)(C|X)/KS
-    C
- 0: C
- 1: C
-MK: A
-    D 
-No match
-
-/(*MARK:A)(*THEN:B)(C|X)/KSY
-    C
- 0: C
- 1: C
-MK: A
-    D 
-No match, mark = B
-
-/(*MARK:A)(*THEN:B)(C|X)/KSS
-    C
- 0: C
- 1: C
-MK: A
-    D 
-No match, mark = B
-
-/--- This should fail, as the skip causes a bump to offset 3 (the skip) ---/
-
-/A(*MARK:A)A+(*SKIP)(B|Z) | AC/xK
-    AAAC
-No match
-
-/--- Same --/
-
-/A(*MARK:A)A+(*MARK:B)(*SKIP:B)(B|Z) | AC/xK
-    AAAC
-No match
-
 /--- This should fail; the SKIP advances by one, but when we get to AC, the
-     PRUNE kills it. ---/ 
+     PRUNE kills it. Perl behaves differently. ---/ 


 /A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xK
     AAAC
-No match
+No match, mark = A


-/A(*:A)A+(*SKIP)(B|Z) | AC/xK
-    AAAC
-No match
+/--- Mark names can be duplicated. Perl doesn't give a mark for this one,
+though PCRE does. ---/


-/--- This should fail, as a null name is the same as no name ---/
-
-/A(*MARK:A)A+(*SKIP:)(B|Z) | AC/xK
-    AAAC
-No match
-
-/--- This fails in PCRE, and I think that is in accordance with Perl's 
-     documentation, though in Perl it succeeds. ---/
-    
-/A(*MARK:A)A+(*SKIP:B)(B|Z) | AAC/xK
-    AAAC
-No match
-
-/--- Mark names can be duplicated ---/
-
-/A(*:A)B|X(*:A)Y/K
-    AABC
- 0: AB
-MK: A
-    XXYZ 
- 0: XY
-MK: A
-    
 /^A(*:A)B|^X(*:A)Y/K
     ** Failers
 No match
     XAQQ
 No match, mark = A


-/--- A check on what happens after hitting a mark and them bumping along to
-something that does not even start. Perl reports tags after the failures here, 
-though it does not when the individual letters are made into something 
-more complicated. ---/
-
-/A(*:A)B|XX(*:B)Y/K
-    AABC
- 0: AB
-MK: A
-    XXYZ 
- 0: XXY
-MK: B
-    ** Failers
-No match
-    XAQQ  
-No match
-    XAQQXZZ  
-No match
-    AXQQQ 
-No match
-    AXXQQQ 
-No match
-    
 /--- COMMIT at the start of a pattern should be the same as an anchor. Perl 
 optimizations defeat this. So does the PCRE optimization unless we disable it 
 with \Y. ---/
@@ -11174,126 +11020,6 @@
     DEFGABC\Y  
 No match


-/--- Repeat some tests with added studying. ---/
-
-/A(*COMMIT)B/+KS
-    ACABX
-No match
- 
-/A(*THEN)B|A(*THEN)C/KS
-    AC
- 0: AC
-
-/A(*PRUNE)B|A(*PRUNE)C/KS
-    AC
-No match
-
-/^(A(*THEN:A)B|C(*THEN:B)D)/KS
-    AB
- 0: AB
- 1: AB
-    CD
- 0: CD
- 1: CD
-    ** Failers
-No match
-    AC
-No match
-    CB    
-No match, mark = B
-
-/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/KS
-    AB
- 0: AB
- 1: AB
-    CD
- 0: CD
- 1: CD
-    ** Failers
-No match
-    AC
-No match, mark = A
-    CB    
-No match, mark = B
-
-/^(A(*PRUNE:)B|C(*PRUNE:B)D)/KS
-    AB
- 0: AB
- 1: AB
-    CD 
- 0: CD
- 1: CD
-
-/A(*PRUNE:A)B/KS
-    ACAB
- 0: AB
-
-/(*MARK:A)(*PRUNE:B)(C|X)/KS
-    C
- 0: C
- 1: C
-MK: A
-    D 
-No match
-
-/(*MARK:A)(*THEN:B)(C|X)/KS
-    C
- 0: C
- 1: C
-MK: A
-    D 
-No match
-
-/A(*MARK:A)A+(*SKIP)(B|Z) | AC/xKS
-    AAAC
-No match
-
-/A(*MARK:A)A+(*MARK:B)(*SKIP:B)(B|Z) | AC/xKS
-    AAAC
-No match
-    
-/A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xKS
-    AAAC
-No match
-
-/A(*:A)A+(*SKIP)(B|Z) | AC/xKS
-    AAAC
-No match
-
-/A(*MARK:A)A+(*SKIP:)(B|Z) | AC/xKS
-    AAAC
-No match
-
-/A(*MARK:A)A+(*SKIP:B)(B|Z) | AAC/xKS
-    AAAC
-No match
-
-/A(*:A)B|XX(*:B)Y/KS
-    AABC
- 0: AB
-MK: A
-    XXYZ 
- 0: XXY
-MK: B
-    ** Failers
-No match
-    XAQQ  
-No match
-    XAQQXZZ  
-No match
-    AXQQQ 
-No match
-    AXXQQQ 
-No match
-    
-/(*COMMIT)ABC/
-    ABCDEFG
- 0: ABC
-    ** Failers
-No match
-    DEFGABC\Y  
-No match
-
 /^(ab (c+(*THEN)cd) | xyz)/x
     abcccd  
 No match
@@ -11878,11 +11604,11 @@
  1: C
 MK: A
     D
-No match
+No match, mark = A


 /(*:A)A+(*SKIP:A)(B|Z)/KS
     AAAC
-No match
+No match, mark = A


/-- --/

@@ -12260,7 +11986,6 @@
 Latest Mark: B
 +18 ^ ^          z
 +20 ^            a
-Latest Mark: <unset>
 +21 ^^           e
 +22 ^ ^          q
 +23 ^  ^         )
@@ -12597,4 +12322,60 @@


/(a)(?(DEFINE)(b))(?2){0,1999}?(?2)/

+/--- This test, with something more complicated than individual letters, causes
+different behaviour in Perl. Perhaps it disables some optimization; no tag is
+passed back for the failures, whereas in PCRE there is a tag. ---/
+    
+/(A|P)(*:A)(B|P) | (X|P)(X|P)(*:B)(Y|P)/xK
+    AABC
+ 0: AB
+ 1: A
+ 2: B
+MK: A
+    XXYZ 
+ 0: XXY
+ 1: <unset>
+ 2: <unset>
+ 3: X
+ 4: X
+ 5: Y
+MK: B
+    ** Failers
+No match
+    XAQQ  
+No match, mark = A
+    XAQQXZZ  
+No match, mark = A
+    AXQQQ 
+No match, mark = A
+    AXXQQQ 
+No match, mark = B
+
+/-- Perl doesn't give marks for these, though it does if the alternatives are
+replaced by single letters. --/
+    
+/(b|q)(*:m)f|a(*:n)w/K
+    aw 
+ 0: aw
+MK: n
+    ** Failers 
+No match, mark = n
+    abc
+No match, mark = m
+
+/(q|b)(*:m)f|a(*:n)w/K
+    aw 
+ 0: aw
+MK: n
+    ** Failers 
+No match, mark = n
+    abc
+No match, mark = m
+
+/-- After a partial match, the behaviour is as for a failure. --/
+
+/^a(*:X)bcde/K
+   abc\P
+Partial match, mark=X: abc
+
 /-- End of testinput2 --/