// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
//
//  file:  regexcmp.cpp
//
//  Copyright (C) 2002-2016 International Business Machines Corporation and others.
//  All Rights Reserved.
//
//  This file contains the ICU regular expression compiler, which is responsible
//  for processing a regular expression pattern into the compiled form that
//  is used by the match finding engine.
//

#include "unicode/utypes.h"

#if !UCONFIG_NO_REGULAR_EXPRESSIONS

#include "unicode/ustring.h"
#include "unicode/unistr.h"
#include "unicode/uniset.h"
#include "unicode/uchar.h"
#include "unicode/uchriter.h"
#include "unicode/parsepos.h"
#include "unicode/parseerr.h"
#include "unicode/regex.h"
#include "unicode/utf.h"
#include "unicode/utf16.h"
#include "patternprops.h"
#include "putilimp.h"
#include "cmemory.h"
#include "cstr.h"
#include "cstring.h"
#include "uvectr32.h"
#include "uvectr64.h"
#include "uassert.h"
#include "uinvchar.h"

#include "regeximp.h"
#include "regexcst.h"   // Contains state table for the regex pattern parser.
                        //   generated by a Perl script.
#include "regexcmp.h"
#include "regexst.h"
#include "regextxt.h"



U_NAMESPACE_BEGIN


//------------------------------------------------------------------------------
//
//  Constructor.
//
//------------------------------------------------------------------------------
RegexCompile::RegexCompile(RegexPattern *rxp, UErrorCode &status) :
   fParenStack(status), fSetStack(status), fSetOpStack(status)
{
    // Lazy init of all shared global sets (needed for init()'s empty text)
    RegexStaticSets::initGlobals(&status);

    fStatus           = &status;

    fRXPat            = rxp;
    fScanIndex        = 0;
    fLastChar         = -1;
    fPeekChar         = -1;
    fLineNum          = 1;
    fCharNum          = 0;
    fQuoteMode        = FALSE;
    fInBackslashQuote = FALSE;
    fModeFlags        = fRXPat->fFlags | 0x80000000;
    fEOLComments      = TRUE;

    fMatchOpenParen   = -1;
    fMatchCloseParen  = -1;
    fCaptureName      = NULL;
    fLastSetLiteral   = U_SENTINEL;

    if (U_SUCCESS(status) && U_FAILURE(rxp->fDeferredStatus)) {
        status = rxp->fDeferredStatus;
    }
}

static const UChar      chAmp       = 0x26;      // '&'
static const UChar      chDash      = 0x2d;      // '-'


//------------------------------------------------------------------------------
//
//  Destructor
//
//------------------------------------------------------------------------------
RegexCompile::~RegexCompile() {
    delete fCaptureName;         // Normally will be NULL, but can exist if pattern
                                 //   compilation stops with a syntax error.
}

static inline void addCategory(UnicodeSet *set, int32_t value, UErrorCode& ec) {
    set->addAll(UnicodeSet().applyIntPropertyValue(UCHAR_GENERAL_CATEGORY_MASK, value, ec));
}

//------------------------------------------------------------------------------
//
//  Compile regex pattern.   The state machine for rexexp pattern parsing is here.
//                           The state tables are hand-written in the file regexcst.txt,
//                           and converted to the form used here by a perl
//                           script regexcst.pl
//
//------------------------------------------------------------------------------
void    RegexCompile::compile(
                         const UnicodeString &pat,   // Source pat to be compiled.
                         UParseError &pp,            // Error position info
                         UErrorCode &e)              // Error Code
{
    fRXPat->fPatternString = new UnicodeString(pat);
    UText patternText = UTEXT_INITIALIZER;
    utext_openConstUnicodeString(&patternText, fRXPat->fPatternString, &e);

    if (U_SUCCESS(e)) {
        compile(&patternText, pp, e);
        utext_close(&patternText);
    }
}

//
//   compile, UText mode
//     All the work is actually done here.
//
void    RegexCompile::compile(
                         UText *pat,                 // Source pat to be compiled.
                         UParseError &pp,            // Error position info
                         UErrorCode &e)              // Error Code
{
    fStatus             = &e;
    fParseErr           = &pp;
    fStackPtr           = 0;
    fStack[fStackPtr]   = 0;

    if (U_FAILURE(*fStatus)) {
        return;
    }

    // There should be no pattern stuff in the RegexPattern object.  They can not be reused.
    U_ASSERT(fRXPat->fPattern == NULL || utext_nativeLength(fRXPat->fPattern) == 0);

    // Prepare the RegexPattern object to receive the compiled pattern.
    fRXPat->fPattern        = utext_clone(fRXPat->fPattern, pat, FALSE, TRUE, fStatus);
    if (U_FAILURE(*fStatus)) {
        return;
    }

    // Initialize the pattern scanning state machine
    fPatternLength = utext_nativeLength(pat);
    uint16_t                state = 1;
    const RegexTableEl      *tableEl;

    // UREGEX_LITERAL force entire pattern to be treated as a literal string.
    if (fModeFlags & UREGEX_LITERAL) {
        fQuoteMode = TRUE;
    }

    nextChar(fC);                        // Fetch the first char from the pattern string.

    //
    // Main loop for the regex pattern parsing state machine.
    //   Runs once per state transition.
    //   Each time through optionally performs, depending on the state table,
    //      - an advance to the the next pattern char
    //      - an action to be performed.
    //      - pushing or popping a state to/from the local state return stack.
    //   file regexcst.txt is the source for the state table.  The logic behind
    //     recongizing the pattern syntax is there, not here.
    //
    for (;;) {
        //  Bail out if anything has gone wrong.
        //  Regex pattern parsing stops on the first error encountered.
        if (U_FAILURE(*fStatus)) {
            break;
        }

        U_ASSERT(state != 0);

        // Find the state table element that matches the input char from the pattern, or the
        //    class of the input character.  Start with the first table row for this
        //    state, then linearly scan forward until we find a row that matches the
        //    character.  The last row for each state always matches all characters, so
        //    the search will stop there, if not before.
        //
        tableEl = &gRuleParseStateTable[state];
        REGEX_SCAN_DEBUG_PRINTF(("char, line, col = (\'%c\', %d, %d)    state=%s ",
            fC.fChar, fLineNum, fCharNum, RegexStateNames[state]));

        for (;;) {    // loop through table rows belonging to this state, looking for one
                      //   that matches the current input char.
            REGEX_SCAN_DEBUG_PRINTF(("."));
            if (tableEl->fCharClass < 127 && fC.fQuoted == FALSE &&   tableEl->fCharClass == fC.fChar) {
                // Table row specified an individual character, not a set, and
                //   the input character is not quoted, and
                //   the input character matched it.
                break;
            }
            if (tableEl->fCharClass == 255) {
                // Table row specified default, match anything character class.
                break;
            }
            if (tableEl->fCharClass == 254 && fC.fQuoted)  {
                // Table row specified "quoted" and the char was quoted.
                break;
            }
            if (tableEl->fCharClass == 253 && fC.fChar == (UChar32)-1)  {
                // Table row specified eof and we hit eof on the input.
                break;
            }

            if (tableEl->fCharClass >= 128 && tableEl->fCharClass < 240 &&   // Table specs a char class &&
                fC.fQuoted == FALSE &&                                       //   char is not escaped &&
                fC.fChar != (UChar32)-1) {                                   //   char is not EOF
                U_ASSERT(tableEl->fCharClass <= 137);
                if (RegexStaticSets::gStaticSets->fRuleSets[tableEl->fCharClass-128].contains(fC.fChar)) {
                    // Table row specified a character class, or set of characters,
                    //   and the current char matches it.
                    break;
                }
            }

            // No match on this row, advance to the next  row for this state,
            tableEl++;
        }
        REGEX_SCAN_DEBUG_PRINTF(("\n"));

        //
        // We've found the row of the state table that matches the current input
        //   character from the rules string.
        // Perform any action specified  by this row in the state table.
        if (doParseActions(tableEl->fAction) == FALSE) {
            // Break out of the state machine loop if the
            //   the action signalled some kind of error, or
            //   the action was to exit, occurs on normal end-of-rules-input.
            break;
        }

        if (tableEl->fPushState != 0) {
            fStackPtr++;
            if (fStackPtr >= kStackSize) {
                error(U_REGEX_INTERNAL_ERROR);
                REGEX_SCAN_DEBUG_PRINTF(("RegexCompile::parse() - state stack overflow.\n"));
                fStackPtr--;
            }
            fStack[fStackPtr] = tableEl->fPushState;
        }

        //
        //  NextChar.  This is where characters are actually fetched from the pattern.
        //             Happens under control of the 'n' tag in the state table.
        //
        if (tableEl->fNextChar) {
            nextChar(fC);
        }

        // Get the next state from the table entry, or from the
        //   state stack if the next state was specified as "pop".
        if (tableEl->fNextState != 255) {
            state = tableEl->fNextState;
        } else {
            state = fStack[fStackPtr];
            fStackPtr--;
            if (fStackPtr < 0) {
                // state stack underflow
                // This will occur if the user pattern has mis-matched parentheses,
                //   with extra close parens.
                //
                fStackPtr++;
                error(U_REGEX_MISMATCHED_PAREN);
            }
        }

    }

    if (U_FAILURE(*fStatus)) {
        // Bail out if the pattern had errors.
        //   Set stack cleanup:  a successful compile would have left it empty,
        //   but errors can leave temporary sets hanging around.
        while (!fSetStack.empty()) {
            delete (UnicodeSet *)fSetStack.pop();
        }
        return;
    }

    //
    // The pattern has now been read and processed, and the compiled code generated.
    //

    //
    // The pattern's fFrameSize so far has accumulated the requirements for
    //   storage for capture parentheses, counters, etc. that are encountered
    //   in the pattern.  Add space for the two variables that are always
    //   present in the saved state:  the input string position (int64_t) and
    //   the position in the compiled pattern.
    //
    allocateStackData(RESTACKFRAME_HDRCOUNT);

    //
    // Optimization pass 1: NOPs, back-references, and case-folding
    //
    stripNOPs();

    //
    // Get bounds for the minimum and maximum length of a string that this
    //   pattern can match.  Used to avoid looking for matches in strings that
    //   are too short.
    //
    fRXPat->fMinMatchLen = minMatchLength(3, fRXPat->fCompiledPat->size()-1);

    //
    // Optimization pass 2: match start type
    //
    matchStartType();

    //
    // Set up fast latin-1 range sets
    //
    int32_t numSets = fRXPat->fSets->size();
    fRXPat->fSets8 = new Regex8BitSet[numSets];
    // Null pointer check.
    if (fRXPat->fSets8 == NULL) {
        e = *fStatus = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    int32_t i;
    for (i=0; i<numSets; i++) {
        UnicodeSet *s = (UnicodeSet *)fRXPat->fSets->elementAt(i);
        fRXPat->fSets8[i].init(s);
    }

}





//------------------------------------------------------------------------------
//
//  doParseAction        Do some action during regex pattern parsing.
//                       Called by the parse state machine.
//
//                       Generation of the match engine PCode happens here, or
//                       in functions called from the parse actions defined here.
//
//
//------------------------------------------------------------------------------
UBool RegexCompile::doParseActions(int32_t action)
{
    UBool   returnVal = TRUE;

    switch ((Regex_PatternParseAction)action) {

    case doPatStart:
        // Start of pattern compiles to:
        //0   SAVE   2        Fall back to position of FAIL
        //1   jmp    3
        //2   FAIL            Stop if we ever reach here.
        //3   NOP             Dummy, so start of pattern looks the same as
        //                    the start of an ( grouping.
        //4   NOP             Resreved, will be replaced by a save if there are
        //                    OR | operators at the top level
        appendOp(URX_STATE_SAVE, 2);
        appendOp(URX_JMP,  3);
        appendOp(URX_FAIL, 0);

        // Standard open nonCapture paren action emits the two NOPs and
        //   sets up the paren stack frame.
        doParseActions(doOpenNonCaptureParen);
        break;

    case doPatFinish:
        // We've scanned to the end of the pattern
        //  The end of pattern compiles to:
        //        URX_END
        //    which will stop the runtime match engine.
        //  Encountering end of pattern also behaves like a close paren,
        //   and forces fixups of the State Save at the beginning of the compiled pattern
        //   and of any OR operations at the top level.
        //
        handleCloseParen();
        if (fParenStack.size() > 0) {
            // Missing close paren in pattern.
            error(U_REGEX_MISMATCHED_PAREN);
        }

        // add the END operation to the compiled pattern.
        appendOp(URX_END, 0);

        // Terminate the pattern compilation state machine.
        returnVal = FALSE;
        break;



    case doOrOperator:
        // Scanning a '|', as in (A|B)
        {
            // Generate code for any pending literals preceding the '|'
            fixLiterals(FALSE);

            // Insert a SAVE operation at the start of the pattern section preceding
            //   this OR at this level.  This SAVE will branch the match forward
            //   to the right hand side of the OR in the event that the left hand
            //   side fails to match and backtracks.  Locate the position for the
            //   save from the location on the top of the parentheses stack.
            int32_t savePosition = fParenStack.popi();
            int32_t op = (int32_t)fRXPat->fCompiledPat->elementAti(savePosition);
            U_ASSERT(URX_TYPE(op) == URX_NOP);  // original contents of reserved location
            op = buildOp(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+1);
            fRXPat->fCompiledPat->setElementAt(op, savePosition);

            // Append an JMP operation into the compiled pattern.  The operand for
            //  the JMP will eventually be the location following the ')' for the
            //  group.  This will be patched in later, when the ')' is encountered.
            appendOp(URX_JMP, 0);

            // Push the position of the newly added JMP op onto the parentheses stack.
            // This registers if for fixup when this block's close paren is encountered.
            fParenStack.push(fRXPat->fCompiledPat->size()-1, *fStatus);

            // Append a NOP to the compiled pattern.  This is the slot reserved
            //   for a SAVE in the event that there is yet another '|' following
            //   this one.
            appendOp(URX_NOP, 0);
            fParenStack.push(fRXPat->fCompiledPat->size()-1, *fStatus);
        }
        break;


    case doBeginNamedCapture:
        // Scanning (?<letter.
        //   The first letter of the name will come through again under doConinueNamedCapture.
        fCaptureName = new UnicodeString();
        if (fCaptureName == NULL) {
            error(U_MEMORY_ALLOCATION_ERROR);
        }
        break;

    case  doContinueNamedCapture:
        fCaptureName->append(fC.fChar);
        break;

    case doBadNamedCapture:
        error(U_REGEX_INVALID_CAPTURE_GROUP_NAME);
        break;
        
    case doOpenCaptureParen:
        // Open Capturing Paren, possibly named.
        //   Compile to a
        //      - NOP, which later may be replaced by a save-state if the
        //         parenthesized group gets a * quantifier, followed by
        //      - START_CAPTURE  n    where n is stack frame offset to the capture group variables.
        //      - NOP, which may later be replaced by a save-state if there
        //             is an '|' alternation within the parens.
        //
        //    Each capture group gets three slots in the save stack frame:
        //         0: Capture Group start position (in input string being matched.)
        //         1: Capture Group end position.
        //         2: Start of Match-in-progress.
        //    The first two locations are for a completed capture group, and are
        //     referred to by back references and the like.
        //    The third location stores the capture start position when an START_CAPTURE is
        //      encountered.  This will be promoted to a completed capture when (and if) the corresponding
        //      END_CAPTURE is encountered.
        {
            fixLiterals();
            appendOp(URX_NOP, 0);
            int32_t  varsLoc = allocateStackData(3);    // Reserve three slots in match stack frame.
            appendOp(URX_START_CAPTURE, varsLoc);
            appendOp(URX_NOP, 0);

            // On the Parentheses stack, start a new frame and add the postions
            //   of the two NOPs.  Depending on what follows in the pattern, the
            //   NOPs may be changed to SAVE_STATE or JMP ops, with a target
            //   address of the end of the parenthesized group.
            fParenStack.push(fModeFlags, *fStatus);                       // Match mode state
            fParenStack.push(capturing, *fStatus);                        // Frame type.
            fParenStack.push(fRXPat->fCompiledPat->size()-3, *fStatus);   // The first  NOP location
            fParenStack.push(fRXPat->fCompiledPat->size()-1, *fStatus);   // The second NOP loc

            // Save the mapping from group number to stack frame variable position.
            fRXPat->fGroupMap->addElement(varsLoc, *fStatus);

            // If this is a named capture group, add the name->group number mapping.
            if (fCaptureName != NULL) {
                if (!fRXPat->initNamedCaptureMap()) {
                    if (U_SUCCESS(*fStatus)) {
                        error(fRXPat->fDeferredStatus);
                    }
                    break;
                }
                int32_t groupNumber = fRXPat->fGroupMap->size();
                int32_t previousMapping = uhash_puti(fRXPat->fNamedCaptureMap, fCaptureName, groupNumber, fStatus);
                fCaptureName = NULL;    // hash table takes ownership of the name (key) string.
                if (previousMapping > 0 && U_SUCCESS(*fStatus)) {
                    error(U_REGEX_INVALID_CAPTURE_GROUP_NAME);
                }
            }
        }
        break;

    case doOpenNonCaptureParen:
        // Open non-caputuring (grouping only) Paren.
        //   Compile to a
        //      - NOP, which later may be replaced by a save-state if the
        //         parenthesized group gets a * quantifier, followed by
        //      - NOP, which may later be replaced by a save-state if there
        //             is an '|' alternation within the parens.
        {
            fixLiterals();
            appendOp(URX_NOP, 0);
            appendOp(URX_NOP, 0);

            // On the Parentheses stack, start a new frame and add the postions
            //   of the two NOPs.
            fParenStack.push(fModeFlags, *fStatus);                       // Match mode state
            fParenStack.push(plain,      *fStatus);                       // Begin a new frame.
            fParenStack.push(fRXPat->fCompiledPat->size()-2, *fStatus);   // The first  NOP location
            fParenStack.push(fRXPat->fCompiledPat->size()-1, *fStatus);   // The second NOP loc
        }
         break;


    case doOpenAtomicParen:
        // Open Atomic Paren.  (?>
        //   Compile to a
        //      - NOP, which later may be replaced if the parenthesized group
        //         has a quantifier, followed by
        //      - STO_SP  save state stack position, so it can be restored at the ")"
        //      - NOP, which may later be replaced by a save-state if there
        //             is an '|' alternation within the parens.
        {
            fixLiterals();
            appendOp(URX_NOP, 0);
            int32_t  varLoc = allocateData(1);    // Reserve a data location for saving the state stack ptr.
            appendOp(URX_STO_SP, varLoc);
            appendOp(URX_NOP, 0);

            // On the Parentheses stack, start a new frame and add the postions
            //   of the two NOPs.  Depending on what follows in the pattern, the
            //   NOPs may be changed to SAVE_STATE or JMP ops, with a target
            //   address of the end of the parenthesized group.
            fParenStack.push(fModeFlags, *fStatus);                       // Match mode state
            fParenStack.push(atomic, *fStatus);                           // Frame type.
            fParenStack.push(fRXPat->fCompiledPat->size()-3, *fStatus);   // The first NOP
            fParenStack.push(fRXPat->fCompiledPat->size()-1, *fStatus);   // The second NOP
        }
        break;


    case doOpenLookAhead:
        // Positive Look-ahead   (?=  stuff  )
        //
        //   Note:   Addition of transparent input regions, with the need to
        //           restore the original regions when failing out of a lookahead
        //           block, complicated this sequence.  Some combined opcodes
        //           might make sense - or might not, lookahead aren't that common.
        //
        //      Caution:  min match length optimization knows about this
        //               sequence; don't change without making updates there too.
        //
        // Compiles to
        //    1    LA_START     dataLoc     Saves SP, Input Pos, Active input region.
        //    2.   STATE_SAVE   4            on failure of lookahead, goto 4
        //    3    JMP          6           continue ...
        //
        //    4.   LA_END                   Look Ahead failed.  Restore regions.
        //    5.   BACKTRACK                and back track again.
        //
        //    6.   NOP              reserved for use by quantifiers on the block.
        //                          Look-ahead can't have quantifiers, but paren stack
        //                             compile time conventions require the slot anyhow.
        //    7.   NOP              may be replaced if there is are '|' ops in the block.
        //    8.     code for parenthesized stuff.
        //    9.   LA_END
        //
        //  Four data slots are reserved, for saving state on entry to the look-around
        //    0:   stack pointer on entry.
        //    1:   input position on entry.
        //    2:   fActiveStart, the active bounds start on entry.
        //    3:   fActiveLimit, the active bounds limit on entry.
        {
            fixLiterals();
            int32_t dataLoc = allocateData(4);
            appendOp(URX_LA_START, dataLoc);
            appendOp(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+ 2);
            appendOp(URX_JMP, fRXPat->fCompiledPat->size()+ 3);
            appendOp(URX_LA_END, dataLoc);
            appendOp(URX_BACKTRACK, 0);
            appendOp(URX_NOP, 0);
            appendOp(URX_NOP, 0);

            // On the Parentheses stack, start a new frame and add the postions
            //   of the NOPs.
            fParenStack.push(fModeFlags, *fStatus);                       // Match mode state
            fParenStack.push(lookAhead, *fStatus);                        // Frame type.
            fParenStack.push(fRXPat->fCompiledPat->size()-2, *fStatus);   // The first  NOP location
            fParenStack.push(fRXPat->fCompiledPat->size()-1, *fStatus);   // The second NOP location
        }
        break;

    case doOpenLookAheadNeg:
        // Negated Lookahead.   (?! stuff )
        // Compiles to
        //    1.    LA_START    dataloc
        //    2.    SAVE_STATE  7         // Fail within look-ahead block restores to this state,
        //                                //   which continues with the match.
        //    3.    NOP                   // Std. Open Paren sequence, for possible '|'
        //    4.       code for parenthesized stuff.
        //    5.    LA_END                // Cut back stack, remove saved state from step 2.
        //    6.    BACKTRACK             // code in block succeeded, so neg. lookahead fails.
        //    7.    END_LA                // Restore match region, in case look-ahead was using
        //                                        an alternate (transparent) region.
        //  Four data slots are reserved, for saving state on entry to the look-around
        //    0:   stack pointer on entry.
        //    1:   input position on entry.
        //    2:   fActiveStart, the active bounds start on entry.
        //    3:   fActiveLimit, the active bounds limit on entry.
        {
            fixLiterals();
            int32_t dataLoc = allocateData(4);
            appendOp(URX_LA_START, dataLoc);
            appendOp(URX_STATE_SAVE, 0);    // dest address will be patched later.
            appendOp(URX_NOP, 0);

            // On the Parentheses stack, start a new frame and add the postions
            //   of the StateSave and NOP.
            fParenStack.push(fModeFlags, *fStatus);                       // Match mode state
            fParenStack.push(negLookAhead, *fStatus);                    // Frame type
            fParenStack.push(fRXPat->fCompiledPat->size()-2, *fStatus);   // The STATE_SAVE location
            fParenStack.push(fRXPat->fCompiledPat->size()-1, *fStatus);   // The second NOP location

            // Instructions #5 - #7 will be added when the ')' is encountered.
        }
        break;

    case doOpenLookBehind:
        {
            //   Compile a (?<= look-behind open paren.
            //
            //          Compiles to
            //              0       URX_LB_START     dataLoc
            //              1       URX_LB_CONT      dataLoc
            //              2                        MinMatchLen
            //              3                        MaxMatchLen
            //              4       URX_NOP          Standard '(' boilerplate.
            //              5       URX_NOP          Reserved slot for use with '|' ops within (block).
            //              6         <code for LookBehind expression>
            //              7       URX_LB_END       dataLoc    # Check match len, restore input  len
            //              8       URX_LA_END       dataLoc    # Restore stack, input pos
            //
            //          Allocate a block of matcher data, to contain (when running a match)
            //              0:    Stack ptr on entry
            //              1:    Input Index on entry
            //              2:    fActiveStart, the active bounds start on entry.
            //              3:    fActiveLimit, the active bounds limit on entry.
            //              4:    Start index of match current match attempt.
            //          The first four items must match the layout of data for LA_START / LA_END

            // Generate match code for any pending literals.
            fixLiterals();

            // Allocate data space
            int32_t dataLoc = allocateData(5);

            // Emit URX_LB_START
            appendOp(URX_LB_START, dataLoc);

            // Emit URX_LB_CONT
            appendOp(URX_LB_CONT, dataLoc);
            appendOp(URX_RESERVED_OP, 0);    // MinMatchLength.  To be filled later.
            appendOp(URX_RESERVED_OP, 0);    // MaxMatchLength.  To be filled later.

            // Emit the NOPs
            appendOp(URX_NOP, 0);
            appendOp(URX_NOP, 0);

            // On the Parentheses stack, start a new frame and add the postions
            //   of the URX_LB_CONT and the NOP.
            fParenStack.push(fModeFlags, *fStatus);                       // Match mode state
            fParenStack.push(lookBehind, *fStatus);                       // Frame type
            fParenStack.push(fRXPat->fCompiledPat->size()-2, *fStatus);   // The first NOP location
            fParenStack.push(fRXPat->fCompiledPat->size()-1, *fStatus);   // The 2nd   NOP location

            // The final two instructions will be added when the ')' is encountered.
        }

        break;

    case doOpenLookBehindNeg:
        {
            //   Compile a (?<! negated look-behind open paren.
            //
            //          Compiles to
            //              0       URX_LB_START     dataLoc    # Save entry stack, input len
            //              1       URX_LBN_CONT     dataLoc    # Iterate possible match positions
            //              2                        MinMatchLen
            //              3                        MaxMatchLen
            //              4                        continueLoc (9)
            //              5       URX_NOP          Standard '(' boilerplate.
            //              6       URX_NOP          Reserved slot for use with '|' ops within (block).
            //              7         <code for LookBehind expression>
            //              8       URX_LBN_END      dataLoc    # Check match len, cause a FAIL
            //              9       ...
            //
            //          Allocate a block of matcher data, to contain (when running a match)
            //              0:    Stack ptr on entry
            //              1:    Input Index on entry
            //              2:    fActiveStart, the active bounds start on entry.
            //              3:    fActiveLimit, the active bounds limit on entry.
            //              4:    Start index of match current match attempt.
            //          The first four items must match the layout of data for LA_START / LA_END

            // Generate match code for any pending literals.
            fixLiterals();

            // Allocate data space
            int32_t dataLoc = allocateData(5);

            // Emit URX_LB_START
            appendOp(URX_LB_START, dataLoc);

            // Emit URX_LBN_CONT
            appendOp(URX_LBN_CONT, dataLoc);
            appendOp(URX_RESERVED_OP, 0);    // MinMatchLength.  To be filled later.
            appendOp(URX_RESERVED_OP, 0);    // MaxMatchLength.  To be filled later.
            appendOp(URX_RESERVED_OP, 0);    // Continue Loc.    To be filled later.

            // Emit the NOPs
            appendOp(URX_NOP, 0);
            appendOp(URX_NOP, 0);

            // On the Parentheses stack, start a new frame and add the postions
            //   of the URX_LB_CONT and the NOP.
            fParenStack.push(fModeFlags, *fStatus);                       // Match mode state
            fParenStack.push(lookBehindN, *fStatus);                      // Frame type
            fParenStack.push(fRXPat->fCompiledPat->size()-2, *fStatus);   // The first NOP location
            fParenStack.push(fRXPat->fCompiledPat->size()-1, *fStatus);   // The 2nd   NOP location

            // The final two instructions will be added when the ')' is encountered.
        }
        break;

    case doConditionalExpr:
        // Conditionals such as (?(1)a:b)
    case doPerlInline:
        // Perl inline-condtionals.  (?{perl code}a|b) We're not perl, no way to do them.
        error(U_REGEX_UNIMPLEMENTED);
        break;


    case doCloseParen:
        handleCloseParen();
        if (fParenStack.size() <= 0) {
            //  Extra close paren, or missing open paren.
            error(U_REGEX_MISMATCHED_PAREN);
        }
        break;

    case doNOP:
        break;


    case doBadOpenParenType:
    case doRuleError:
        error(U_REGEX_RULE_SYNTAX);
        break;


    case doMismatchedParenErr:
        error(U_REGEX_MISMATCHED_PAREN);
        break;

    case doPlus:
        //  Normal '+'  compiles to
        //     1.   stuff to be repeated  (already built)
        //     2.   jmp-sav 1
        //     3.   ...
        //
        //  Or, if the item to be repeated can match a zero length string,
        //     1.   STO_INP_LOC  data-loc
        //     2.      body of stuff to be repeated
        //     3.   JMP_SAV_X    2
        //     4.   ...

        //
        //  Or, if the item to be repeated is simple
        //     1.   Item to be repeated.
        //     2.   LOOP_SR_I    set number  (assuming repeated item is a set ref)
        //     3.   LOOP_C       stack location
        {
            int32_t  topLoc = blockTopLoc(FALSE);        // location of item #1
            int32_t  frameLoc;

            // Check for simple constructs, which may get special optimized code.
            if (topLoc == fRXPat->fCompiledPat->size() - 1) {
                int32_t repeatedOp = (int32_t)fRXPat->fCompiledPat->elementAti(topLoc);

                if (URX_TYPE(repeatedOp) == URX_SETREF) {
                    // Emit optimized code for [char set]+
                    appendOp(URX_LOOP_SR_I, URX_VAL(repeatedOp));
                    frameLoc = allocateStackData(1);
                    appendOp(URX_LOOP_C, frameLoc);
                    break;
                }

                if (URX_TYPE(repeatedOp) == URX_DOTANY ||
                    URX_TYPE(repeatedOp) == URX_DOTANY_ALL ||
                    URX_TYPE(repeatedOp) == URX_DOTANY_UNIX) {
                    // Emit Optimized code for .+ operations.
                    int32_t loopOpI = buildOp(URX_LOOP_DOT_I, 0);
                    if (URX_TYPE(repeatedOp) == URX_DOTANY_ALL) {
                        // URX_LOOP_DOT_I operand is a flag indicating ". matches any" mode.
                        loopOpI |= 1;
                    }
                    if (fModeFlags & UREGEX_UNIX_LINES) {
                        loopOpI |= 2;
                    }
                    appendOp(loopOpI);
                    frameLoc = allocateStackData(1);
                    appendOp(URX_LOOP_C, frameLoc);
                    break;
                }

            }

            // General case.

            // Check for minimum match length of zero, which requires
            //    extra loop-breaking code.
            if (minMatchLength(topLoc, fRXPat->fCompiledPat->size()-1) == 0) {
                // Zero length match is possible.
                // Emit the code sequence that can handle it.
                insertOp(topLoc);
                frameLoc = allocateStackData(1);

                int32_t op = buildOp(URX_STO_INP_LOC, frameLoc);
                fRXPat->fCompiledPat->setElementAt(op, topLoc);

                appendOp(URX_JMP_SAV_X, topLoc+1);
            } else {
                // Simpler code when the repeated body must match something non-empty
                appendOp(URX_JMP_SAV, topLoc);
            }
        }
        break;

    case doNGPlus:
        //  Non-greedy '+?'  compiles to
        //     1.   stuff to be repeated  (already built)
        //     2.   state-save  1
        //     3.   ...
        {
            int32_t topLoc      = blockTopLoc(FALSE);
            appendOp(URX_STATE_SAVE, topLoc);
        }
        break;


    case doOpt:
        // Normal (greedy) ? quantifier.
        //  Compiles to
        //     1. state save 3
        //     2.    body of optional block
        //     3. ...
        // Insert the state save into the compiled pattern, and we're done.
        {
            int32_t   saveStateLoc = blockTopLoc(TRUE);
            int32_t   saveStateOp  = buildOp(URX_STATE_SAVE, fRXPat->fCompiledPat->size());
            fRXPat->fCompiledPat->setElementAt(saveStateOp, saveStateLoc);
        }
        break;

    case doNGOpt:
        // Non-greedy ?? quantifier
        //   compiles to
        //    1.  jmp   4
        //    2.     body of optional block
        //    3   jmp   5
        //    4.  state save 2
        //    5    ...
        //  This code is less than ideal, with two jmps instead of one, because we can only
        //  insert one instruction at the top of the block being iterated.
        {
            int32_t  jmp1_loc = blockTopLoc(TRUE);
            int32_t  jmp2_loc = fRXPat->fCompiledPat->size();

            int32_t  jmp1_op  = buildOp(URX_JMP, jmp2_loc+1);
            fRXPat->fCompiledPat->setElementAt(jmp1_op, jmp1_loc);

            appendOp(URX_JMP, jmp2_loc+2);

            appendOp(URX_STATE_SAVE, jmp1_loc+1);
        }
        break;


    case doStar:
        // Normal (greedy) * quantifier.
        // Compiles to
        //       1.   STATE_SAVE   4
        //       2.      body of stuff being iterated over
        //       3.   JMP_SAV      2
        //       4.   ...
        //
        // Or, if the body is a simple [Set],
        //       1.   LOOP_SR_I    set number
        //       2.   LOOP_C       stack location
        //       ...
        //
        // Or if this is a .*
        //       1.   LOOP_DOT_I    (. matches all mode flag)
        //       2.   LOOP_C        stack location
        //
        // Or, if the body can match a zero-length string, to inhibit infinite loops,
        //       1.   STATE_SAVE   5
        //       2.   STO_INP_LOC  data-loc
        //       3.      body of stuff
        //       4.   JMP_SAV_X    2
        //       5.   ...
        {
            // location of item #1, the STATE_SAVE
            int32_t   topLoc = blockTopLoc(FALSE);
            int32_t   dataLoc = -1;

            // Check for simple *, where the construct being repeated
            //   compiled to single opcode, and might be optimizable.
            if (topLoc == fRXPat->fCompiledPat->size() - 1) {
                int32_t repeatedOp = (int32_t)fRXPat->fCompiledPat->elementAti(topLoc);

                if (URX_TYPE(repeatedOp) == URX_SETREF) {
                    // Emit optimized code for a [char set]*
                    int32_t loopOpI = buildOp(URX_LOOP_SR_I, URX_VAL(repeatedOp));
                    fRXPat->fCompiledPat->setElementAt(loopOpI, topLoc);
                    dataLoc = allocateStackData(1);
                    appendOp(URX_LOOP_C, dataLoc);
                    break;
                }

                if (URX_TYPE(repeatedOp) == URX_DOTANY ||
                    URX_TYPE(repeatedOp) == URX_DOTANY_ALL ||
                    URX_TYPE(repeatedOp) == URX_DOTANY_UNIX) {
                    // Emit Optimized code for .* operations.
                    int32_t loopOpI = buildOp(URX_LOOP_DOT_I, 0);
                    if (URX_TYPE(repeatedOp) == URX_DOTANY_ALL) {
                        // URX_LOOP_DOT_I operand is a flag indicating . matches any mode.
                        loopOpI |= 1;
                    }
                    if ((fModeFlags & UREGEX_UNIX_LINES) != 0) {
                        loopOpI |= 2;
                    }
                    fRXPat->fCompiledPat->setElementAt(loopOpI, topLoc);
                    dataLoc = allocateStackData(1);
                    appendOp(URX_LOOP_C, dataLoc);
                    break;
                }
            }

            // Emit general case code for this *
            // The optimizations did not apply.

            int32_t   saveStateLoc = blockTopLoc(TRUE);
            int32_t   jmpOp        = buildOp(URX_JMP_SAV, saveStateLoc+1);

            // Check for minimum match length of zero, which requires
            //    extra loop-breaking code.
            if (minMatchLength(saveStateLoc, fRXPat->fCompiledPat->size()-1) == 0) {
                insertOp(saveStateLoc);
                dataLoc = allocateStackData(1);

                int32_t op = buildOp(URX_STO_INP_LOC, dataLoc);
                fRXPat->fCompiledPat->setElementAt(op, saveStateLoc+1);
                jmpOp      = buildOp(URX_JMP_SAV_X, saveStateLoc+2);
            }

            // Locate the position in the compiled pattern where the match will continue
            //   after completing the *.   (4 or 5 in the comment above)
            int32_t continueLoc = fRXPat->fCompiledPat->size()+1;

            // Put together the save state op and store it into the compiled code.
            int32_t saveStateOp = buildOp(URX_STATE_SAVE, continueLoc);
            fRXPat->fCompiledPat->setElementAt(saveStateOp, saveStateLoc);

            // Append the URX_JMP_SAV or URX_JMPX operation to the compiled pattern.
            appendOp(jmpOp);
        }
        break;

    case doNGStar:
        // Non-greedy *? quantifier
        // compiles to
        //     1.   JMP    3
        //     2.      body of stuff being iterated over
        //     3.   STATE_SAVE  2
        //     4    ...
        {
            int32_t     jmpLoc  = blockTopLoc(TRUE);                   // loc  1.
            int32_t     saveLoc = fRXPat->fCompiledPat->size();        // loc  3.
            int32_t     jmpOp   = buildOp(URX_JMP, saveLoc);
            fRXPat->fCompiledPat->setElementAt(jmpOp, jmpLoc);
            appendOp(URX_STATE_SAVE, jmpLoc+1);
        }
        break;


    case doIntervalInit:
        // The '{' opening an interval quantifier was just scanned.
        // Init the counter varaiables that will accumulate the values as the digits
        //    are scanned.
        fIntervalLow = 0;
        fIntervalUpper = -1;
        break;

    case doIntevalLowerDigit:
        // Scanned a digit from the lower value of an {lower,upper} interval
        {
            int32_t digitValue = u_charDigitValue(fC.fChar);
            U_ASSERT(digitValue >= 0);
            int64_t val = (int64_t)fIntervalLow*10 + digitValue;
            if (val > INT32_MAX) {
                error(U_REGEX_NUMBER_TOO_BIG);
            } else {
                fIntervalLow = (int32_t)val;
            }
        }
        break;

    case doIntervalUpperDigit:
        // Scanned a digit from the upper value of an {lower,upper} interval
        {
            if (fIntervalUpper < 0) {
                fIntervalUpper = 0;
            }
            int32_t digitValue = u_charDigitValue(fC.fChar);
            U_ASSERT(digitValue >= 0);
            int64_t val = (int64_t)fIntervalUpper*10 + digitValue;
            if (val > INT32_MAX) {
                error(U_REGEX_NUMBER_TOO_BIG);
            } else {
                fIntervalUpper = (int32_t)val;
            }
        }
        break;

    case doIntervalSame:
        // Scanned a single value interval like {27}.  Upper = Lower.
        fIntervalUpper = fIntervalLow;
        break;

    case doInterval:
        // Finished scanning a normal {lower,upper} interval.  Generate the code for it.
        if (compileInlineInterval() == FALSE) {
            compileInterval(URX_CTR_INIT, URX_CTR_LOOP);
        }
        break;

    case doPossessiveInterval:
        // Finished scanning a Possessive {lower,upper}+ interval.  Generate the code for it.
        {
            // Remember the loc for the top of the block being looped over.
            //   (Can not reserve a slot in the compiled pattern at this time, because
            //    compileInterval needs to reserve also, and blockTopLoc can only reserve
            //    once per block.)
            int32_t topLoc = blockTopLoc(FALSE);

            // Produce normal looping code.
            compileInterval(URX_CTR_INIT, URX_CTR_LOOP);

            // Surround the just-emitted normal looping code with a STO_SP ... LD_SP
            //  just as if the loop was inclosed in atomic parentheses.

            // First the STO_SP before the start of the loop
            insertOp(topLoc);

            int32_t  varLoc = allocateData(1);   // Reserve a data location for saving the
            int32_t  op     = buildOp(URX_STO_SP, varLoc);
            fRXPat->fCompiledPat->setElementAt(op, topLoc);

            int32_t loopOp = (int32_t)fRXPat->fCompiledPat->popi();
            U_ASSERT(URX_TYPE(loopOp) == URX_CTR_LOOP && URX_VAL(loopOp) == topLoc);
            loopOp++;     // point LoopOp after the just-inserted STO_SP
            fRXPat->fCompiledPat->push(loopOp, *fStatus);

            // Then the LD_SP after the end of the loop
            appendOp(URX_LD_SP, varLoc);
        }

        break;

    case doNGInterval:
        // Finished scanning a non-greedy {lower,upper}? interval.  Generate the code for it.
        compileInterval(URX_CTR_INIT_NG, URX_CTR_LOOP_NG);
        break;

    case doIntervalError:
        error(U_REGEX_BAD_INTERVAL);
        break;

    case doLiteralChar:
        // We've just scanned a "normal" character from the pattern,
        literalChar(fC.fChar);
        break;


    case doEscapedLiteralChar:
        // We've just scanned an backslashed escaped character with  no
        //   special meaning.  It represents itself.
        if ((fModeFlags & UREGEX_ERROR_ON_UNKNOWN_ESCAPES) != 0 &&
            ((fC.fChar >= 0x41 && fC.fChar<= 0x5A) ||     // in [A-Z]
            (fC.fChar >= 0x61 && fC.fChar <= 0x7a))) {   // in [a-z]
               error(U_REGEX_BAD_ESCAPE_SEQUENCE);
             }
        literalChar(fC.fChar);
        break;


    case doDotAny:
        // scanned a ".",  match any single character.
        {
            fixLiterals(FALSE);
            if (fModeFlags & UREGEX_DOTALL) {
                appendOp(URX_DOTANY_ALL, 0);
            } else if (fModeFlags & UREGEX_UNIX_LINES) {
                appendOp(URX_DOTANY_UNIX, 0);
            } else {
                appendOp(URX_DOTANY, 0);
            }
        }
        break;

    case doCaret:
        {
            fixLiterals(FALSE);
            if (       (fModeFlags & UREGEX_MULTILINE) == 0 && (fModeFlags & UREGEX_UNIX_LINES) == 0) {
                appendOp(URX_CARET, 0);
            } else if ((fModeFlags & UREGEX_MULTILINE) != 0 && (fModeFlags & UREGEX_UNIX_LINES) == 0) {
                appendOp(URX_CARET_M, 0);
            } else if ((fModeFlags & UREGEX_MULTILINE) == 0 && (fModeFlags & UREGEX_UNIX_LINES) != 0) {
                appendOp(URX_CARET, 0);   // Only testing true start of input.
            } else if ((fModeFlags & UREGEX_MULTILINE) != 0 && (fModeFlags & UREGEX_UNIX_LINES) != 0) {
                appendOp(URX_CARET_M_UNIX, 0);
            }
        }
        break;

    case doDollar:
        {
            fixLiterals(FALSE);
            if (       (fModeFlags & UREGEX_MULTILINE) == 0 && (fModeFlags & UREGEX_UNIX_LINES) == 0) {
                appendOp(URX_DOLLAR, 0);
            } else if ((fModeFlags & UREGEX_MULTILINE) != 0 && (fModeFlags & UREGEX_UNIX_LINES) == 0) {
                appendOp(URX_DOLLAR_M, 0);
            } else if ((fModeFlags & UREGEX_MULTILINE) == 0 && (fModeFlags & UREGEX_UNIX_LINES) != 0) {
                appendOp(URX_DOLLAR_D, 0);
            } else if ((fModeFlags & UREGEX_MULTILINE) != 0 && (fModeFlags & UREGEX_UNIX_LINES) != 0) {
                appendOp(URX_DOLLAR_MD, 0);
            }
        }
        break;

    case doBackslashA:
        fixLiterals(FALSE);
        appendOp(URX_CARET, 0);
        break;

    case doBackslashB:
        {
            #if  UCONFIG_NO_BREAK_ITERATION==1
            if (fModeFlags & UREGEX_UWORD) {
                error(U_UNSUPPORTED_ERROR);
            }
            #endif
            fixLiterals(FALSE);
            int32_t op = (fModeFlags & UREGEX_UWORD)? URX_BACKSLASH_BU : URX_BACKSLASH_B;
            appendOp(op, 1);
        }
        break;

    case doBackslashb:
        {
            #if  UCONFIG_NO_BREAK_ITERATION==1
            if (fModeFlags & UREGEX_UWORD) {
                error(U_UNSUPPORTED_ERROR);
            }
            #endif
            fixLiterals(FALSE);
            int32_t op = (fModeFlags & UREGEX_UWORD)? URX_BACKSLASH_BU : URX_BACKSLASH_B;
            appendOp(op, 0);
        }
        break;

    case doBackslashD:
        fixLiterals(FALSE);
        appendOp(URX_BACKSLASH_D, 1);
        break;

    case doBackslashd:
        fixLiterals(FALSE);
        appendOp(URX_BACKSLASH_D, 0);
        break;

    case doBackslashG:
        fixLiterals(FALSE);
        appendOp(URX_BACKSLASH_G, 0);
        break;

    case doBackslashH:
        fixLiterals(FALSE);
        appendOp(URX_BACKSLASH_H, 1);
        break;

    case doBackslashh:
        fixLiterals(FALSE);
        appendOp(URX_BACKSLASH_H, 0);
        break;

    case doBackslashR:
        fixLiterals(FALSE);
        appendOp(URX_BACKSLASH_R, 0);
        break;

    case doBackslashS:
        fixLiterals(FALSE);
        appendOp(URX_STAT_SETREF_N, URX_ISSPACE_SET);
        break;

    case doBackslashs:
        fixLiterals(FALSE);
        appendOp(URX_STATIC_SETREF, URX_ISSPACE_SET);
        break;

    case doBackslashV:
        fixLiterals(FALSE);
        appendOp(URX_BACKSLASH_V, 1);
        break;

    case doBackslashv:
        fixLiterals(FALSE);
        appendOp(URX_BACKSLASH_V, 0);
        break;

    case doBackslashW:
        fixLiterals(FALSE);
        appendOp(URX_STAT_SETREF_N, URX_ISWORD_SET);
        break;

    case doBackslashw:
        fixLiterals(FALSE);
        appendOp(URX_STATIC_SETREF, URX_ISWORD_SET);
        break;

    case doBackslashX:
        #if  UCONFIG_NO_BREAK_ITERATION==1
        // Grapheme Cluster Boundary requires ICU break iteration.
        error(U_UNSUPPORTED_ERROR);
        #endif
        fixLiterals(FALSE);
        appendOp(URX_BACKSLASH_X, 0);
        break;

    case doBackslashZ:
        fixLiterals(FALSE);
        appendOp(URX_DOLLAR, 0);
        break;

    case doBackslashz:
        fixLiterals(FALSE);
        appendOp(URX_BACKSLASH_Z, 0);
        break;

    case doEscapeError:
        error(U_REGEX_BAD_ESCAPE_SEQUENCE);
        break;

    case doExit:
        fixLiterals(FALSE);
        returnVal = FALSE;
        break;

    case doProperty:
        {
            fixLiterals(FALSE);
            UnicodeSet *theSet = scanProp();
            compileSet(theSet);
        }
        break;

    case doNamedChar:
        {
            UChar32 c = scanNamedChar();
            literalChar(c);
        }
        break;


    case doBackRef:
        // BackReference.  Somewhat unusual in that the front-end can not completely parse
        //                 the regular expression, because the number of digits to be consumed
        //                 depends on the number of capture groups that have been defined.  So
        //                 we have to do it here instead.
        {
            int32_t  numCaptureGroups = fRXPat->fGroupMap->size();
            int32_t  groupNum = 0;
            UChar32  c        = fC.fChar;

            for (;;) {
                // Loop once per digit, for max allowed number of digits in a back reference.
                int32_t digit = u_charDigitValue(c);
                groupNum = groupNum * 10 + digit;
                if (groupNum >= numCaptureGroups) {
                    break;
                }
                c = peekCharLL();
                if (RegexStaticSets::gStaticSets->fRuleDigitsAlias->contains(c) == FALSE) {
                    break;
                }
                nextCharLL();
            }

            // Scan of the back reference in the source regexp is complete.  Now generate
            //  the compiled code for it.
            // Because capture groups can be forward-referenced by back-references,
            //  we fill the operand with the capture group number.  At the end
            //  of compilation, it will be changed to the variable's location.
            U_ASSERT(groupNum > 0);  // Shouldn't happen.  '\0' begins an octal escape sequence,
                                     //    and shouldn't enter this code path at all.
            fixLiterals(FALSE);
            if (fModeFlags & UREGEX_CASE_INSENSITIVE) {
                appendOp(URX_BACKREF_I, groupNum);
            } else {
                appendOp(URX_BACKREF, groupNum);
            }
        }
        break;

    case doBeginNamedBackRef:
        U_ASSERT(fCaptureName == NULL);
        fCaptureName = new UnicodeString;
        if (fCaptureName == NULL) {
            error(U_MEMORY_ALLOCATION_ERROR);
        }
        break;
            
    case doContinueNamedBackRef:
        fCaptureName->append(fC.fChar);
        break;

    case doCompleteNamedBackRef:
        {
        int32_t groupNumber =
            fRXPat->fNamedCaptureMap ? uhash_geti(fRXPat->fNamedCaptureMap, fCaptureName) : 0;
        if (groupNumber == 0) {
            // Group name has not been defined.
            //   Could be a forward reference. If we choose to support them at some
            //   future time, extra mechanism will be required at this point.
            error(U_REGEX_INVALID_CAPTURE_GROUP_NAME);
        } else {
            // Given the number, handle identically to a \n numbered back reference.
            // See comments above, under doBackRef
            fixLiterals(FALSE);
            if (fModeFlags & UREGEX_CASE_INSENSITIVE) {
                appendOp(URX_BACKREF_I, groupNumber);
            } else {
                appendOp(URX_BACKREF, groupNumber);
            }
        }
        delete fCaptureName;
        fCaptureName = NULL;
        break;
        }
       
    case doPossessivePlus:
        // Possessive ++ quantifier.
        // Compiles to
        //       1.   STO_SP
        //       2.      body of stuff being iterated over
        //       3.   STATE_SAVE 5
        //       4.   JMP        2
        //       5.   LD_SP
        //       6.   ...
        //
        //  Note:  TODO:  This is pretty inefficient.  A mass of saved state is built up
        //                then unconditionally discarded.  Perhaps introduce a new opcode.  Ticket 6056
        //
        {
            // Emit the STO_SP
            int32_t   topLoc = blockTopLoc(TRUE);
            int32_t   stoLoc = allocateData(1);  // Reserve the data location for storing save stack ptr.
            int32_t   op     = buildOp(URX_STO_SP, stoLoc);
            fRXPat->fCompiledPat->setElementAt(op, topLoc);

            // Emit the STATE_SAVE
            appendOp(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+2);

            // Emit the JMP
            appendOp(URX_JMP, topLoc+1);

            // Emit the LD_SP
            appendOp(URX_LD_SP, stoLoc);
        }
        break;

    case doPossessiveStar:
        // Possessive *+ quantifier.
        // Compiles to
        //       1.   STO_SP       loc
        //       2.   STATE_SAVE   5
        //       3.      body of stuff being iterated over
        //       4.   JMP          2
        //       5.   LD_SP        loc
        //       6    ...
        // TODO:  do something to cut back the state stack each time through the loop.
        {
            // Reserve two slots at the top of the block.
            int32_t   topLoc = blockTopLoc(TRUE);
            insertOp(topLoc);

            // emit   STO_SP     loc
            int32_t   stoLoc = allocateData(1);    // Reserve the data location for storing save stack ptr.
            int32_t   op     = buildOp(URX_STO_SP, stoLoc);
            fRXPat->fCompiledPat->setElementAt(op, topLoc);

            // Emit the SAVE_STATE   5
            int32_t L7 = fRXPat->fCompiledPat->size()+1;
            op = buildOp(URX_STATE_SAVE, L7);
            fRXPat->fCompiledPat->setElementAt(op, topLoc+1);

            // Append the JMP operation.
            appendOp(URX_JMP, topLoc+1);

            // Emit the LD_SP       loc
            appendOp(URX_LD_SP, stoLoc);
        }
        break;

    case doPossessiveOpt:
        // Possessive  ?+ quantifier.
        //  Compiles to
        //     1. STO_SP      loc
        //     2. SAVE_STATE  5
        //     3.    body of optional block
        //     4. LD_SP       loc
        //     5. ...
        //
        {
            // Reserve two slots at the top of the block.
            int32_t   topLoc = blockTopLoc(TRUE);
            insertOp(topLoc);

            // Emit the STO_SP
            int32_t   stoLoc = allocateData(1);   // Reserve the data location for storing save stack ptr.
            int32_t   op     = buildOp(URX_STO_SP, stoLoc);
            fRXPat->fCompiledPat->setElementAt(op, topLoc);

            // Emit the SAVE_STATE
            int32_t   continueLoc = fRXPat->fCompiledPat->size()+1;
            op = buildOp(URX_STATE_SAVE, continueLoc);
            fRXPat->fCompiledPat->setElementAt(op, topLoc+1);

            // Emit the LD_SP
            appendOp(URX_LD_SP, stoLoc);
        }
        break;


    case doBeginMatchMode:
        fNewModeFlags = fModeFlags;
        fSetModeFlag  = TRUE;
        break;

    case doMatchMode:   //  (?i)    and similar
        {
            int32_t  bit = 0;
            switch (fC.fChar) {
            case 0x69: /* 'i' */   bit = UREGEX_CASE_INSENSITIVE; break;
            case 0x64: /* 'd' */   bit = UREGEX_UNIX_LINES;       break;
            case 0x6d: /* 'm' */   bit = UREGEX_MULTILINE;        break;
            case 0x73: /* 's' */   bit = UREGEX_DOTALL;           break;
            case 0x75: /* 'u' */   bit = 0; /* Unicode casing */  break;
            case 0x77: /* 'w' */   bit = UREGEX_UWORD;            break;
            case 0x78: /* 'x' */   bit = UREGEX_COMMENTS;         break;
            case 0x2d: /* '-' */   fSetModeFlag = FALSE;          break;
            default:
                UPRV_UNREACHABLE;   // Should never happen.  Other chars are filtered out
                                   // by the scanner.
            }
            if (fSetModeFlag) {
                fNewModeFlags |= bit;
            } else {
                fNewModeFlags &= ~bit;
            }
        }
        break;

    case doSetMatchMode:
        // Emit code to match any pending literals, using the not-yet changed match mode.
        fixLiterals();

        // We've got a (?i) or similar.  The match mode is being changed, but
        //   the change is not scoped to a parenthesized block.
        U_ASSERT(fNewModeFlags < 0);
        fModeFlags = fNewModeFlags;

        break;


    case doMatchModeParen:
        // We've got a (?i: or similar.  Begin a parenthesized block, save old
        //   mode flags so they can be restored at the close of the block.
        //
        //   Compile to a
        //      - NOP, which later may be replaced by a save-state if the
        //         parenthesized group gets a * quantifier, followed by
        //      - NOP, which may later be replaced by a save-state if there
        //             is an '|' alternation within the parens.
        {
            fixLiterals(FALSE);
            appendOp(URX_NOP, 0);
            appendOp(URX_NOP, 0);

            // On the Parentheses stack, start a new frame and add the postions
            //   of the two NOPs (a normal non-capturing () frame, except for the
            //   saving of the orignal mode flags.)
            fParenStack.push(fModeFlags, *fStatus);
            fParenStack.push(flags, *fStatus);                            // Frame Marker
            fParenStack.push(fRXPat->fCompiledPat->size()-2, *fStatus);   // The first NOP
            fParenStack.push(fRXPat->fCompiledPat->size()-1, *fStatus);   // The second NOP

            // Set the current mode flags to the new values.
            U_ASSERT(fNewModeFlags < 0);
            fModeFlags = fNewModeFlags;
        }
        break;

    case doBadModeFlag:
        error(U_REGEX_INVALID_FLAG);
        break;

    case doSuppressComments:
        // We have just scanned a '(?'.  We now need to prevent the character scanner from
        // treating a '#' as a to-the-end-of-line comment.
        //   (This Perl compatibility just gets uglier and uglier to do...)
        fEOLComments = FALSE;
        break;


    case doSetAddAmp:
        {
          UnicodeSet *set = (UnicodeSet *)fSetStack.peek();
          set->add(chAmp);
        }
        break;

    case doSetAddDash:
        {
          UnicodeSet *set = (UnicodeSet *)fSetStack.peek();
          set->add(chDash);
        }
        break;

     case doSetBackslash_s:
        {
         UnicodeSet *set = (UnicodeSet *)fSetStack.peek();
         set->addAll(RegexStaticSets::gStaticSets->fPropSets[URX_ISSPACE_SET]);
         break;
        }

     case doSetBackslash_S:
        {
            UnicodeSet *set = (UnicodeSet *)fSetStack.peek();
            UnicodeSet SSet;
            SSet.addAll(RegexStaticSets::gStaticSets->fPropSets[URX_ISSPACE_SET]).complement();
            set->addAll(SSet);
            break;
        }

    case doSetBackslash_d:
        {
            UnicodeSet *set = (UnicodeSet *)fSetStack.peek();
            // TODO - make a static set, ticket 6058.
            addCategory(set, U_GC_ND_MASK, *fStatus);
            break;
        }

    case doSetBackslash_D:
        {
            UnicodeSet *set = (UnicodeSet *)fSetStack.peek();
            UnicodeSet digits;
            // TODO - make a static set, ticket 6058.
            digits.applyIntPropertyValue(UCHAR_GENERAL_CATEGORY_MASK, U_GC_ND_MASK, *fStatus);
            digits.complement();
            set->addAll(digits);
            break;
        }

    case doSetBackslash_h:
        {
            UnicodeSet *set = (UnicodeSet *)fSetStack.peek();
            UnicodeSet h;
            h.applyIntPropertyValue(UCHAR_GENERAL_CATEGORY_MASK, U_GC_ZS_MASK, *fStatus);
            h.add((UChar32)9);   // Tab
            set->addAll(h);
            break;
        }

    case doSetBackslash_H:
        {
            UnicodeSet *set = (UnicodeSet *)fSetStack.peek();
            UnicodeSet h;
            h.applyIntPropertyValue(UCHAR_GENERAL_CATEGORY_MASK, U_GC_ZS_MASK, *fStatus);
            h.add((UChar32)9);   // Tab
            h.complement();
            set->addAll(h);
            break;
        }

    case doSetBackslash_v:
        {
            UnicodeSet *set = (UnicodeSet *)fSetStack.peek();
            set->add((UChar32)0x0a, (UChar32)0x0d);  // add range
            set->add((UChar32)0x85);
            set->add((UChar32)0x2028, (UChar32)0x2029);
            break;
        }

    case doSetBackslash_V:
        {
            UnicodeSet *set = (UnicodeSet *)fSetStack.peek();
            UnicodeSet v;
            v.add((UChar32)0x0a, (UChar32)0x0d);  // add range
            v.add((UChar32)0x85);
            v.add((UChar32)0x2028, (UChar32)0x2029);
            v.complement();
            set->addAll(v);
            break;
        }

    case doSetBackslash_w:
        {
            UnicodeSet *set = (UnicodeSet *)fSetStack.peek();
            set->addAll(RegexStaticSets::gStaticSets->fPropSets[URX_ISWORD_SET]);
            break;
        }

    case doSetBackslash_W:
        {
            UnicodeSet *set = (UnicodeSet *)fSetStack.peek();
            UnicodeSet SSet;
            SSet.addAll(RegexStaticSets::gStaticSets->fPropSets[URX_ISWORD_SET]).complement();
            set->addAll(SSet);
            break;
        }

    case doSetBegin:
        fixLiterals(FALSE);
        fSetStack.push(new UnicodeSet(), *fStatus);
        fSetOpStack.push(setStart, *fStatus);
        if ((fModeFlags & UREGEX_CASE_INSENSITIVE) != 0) {
            fSetOpStack.push(setCaseClose, *fStatus);
        }
        break;

    case doSetBeginDifference1:
        //  We have scanned something like [[abc]-[
        //  Set up a new UnicodeSet for the set beginning with the just-scanned '['
        //  Push a Difference operator, which will cause the new set to be subtracted from what
        //    went before once it is created.
        setPushOp(setDifference1);
        fSetOpStack.push(setStart, *fStatus);
        if ((fModeFlags & UREGEX_CASE_INSENSITIVE) != 0) {
            fSetOpStack.push(setCaseClose, *fStatus);
        }
        break;

    case doSetBeginIntersection1:
        //  We have scanned something like  [[abc]&[
        //   Need both the '&' operator and the open '[' operator.
        setPushOp(setIntersection1);
        fSetOpStack.push(setStart, *fStatus);
        if ((fModeFlags & UREGEX_CASE_INSENSITIVE) != 0) {
            fSetOpStack.push(setCaseClose, *fStatus);
        }
        break;

    case doSetBeginUnion:
        //  We have scanned something like  [[abc][
        //     Need to handle the union operation explicitly [[abc] | [
        setPushOp(setUnion);
        fSetOpStack.push(setStart, *fStatus);
        if ((fModeFlags & UREGEX_CASE_INSENSITIVE) != 0) {
            fSetOpStack.push(setCaseClose, *fStatus);
        }
        break;

    case doSetDifference2:
        // We have scanned something like [abc--
        //   Consider this to unambiguously be a set difference operator.
        setPushOp(setDifference2);
        break;

    case doSetEnd:
        // Have encountered the ']' that closes a set.
        //    Force the evaluation of any pending operations within this set,
        //    leave the completed set on the top of the set stack.
        setEval(setEnd);
        U_ASSERT(fSetOpStack.peeki()==setStart);
        fSetOpStack.popi();
        break;

    case doSetFinish:
        {
        // Finished a complete set expression, including all nested sets.
        //   The close bracket has already triggered clearing out pending set operators,
        //    the operator stack should be empty and the operand stack should have just
        //    one entry, the result set.
        U_ASSERT(fSetOpStack.empty());
        UnicodeSet *theSet = (UnicodeSet *)fSetStack.pop();
        U_ASSERT(fSetStack.empty());
        compileSet(theSet);
        break;
        }

    case doSetIntersection2:
        // Have scanned something like [abc&&
        setPushOp(setIntersection2);
        break;

    case doSetLiteral:
        // Union the just-scanned literal character into the set being built.
        //    This operation is the highest precedence set operation, so we can always do
        //    it immediately, without waiting to see what follows.  It is necessary to perform
        //    any pending '-' or '&' operation first, because these have the same precedence
        //    as union-ing in a literal'
        {
            setEval(setUnion);
            UnicodeSet *s = (UnicodeSet *)fSetStack.peek();
            s->add(fC.fChar);
            fLastSetLiteral = fC.fChar;
            break;
        }

    case doSetLiteralEscaped:
        // A back-slash escaped literal character was encountered.
        // Processing is the same as with setLiteral, above, with the addition of
        //  the optional check for errors on escaped ASCII letters.
        {
            if ((fModeFlags & UREGEX_ERROR_ON_UNKNOWN_ESCAPES) != 0 &&
                ((fC.fChar >= 0x41 && fC.fChar<= 0x5A) ||     // in [A-Z]
                 (fC.fChar >= 0x61 && fC.fChar <= 0x7a))) {   // in [a-z]
                error(U_REGEX_BAD_ESCAPE_SEQUENCE);
            }
            setEval(setUnion);
            UnicodeSet *s = (UnicodeSet *)fSetStack.peek();
            s->add(fC.fChar);
            fLastSetLiteral = fC.fChar;
            break;
        }

        case doSetNamedChar:
        // Scanning a \N{UNICODE CHARACTER NAME}
        //  Aside from the source of the character, the processing is identical to doSetLiteral,
        //    above.
        {
            UChar32  c = scanNamedChar();
            setEval(setUnion);
            UnicodeSet *s = (UnicodeSet *)fSetStack.peek();
            s->add(c);
            fLastSetLiteral = c;
            break;
        }

    case doSetNamedRange:
        // We have scanned literal-\N{CHAR NAME}.  Add the range to the set.
        // The left character is already in the set, and is saved in fLastSetLiteral.
        // The right side needs to be picked up, the scan is at the 'N'.
        // Lower Limit > Upper limit being an error matches both Java
        //        and ICU UnicodeSet behavior.
        {
            UChar32  c = scanNamedChar();
            if (U_SUCCESS(*fStatus) && (fLastSetLiteral == U_SENTINEL || fLastSetLiteral > c)) {
                error(U_REGEX_INVALID_RANGE);
            }
            UnicodeSet *s = (UnicodeSet *)fSetStack.peek();
            s->add(fLastSetLiteral, c);
            fLastSetLiteral = c;
            break;
        }


    case  doSetNegate:
        // Scanned a '^' at the start of a set.
        // Push the negation operator onto the set op stack.
        // A twist for case-insensitive matching:
        //   the case closure operation must happen _before_ negation.
        //   But the case closure operation will already be on the stack if it's required.
        //   This requires checking for case closure, and swapping the stack order
        //    if it is present.
        {
            int32_t  tosOp = fSetOpStack.peeki();
            if (tosOp == setCaseClose) {
                fSetOpStack.popi();
                fSetOpStack.push(setNegation, *fStatus);
                fSetOpStack.push(setCaseClose, *fStatus);
            } else {
                fSetOpStack.push(setNegation, *fStatus);
            }
        }
        break;

    case doSetNoCloseError:
        error(U_REGEX_MISSING_CLOSE_BRACKET);
        break;

    case doSetOpError:
        error(U_REGEX_RULE_SYNTAX);   //  -- or && at the end of a set.  Illegal.
        break;

    case doSetPosixProp:
        {
            UnicodeSet *s = scanPosixProp();
            if (s != NULL) {
                UnicodeSet *tos = (UnicodeSet *)fSetStack.peek();
                tos->addAll(*s);
                delete s;
            }  // else error.  scanProp() reported the error status already.
        }
        break;

    case doSetProp:
        //  Scanned a \p \P within [brackets].
        {
            UnicodeSet *s = scanProp();
            if (s != NULL) {
                UnicodeSet *tos = (UnicodeSet *)fSetStack.peek();
                tos->addAll(*s);
                delete s;
            }  // else error.  scanProp() reported the error status already.
        }
        break;


    case doSetRange:
        // We have scanned literal-literal.  Add the range to the set.
        // The left character is already in the set, and is saved in fLastSetLiteral.
        // The right side is the current character.
        // Lower Limit > Upper limit being an error matches both Java
        //        and ICU UnicodeSet behavior.
        {

        if (fLastSetLiteral == U_SENTINEL || fLastSetLiteral > fC.fChar) {
            error(U_REGEX_INVALID_RANGE);
        }
        UnicodeSet *s = (UnicodeSet *)fSetStack.peek();
        s->add(fLastSetLiteral, fC.fChar);
        break;
        }

    default:
        UPRV_UNREACHABLE;
    }

    if (U_FAILURE(*fStatus)) {
        returnVal = FALSE;
    }

    return returnVal;
}



//------------------------------------------------------------------------------
//
//   literalChar           We've encountered a literal character from the pattern,
//                             or an escape sequence that reduces to a character.
//                         Add it to the string containing all literal chars/strings from
//                             the pattern.
//
//------------------------------------------------------------------------------
void RegexCompile::literalChar(UChar32 c)  {
    fLiteralChars.append(c);
}


//------------------------------------------------------------------------------
//
//    fixLiterals           When compiling something that can follow a literal
//                          string in a pattern, emit the code to match the
//                          accumulated literal string.
//
//                          Optionally, split the last char of the string off into
//                          a single "ONE_CHAR" operation, so that quantifiers can
//                          apply to that char alone.  Example:   abc*
//                          The * must apply to the 'c' only.
//
//------------------------------------------------------------------------------
void    RegexCompile::fixLiterals(UBool split) {

    // If no literal characters have been scanned but not yet had code generated
    //   for them, nothing needs to be done.
    if (fLiteralChars.length() == 0) {
        return;
    }

    int32_t indexOfLastCodePoint = fLiteralChars.moveIndex32(fLiteralChars.length(), -1);
    UChar32 lastCodePoint = fLiteralChars.char32At(indexOfLastCodePoint);

    // Split:  We need to  ensure that the last item in the compiled pattern
    //     refers only to the last literal scanned in the pattern, so that
    //     quantifiers (*, +, etc.) affect only it, and not a longer string.
    //     Split before case folding for case insensitive matches.

    if (split) {
        fLiteralChars.truncate(indexOfLastCodePoint);
        fixLiterals(FALSE);   // Recursive call, emit code to match the first part of the string.
                              //  Note that the truncated literal string may be empty, in which case
                              //  nothing will be emitted.

        literalChar(lastCodePoint);  // Re-add the last code point as if it were a new literal.
        fixLiterals(FALSE);          // Second recursive call, code for the final code point.
        return;
    }

    // If we are doing case-insensitive matching, case fold the string.  This may expand
    //   the string, e.g. the German sharp-s turns into "ss"
    if (fModeFlags & UREGEX_CASE_INSENSITIVE) {
        fLiteralChars.foldCase();
        indexOfLastCodePoint = fLiteralChars.moveIndex32(fLiteralChars.length(), -1);
        lastCodePoint = fLiteralChars.char32At(indexOfLastCodePoint);
    }

    if (indexOfLastCodePoint == 0) {
        // Single character, emit a URX_ONECHAR op to match it.
        if ((fModeFlags & UREGEX_CASE_INSENSITIVE) &&
                 u_hasBinaryProperty(lastCodePoint, UCHAR_CASE_SENSITIVE)) {
            appendOp(URX_ONECHAR_I, lastCodePoint);
        } else {
            appendOp(URX_ONECHAR, lastCodePoint);
        }
    } else {
        // Two or more chars, emit a URX_STRING to match them.
        if (fLiteralChars.length() > 0x00ffffff || fRXPat->fLiteralText.length() > 0x00ffffff) {
            error(U_REGEX_PATTERN_TOO_BIG);
        }
        if (fModeFlags & UREGEX_CASE_INSENSITIVE) {
            appendOp(URX_STRING_I, fRXPat->fLiteralText.length());
        } else {
            // TODO here:  add optimization to split case sensitive strings of length two
            //             into two single char ops, for efficiency.
            appendOp(URX_STRING, fRXPat->fLiteralText.length());
        }
        appendOp(URX_STRING_LEN, fLiteralChars.length());

        // Add this string into the accumulated strings of the compiled pattern.
        fRXPat->fLiteralText.append(fLiteralChars);
    }

    fLiteralChars.remove();
}


int32_t RegexCompile::buildOp(int32_t type, int32_t val) {
    if (U_FAILURE(*fStatus)) {
        return 0;
    }
    if (type < 0 || type > 255) {
        UPRV_UNREACHABLE;
    }
    if (val > 0x00ffffff) {
        UPRV_UNREACHABLE;
    }
    if (val < 0) {
        if (!(type == URX_RESERVED_OP_N || type == URX_RESERVED_OP)) {
            UPRV_UNREACHABLE;
        }
        if (URX_TYPE(val) != 0xff) {
            UPRV_UNREACHABLE;
        }
        type = URX_RESERVED_OP_N;
    }
    return (type << 24) | val;
}


//------------------------------------------------------------------------------
//
//   appendOp()             Append a new instruction onto the compiled pattern
//                          Includes error checking, limiting the size of the
//                          pattern to lengths that can be represented in the
//                          24 bit operand field of an instruction.
//
//------------------------------------------------------------------------------
void RegexCompile::appendOp(int32_t op) {
    if (U_FAILURE(*fStatus)) {
        return;
    }
    fRXPat->fCompiledPat->addElement(op, *fStatus);
    if ((fRXPat->fCompiledPat->size() > 0x00fffff0) && U_SUCCESS(*fStatus)) {
        error(U_REGEX_PATTERN_TOO_BIG);
    }
}

void RegexCompile::appendOp(int32_t type, int32_t val) {
    appendOp(buildOp(type, val));
}


//------------------------------------------------------------------------------
//
//   insertOp()             Insert a slot for a new opcode into the already
//                          compiled pattern code.
//
//                          Fill the slot with a NOP.  Our caller will replace it
//                          with what they really wanted.
//
//------------------------------------------------------------------------------
void   RegexCompile::insertOp(int32_t where) {
    UVector64 *code = fRXPat->fCompiledPat;
    U_ASSERT(where>0 && where < code->size());

    int32_t  nop = buildOp(URX_NOP, 0);
    code->insertElementAt(nop, where, *fStatus);

    // Walk through the pattern, looking for any ops with targets that
    //  were moved down by the insert.  Fix them.
    int32_t loc;
    for (loc=0; loc<code->size(); loc++) {
        int32_t op = (int32_t)code->elementAti(loc);
        int32_t opType = URX_TYPE(op);
        int32_t opValue = URX_VAL(op);
        if ((opType == URX_JMP         ||
            opType == URX_JMPX         ||
            opType == URX_STATE_SAVE   ||
            opType == URX_CTR_LOOP     ||
            opType == URX_CTR_LOOP_NG  ||
            opType == URX_JMP_SAV      ||
            opType == URX_JMP_SAV_X    ||
            opType == URX_RELOC_OPRND)    && opValue > where) {
            // Target location for this opcode is after the insertion point and
            //   needs to be incremented to adjust for the insertion.
            opValue++;
            op = buildOp(opType, opValue);
            code->setElementAt(op, loc);
        }
    }

    // Now fix up the parentheses stack.  All positive values in it are locations in
    //  the compiled pattern.   (Negative values are frame boundaries, and don't need fixing.)
    for (loc=0; loc<fParenStack.size(); loc++) {
        int32_t x = fParenStack.elementAti(loc);
        U_ASSERT(x < code->size());
        if (x>where) {
            x++;
            fParenStack.setElementAt(x, loc);
        }
    }

    if (fMatchCloseParen > where) {
        fMatchCloseParen++;
    }
    if (fMatchOpenParen > where) {
        fMatchOpenParen++;
    }
}


//------------------------------------------------------------------------------
//
//   allocateData()        Allocate storage in the matcher's static data area.
//                         Return the index for the newly allocated data.
//                         The storage won't actually exist until we are running a match
//                         operation, but the storage indexes are inserted into various
//                         opcodes while compiling the pattern.
//
//------------------------------------------------------------------------------
int32_t RegexCompile::allocateData(int32_t size) {
    if (U_FAILURE(*fStatus)) {
        return 0;
    }
    if (size <= 0 || size > 0x100 || fRXPat->fDataSize < 0) {
        error(U_REGEX_INTERNAL_ERROR);
        return 0;
    }
    int32_t dataIndex = fRXPat->fDataSize;
    fRXPat->fDataSize += size;
    if (fRXPat->fDataSize >= 0x00fffff0) {
        error(U_REGEX_INTERNAL_ERROR);
    }
    return dataIndex;
}


//------------------------------------------------------------------------------
//
//   allocateStackData()   Allocate space in the back-tracking stack frame.
//                         Return the index for the newly allocated data.
//                         The frame indexes are inserted into various
//                         opcodes while compiling the pattern, meaning that frame
//                         size must be restricted to the size that will fit
//                         as an operand (24 bits).
//
//------------------------------------------------------------------------------
int32_t RegexCompile::allocateStackData(int32_t size) {
    if (U_FAILURE(*fStatus)) {
        return 0;
    }
    if (size <= 0 || size > 0x100 || fRXPat->fFrameSize < 0) {
        error(U_REGEX_INTERNAL_ERROR);
        return 0;
    }
    int32_t dataIndex = fRXPat->fFrameSize;
    fRXPat->fFrameSize += size;
    if (fRXPat->fFrameSize >= 0x00fffff0) {
        error(U_REGEX_PATTERN_TOO_BIG);
    }
    return dataIndex;
}


//------------------------------------------------------------------------------
//
//   blockTopLoc()          Find or create a location in the compiled pattern
//                          at the start of the operation or block that has
//                          just been compiled.  Needed when a quantifier (* or
//                          whatever) appears, and we need to add an operation
//                          at the start of the thing being quantified.
//
//                          (Parenthesized Blocks) have a slot with a NOP that
//                          is reserved for this purpose.  .* or similar don't
//                          and a slot needs to be added.
//
//       parameter reserveLoc   :  TRUE -  ensure that there is space to add an opcode
//                                         at the returned location.
//                                 FALSE - just return the address,
//                                         do not reserve a location there.
//
//------------------------------------------------------------------------------
int32_t   RegexCompile::blockTopLoc(UBool reserveLoc) {
    int32_t   theLoc;
    fixLiterals(TRUE);  // Emit code for any pending literals.
                        //   If last item was a string, emit separate op for the its last char.
    if (fRXPat->fCompiledPat->size() == fMatchCloseParen)
    {
        // The item just processed is a parenthesized block.
        theLoc = fMatchOpenParen;   // A slot is already reserved for us.
        U_ASSERT(theLoc > 0);
        U_ASSERT(URX_TYPE(((uint32_t)fRXPat->fCompiledPat->elementAti(theLoc))) == URX_NOP);
    }
    else {
        // Item just compiled is a single thing, a ".", or a single char, a string or a set reference.
        // No slot for STATE_SAVE was pre-reserved in the compiled code.
        // We need to make space now.
        theLoc = fRXPat->fCompiledPat->size()-1;
        int32_t opAtTheLoc = (int32_t)fRXPat->fCompiledPat->elementAti(theLoc);
        if (URX_TYPE(opAtTheLoc) == URX_STRING_LEN) {
            // Strings take two opcode, we want the position of the first one.
            // We can have a string at this point if a single character case-folded to two.
            theLoc--;
        }
        if (reserveLoc) {
            int32_t  nop = buildOp(URX_NOP, 0);
            fRXPat->fCompiledPat->insertElementAt(nop, theLoc, *fStatus);
        }
    }
    return theLoc;
}



//------------------------------------------------------------------------------
//
//    handleCloseParen      When compiling a close paren, we need to go back
//                          and fix up any JMP or SAVE operations within the
//                          parenthesized block that need to target the end
//                          of the block.  The locations of these are kept on
//                          the paretheses stack.
//
//                          This function is called both when encountering a
//                          real ) and at the end of the pattern.
//
//------------------------------------------------------------------------------
void  RegexCompile::handleCloseParen() {
    int32_t   patIdx;
    int32_t   patOp;
    if (fParenStack.size() <= 0) {
        error(U_REGEX_MISMATCHED_PAREN);
        return;
    }

    // Emit code for any pending literals.
    fixLiterals(FALSE);

    // Fixup any operations within the just-closed parenthesized group
    //    that need to reference the end of the (block).
    //    (The first one popped from the stack is an unused slot for
    //     alternation (OR) state save, but applying the fixup to it does no harm.)
    for (;;) {
        patIdx = fParenStack.popi();
        if (patIdx < 0) {
            // value < 0 flags the start of the frame on the paren stack.
            break;
        }
        U_ASSERT(patIdx>0 && patIdx <= fRXPat->fCompiledPat->size());
        patOp = (int32_t)fRXPat->fCompiledPat->elementAti(patIdx);
        U_ASSERT(URX_VAL(patOp) == 0);          // Branch target for JMP should not be set.
        patOp |= fRXPat->fCompiledPat->size();  // Set it now.
        fRXPat->fCompiledPat->setElementAt(patOp, patIdx);
        fMatchOpenParen     = patIdx;
    }

    //  At the close of any parenthesized block, restore the match mode flags  to
    //  the value they had at the open paren.  Saved value is
    //  at the top of the paren stack.
    fModeFlags = fParenStack.popi();
    U_ASSERT(fModeFlags < 0);

    // DO any additional fixups, depending on the specific kind of
    // parentesized grouping this is

    switch (patIdx) {
    case plain:
    case flags:
        // No additional fixups required.
        //   (Grouping-only parentheses)
        break;
    case capturing:
        // Capturing Parentheses.
        //   Insert a End Capture op into the pattern.
        //   The frame offset of the variables for this cg is obtained from the
        //       start capture op and put it into the end-capture op.
        {
            int32_t   captureOp = (int32_t)fRXPat->fCompiledPat->elementAti(fMatchOpenParen+1);
            U_ASSERT(URX_TYPE(captureOp) == URX_START_CAPTURE);

            int32_t   frameVarLocation = URX_VAL(captureOp);
            appendOp(URX_END_CAPTURE, frameVarLocation);
        }
        break;
    case atomic:
        // Atomic Parenthesis.
        //   Insert a LD_SP operation to restore the state stack to the position
        //   it was when the atomic parens were entered.
        {
            int32_t   stoOp = (int32_t)fRXPat->fCompiledPat->elementAti(fMatchOpenParen+1);
            U_ASSERT(URX_TYPE(stoOp) == URX_STO_SP);
            int32_t   stoLoc = URX_VAL(stoOp);
            appendOp(URX_LD_SP, stoLoc);
        }
        break;

    case lookAhead:
        {
            int32_t  startOp = (int32_t)fRXPat->fCompiledPat->elementAti(fMatchOpenParen-5);
            U_ASSERT(URX_TYPE(startOp) == URX_LA_START);
            int32_t dataLoc  = URX_VAL(startOp);
            appendOp(URX_LA_END, dataLoc);
        }
        break;

    case negLookAhead:
        {
            // See comment at doOpenLookAheadNeg
            int32_t  startOp = (int32_t)fRXPat->fCompiledPat->elementAti(fMatchOpenParen-1);
            U_ASSERT(URX_TYPE(startOp) == URX_LA_START);
            int32_t dataLoc  = URX_VAL(startOp);
            appendOp(URX_LA_END, dataLoc);
            appendOp(URX_BACKTRACK, 0);
            appendOp(URX_LA_END, dataLoc);

            // Patch the URX_SAVE near the top of the block.
            // The destination of the SAVE is the final LA_END that was just added.
            int32_t saveOp   = (int32_t)fRXPat->fCompiledPat->elementAti(fMatchOpenParen);
            U_ASSERT(URX_TYPE(saveOp) == URX_STATE_SAVE);
            int32_t dest     = fRXPat->fCompiledPat->size()-1;
            saveOp           = buildOp(URX_STATE_SAVE, dest);
            fRXPat->fCompiledPat->setElementAt(saveOp, fMatchOpenParen);
        }
        break;

    case lookBehind:
        {
            // See comment at doOpenLookBehind.

            // Append the URX_LB_END and URX_LA_END to the compiled pattern.
            int32_t  startOp = (int32_t)fRXPat->fCompiledPat->elementAti(fMatchOpenParen-4);
            U_ASSERT(URX_TYPE(startOp) == URX_LB_START);
            int32_t dataLoc  = URX_VAL(startOp);
            appendOp(URX_LB_END, dataLoc);
            appendOp(URX_LA_END, dataLoc);

            // Determine the min and max bounds for the length of the
            //  string that the pattern can match.
            //  An unbounded upper limit is an error.
            int32_t patEnd   = fRXPat->fCompiledPat->size() - 1;
            int32_t minML    = minMatchLength(fMatchOpenParen, patEnd);
            int32_t maxML    = maxMatchLength(fMatchOpenParen, patEnd);
            if (URX_TYPE(maxML) != 0) {
                error(U_REGEX_LOOK_BEHIND_LIMIT);
                break;
            }
            if (maxML == INT32_MAX) {
                error(U_REGEX_LOOK_BEHIND_LIMIT);
                break;
            }
            if (minML == INT32_MAX) {
                // This condition happens when no match is possible, such as with a
                // [set] expression containing no elements.
                // In principle, the generated code to evaluate the expression could be deleted,
                // but it's probably not worth the complication.
                minML = 0;
            }
            U_ASSERT(minML <= maxML);

            // Insert the min and max match len bounds into the URX_LB_CONT op that
            //  appears at the top of the look-behind block, at location fMatchOpenParen+1
            fRXPat->fCompiledPat->setElementAt(minML,  fMatchOpenParen-2);
            fRXPat->fCompiledPat->setElementAt(maxML,  fMatchOpenParen-1);

        }
        break;



    case lookBehindN:
        {
            // See comment at doOpenLookBehindNeg.

            // Append the URX_LBN_END to the compiled pattern.
            int32_t  startOp = (int32_t)fRXPat->fCompiledPat->elementAti(fMatchOpenParen-5);
            U_ASSERT(URX_TYPE(startOp) == URX_LB_START);
            int32_t dataLoc  = URX_VAL(startOp);
            appendOp(URX_LBN_END, dataLoc);

            // Determine the min and max bounds for the length of the
            //  string that the pattern can match.
            //  An unbounded upper limit is an error.
            int32_t patEnd   = fRXPat->fCompiledPat->size() - 1;
            int32_t minML    = minMatchLength(fMatchOpenParen, patEnd);
            int32_t maxML    = maxMatchLength(fMatchOpenParen, patEnd);
            if (URX_TYPE(maxML) != 0) {
                error(U_REGEX_LOOK_BEHIND_LIMIT);
                break;
            }
            if (maxML == INT32_MAX) {
                error(U_REGEX_LOOK_BEHIND_LIMIT);
                break;
            }
            if (minML == INT32_MAX) {
                // This condition happens when no match is possible, such as with a
                // [set] expression containing no elements.
                // In principle, the generated code to evaluate the expression could be deleted,
                // but it's probably not worth the complication.
                minML = 0;
            }

            U_ASSERT(minML <= maxML);

            // Insert the min and max match len bounds into the URX_LB_CONT op that
            //  appears at the top of the look-behind block, at location fMatchOpenParen+1
            fRXPat->fCompiledPat->setElementAt(minML,  fMatchOpenParen-3);
            fRXPat->fCompiledPat->setElementAt(maxML,  fMatchOpenParen-2);

            // Insert the pattern location to continue at after a successful match
            //  as the last operand of the URX_LBN_CONT
            int32_t op = buildOp(URX_RELOC_OPRND, fRXPat->fCompiledPat->size());
            fRXPat->fCompiledPat->setElementAt(op,  fMatchOpenParen-1);
        }
        break;



    default:
        UPRV_UNREACHABLE;
    }

    // remember the next location in the compiled pattern.
    // The compilation of Quantifiers will look at this to see whether its looping
    //   over a parenthesized block or a single item
    fMatchCloseParen = fRXPat->fCompiledPat->size();
}



//------------------------------------------------------------------------------
//
//   compileSet       Compile the pattern operations for a reference to a
//                    UnicodeSet.
//
//------------------------------------------------------------------------------
void        RegexCompile::compileSet(UnicodeSet *theSet)
{
    if (theSet == NULL) {
        return;
    }
    //  Remove any strings from the set.
    //  There shoudn't be any, but just in case.
    //     (Case Closure can add them; if we had a simple case closure available that
    //      ignored strings, that would be better.)
    theSet->removeAllStrings();
    int32_t  setSize = theSet->size();

    switch (setSize) {
    case 0:
        {
            // Set of no elements.   Always fails to match.
            appendOp(URX_BACKTRACK, 0);
            delete theSet;
        }
        break;

    case 1:
        {
            // The set contains only a single code point.  Put it into
            //   the compiled pattern as a single char operation rather
            //   than a set, and discard the set itself.
            literalChar(theSet->charAt(0));
            delete theSet;
        }
        break;

    default:
        {
            //  The set contains two or more chars.  (the normal case)
            //  Put it into the compiled pattern as a set.
            theSet->freeze();
            int32_t setNumber = fRXPat->fSets->size();
            fRXPat->fSets->addElement(theSet, *fStatus);
            appendOp(URX_SETREF, setNumber);
        }
    }
}


//------------------------------------------------------------------------------
//
//   compileInterval    Generate the code for a {min, max} style interval quantifier.
//                      Except for the specific opcodes used, the code is the same
//                      for all three types (greedy, non-greedy, possessive) of
//                      intervals.  The opcodes are supplied as parameters.
//                      (There are two sets of opcodes - greedy & possessive use the
//                      same ones, while non-greedy has it's own.)
//
//                      The code for interval loops has this form:
//                         0  CTR_INIT   counter loc (in stack frame)
//                         1             5  patt address of CTR_LOOP at bottom of block
//                         2             min count
//                         3             max count   (-1 for unbounded)
//                         4  ...        block to be iterated over
//                         5  CTR_LOOP
//
//                       In
//------------------------------------------------------------------------------
void        RegexCompile::compileInterval(int32_t InitOp,  int32_t LoopOp)
{
    // The CTR_INIT op at the top of the block with the {n,m} quantifier takes
    //   four slots in the compiled code.  Reserve them.
    int32_t   topOfBlock = blockTopLoc(TRUE);
    insertOp(topOfBlock);
    insertOp(topOfBlock);
    insertOp(topOfBlock);

    // The operands for the CTR_INIT opcode include the index in the matcher data
    //   of the counter.  Allocate it now. There are two data items
    //        counterLoc   -->  Loop counter
    //               +1    -->  Input index (for breaking non-progressing loops)
    //                          (Only present if unbounded upper limit on loop)
    int32_t   dataSize = fIntervalUpper < 0 ? 2 : 1;
    int32_t   counterLoc = allocateStackData(dataSize);

    int32_t   op = buildOp(InitOp, counterLoc);
    fRXPat->fCompiledPat->setElementAt(op, topOfBlock);

    // The second operand of CTR_INIT is the location following the end of the loop.
    //   Must put in as a URX_RELOC_OPRND so that the value will be adjusted if the
    //   compilation of something later on causes the code to grow and the target
    //   position to move.
    int32_t loopEnd = fRXPat->fCompiledPat->size();
    op = buildOp(URX_RELOC_OPRND, loopEnd);
    fRXPat->fCompiledPat->setElementAt(op, topOfBlock+1);

    // Followed by the min and max counts.
    fRXPat->fCompiledPat->setElementAt(fIntervalLow, topOfBlock+2);
    fRXPat->fCompiledPat->setElementAt(fIntervalUpper, topOfBlock+3);

    // Append the CTR_LOOP op.  The operand is the location of the CTR_INIT op.
    //   Goes at end of the block being looped over, so just append to the code so far.
    appendOp(LoopOp, topOfBlock);

    if ((fIntervalLow & 0xff000000) != 0 ||
        (fIntervalUpper > 0 && (fIntervalUpper & 0xff000000) != 0)) {
            error(U_REGEX_NUMBER_TOO_BIG);
        }

    if (fIntervalLow > fIntervalUpper && fIntervalUpper != -1) {
        error(U_REGEX_MAX_LT_MIN);
    }
}



UBool RegexCompile::compileInlineInterval() {
    if (fIntervalUpper > 10 || fIntervalUpper < fIntervalLow) {
        // Too big to inline.  Fail, which will cause looping code to be generated.
        //   (Upper < Lower picks up unbounded upper and errors, both.)
        return FALSE;
    }

    int32_t   topOfBlock = blockTopLoc(FALSE);
    if (fIntervalUpper == 0) {
        // Pathological case.  Attempt no matches, as if the block doesn't exist.
        // Discard the generated code for the block.
        // If the block included parens, discard the info pertaining to them as well.
        fRXPat->fCompiledPat->setSize(topOfBlock);
        if (fMatchOpenParen >= topOfBlock) {
            fMatchOpenParen = -1;
        }
        if (fMatchCloseParen >= topOfBlock) {
            fMatchCloseParen = -1;
        }
        return TRUE;
    }

    if (topOfBlock != fRXPat->fCompiledPat->size()-1 && fIntervalUpper != 1) {
        // The thing being repeated is not a single op, but some
        //   more complex block.  Do it as a loop, not inlines.
        //   Note that things "repeated" a max of once are handled as inline, because
        //     the one copy of the code already generated is just fine.
        return FALSE;
    }

    // Pick up the opcode that is to be repeated
    //
    int32_t op = (int32_t)fRXPat->fCompiledPat->elementAti(topOfBlock);

    // Compute the pattern location where the inline sequence
    //   will end, and set up the state save op that will be needed.
    //
    int32_t endOfSequenceLoc = fRXPat->fCompiledPat->size()-1
                                + fIntervalUpper + (fIntervalUpper-fIntervalLow);
    int32_t saveOp = buildOp(URX_STATE_SAVE, endOfSequenceLoc);
    if (fIntervalLow == 0) {
        insertOp(topOfBlock);
        fRXPat->fCompiledPat->setElementAt(saveOp, topOfBlock);
    }



    //  Loop, emitting the op for the thing being repeated each time.
    //    Loop starts at 1 because one instance of the op already exists in the pattern,
    //    it was put there when it was originally encountered.
    int32_t i;
    for (i=1; i<fIntervalUpper; i++ ) {
        if (i >= fIntervalLow) {
            appendOp(saveOp);
        }
        appendOp(op);
    }
    return TRUE;
}



//------------------------------------------------------------------------------
//
//   caseInsensitiveStart  given a single code point from a pattern string, determine the 
//                         set of characters that could potentially begin a case-insensitive 
//                         match of a string beginning with that character, using full Unicode
//                         case insensitive matching.
//
//          This is used in optimizing find().
//
//          closeOver(USET_CASE_INSENSITIVE) does most of what is needed, but
//          misses cases like this:
//             A string from the pattern begins with 'ss' (although all we know
//                 in this context is that it begins with 's')
//             The pattern could match a string beginning with a German sharp-s
//
//           To the ordinary case closure for a character c, we add all other
//           characters cx where the case closure of cx incudes a string form that begins
//           with the original character c.
//
//           This function could be made smarter. The full pattern string is available
//           and it would be possible to verify that the extra characters being added
//           to the starting set fully match, rather than having just a first-char of the
//           folded form match.
//
//------------------------------------------------------------------------------
void  RegexCompile::findCaseInsensitiveStarters(UChar32 c, UnicodeSet *starterChars) {

// Machine Generated below.
// It may need updating with new versions of Unicode.
// Intltest test RegexTest::TestCaseInsensitiveStarters will fail if an update is needed.
// The update tool is here: svn+ssh://source.icu-project.org/repos/icu/tools/trunk/unicode/c/genregexcasing

// Machine Generated Data. Do not hand edit.
    static const UChar32 RECaseFixCodePoints[] = {
        0x61, 0x66, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x77, 0x79, 0x2bc, 
        0x3ac, 0x3ae, 0x3b1, 0x3b7, 0x3b9, 0x3c1, 0x3c5, 0x3c9, 0x3ce, 0x565, 
        0x574, 0x57e, 0x1f00, 0x1f01, 0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07, 
        0x1f20, 0x1f21, 0x1f22, 0x1f23, 0x1f24, 0x1f25, 0x1f26, 0x1f27, 0x1f60, 0x1f61, 
        0x1f62, 0x1f63, 0x1f64, 0x1f65, 0x1f66, 0x1f67, 0x1f70, 0x1f74, 0x1f7c, 0x110000};

    static const int16_t RECaseFixStringOffsets[] = {
        0x0, 0x1, 0x6, 0x7, 0x8, 0x9, 0xd, 0xe, 0xf, 0x10, 
        0x11, 0x12, 0x13, 0x17, 0x1b, 0x20, 0x21, 0x2a, 0x2e, 0x2f, 
        0x30, 0x34, 0x35, 0x37, 0x39, 0x3b, 0x3d, 0x3f, 0x41, 0x43, 
        0x45, 0x47, 0x49, 0x4b, 0x4d, 0x4f, 0x51, 0x53, 0x55, 0x57, 
        0x59, 0x5b, 0x5d, 0x5f, 0x61, 0x63, 0x65, 0x66, 0x67, 0};

    static const int16_t RECaseFixCounts[] = {
        0x1, 0x5, 0x1, 0x1, 0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 
        0x1, 0x1, 0x4, 0x4, 0x5, 0x1, 0x9, 0x4, 0x1, 0x1, 
        0x4, 0x1, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 
        0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 
        0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0};

    static const UChar RECaseFixData[] = {
        0x1e9a, 0xfb00, 0xfb01, 0xfb02, 0xfb03, 0xfb04, 0x1e96, 0x130, 0x1f0, 0xdf, 
        0x1e9e, 0xfb05, 0xfb06, 0x1e97, 0x1e98, 0x1e99, 0x149, 0x1fb4, 0x1fc4, 0x1fb3, 
        0x1fb6, 0x1fb7, 0x1fbc, 0x1fc3, 0x1fc6, 0x1fc7, 0x1fcc, 0x390, 0x1fd2, 0x1fd3, 
        0x1fd6, 0x1fd7, 0x1fe4, 0x3b0, 0x1f50, 0x1f52, 0x1f54, 0x1f56, 0x1fe2, 0x1fe3, 
        0x1fe6, 0x1fe7, 0x1ff3, 0x1ff6, 0x1ff7, 0x1ffc, 0x1ff4, 0x587, 0xfb13, 0xfb14, 
        0xfb15, 0xfb17, 0xfb16, 0x1f80, 0x1f88, 0x1f81, 0x1f89, 0x1f82, 0x1f8a, 0x1f83, 
        0x1f8b, 0x1f84, 0x1f8c, 0x1f85, 0x1f8d, 0x1f86, 0x1f8e, 0x1f87, 0x1f8f, 0x1f90, 
        0x1f98, 0x1f91, 0x1f99, 0x1f92, 0x1f9a, 0x1f93, 0x1f9b, 0x1f94, 0x1f9c, 0x1f95, 
        0x1f9d, 0x1f96, 0x1f9e, 0x1f97, 0x1f9f, 0x1fa0, 0x1fa8, 0x1fa1, 0x1fa9, 0x1fa2, 
        0x1faa, 0x1fa3, 0x1fab, 0x1fa4, 0x1fac, 0x1fa5, 0x1fad, 0x1fa6, 0x1fae, 0x1fa7, 
        0x1faf, 0x1fb2, 0x1fc2, 0x1ff2, 0};

// End of machine generated data.

    if (c < UCHAR_MIN_VALUE || c > UCHAR_MAX_VALUE) {
        // This function should never be called with an invalid input character.
        UPRV_UNREACHABLE;
    } else if (u_hasBinaryProperty(c, UCHAR_CASE_SENSITIVE)) {
        UChar32 caseFoldedC  = u_foldCase(c, U_FOLD_CASE_DEFAULT);
        starterChars->set(caseFoldedC, caseFoldedC);

        int32_t i;
        for (i=0; RECaseFixCodePoints[i]<c ; i++) {
            // Simple linear search through the sorted list of interesting code points.
        }

        if (RECaseFixCodePoints[i] == c) {
            int32_t dataIndex = RECaseFixStringOffsets[i];
            int32_t numCharsToAdd = RECaseFixCounts[i];
            UChar32 cpToAdd = 0;
            for (int32_t j=0; j<numCharsToAdd; j++) {
                U16_NEXT_UNSAFE(RECaseFixData, dataIndex, cpToAdd);
                starterChars->add(cpToAdd);
            }
        }

        starterChars->closeOver(USET_CASE_INSENSITIVE);
        starterChars->removeAllStrings();
    } else {
        // Not a cased character. Just return it alone.
        starterChars->set(c, c);
    }
}


// Increment with overflow check.
// val and delta will both be positive.

static int32_t safeIncrement(int32_t val, int32_t delta) {
    if (INT32_MAX - val > delta) {
        return val + delta;
    } else {
        return INT32_MAX;
    }
}


//------------------------------------------------------------------------------
//
//   matchStartType    Determine how a match can start.
//                     Used to optimize find() operations.
//
//                     Operation is very similar to minMatchLength().  Walk the compiled
//                     pattern, keeping an on-going minimum-match-length.  For any
//                     op where the min match coming in is zero, add that ops possible
//                     starting matches to the possible starts for the overall pattern.
//
//------------------------------------------------------------------------------
void   RegexCompile::matchStartType() {
    if (U_FAILURE(*fStatus)) {
        return;
    }


    int32_t    loc;                    // Location in the pattern of the current op being processed.
    int32_t    op;                     // The op being processed
    int32_t    opType;                 // The opcode type of the op
    int32_t    currentLen = 0;         // Minimum length of a match to this point (loc) in the pattern
    int32_t    numInitialStrings = 0;  // Number of strings encountered that could match at start.

    UBool      atStart = TRUE;         // True if no part of the pattern yet encountered
                                       //   could have advanced the position in a match.
                                       //   (Maximum match length so far == 0)

    // forwardedLength is a vector holding minimum-match-length values that
    //   are propagated forward in the pattern by JMP or STATE_SAVE operations.
    //   It must be one longer than the pattern being checked because some  ops
    //   will jmp to a end-of-block+1 location from within a block, and we must
    //   count those when checking the block.
    int32_t end = fRXPat->fCompiledPat->size();
    UVector32  forwardedLength(end+1, *fStatus);
    forwardedLength.setSize(end+1);
    for (loc=3; loc<end; loc++) {
        forwardedLength.setElementAt(INT32_MAX, loc);
    }

    for (loc = 3; loc<end; loc++) {
        op = (int32_t)fRXPat->fCompiledPat->elementAti(loc);
        opType = URX_TYPE(op);

        // The loop is advancing linearly through the pattern.
        // If the op we are now at was the destination of a branch in the pattern,
        // and that path has a shorter minimum length than the current accumulated value,
        // replace the current accumulated value.
        if (forwardedLength.elementAti(loc) < currentLen) {
            currentLen = forwardedLength.elementAti(loc);
            U_ASSERT(currentLen>=0 && currentLen < INT32_MAX);
        }

        switch (opType) {
            // Ops that don't change the total length matched
        case URX_RESERVED_OP:
        case URX_END:
        case URX_FAIL:
        case URX_STRING_LEN:
        case URX_NOP:
        case URX_START_CAPTURE:
        case URX_END_CAPTURE:
        case URX_BACKSLASH_B:
        case URX_BACKSLASH_BU:
        case URX_BACKSLASH_G:
        case URX_BACKSLASH_Z:
        case URX_DOLLAR:
        case URX_DOLLAR_M:
        case URX_DOLLAR_D:
        case URX_DOLLAR_MD:
        case URX_RELOC_OPRND:
        case URX_STO_INP_LOC:
        case URX_BACKREF:         // BackRef.  Must assume that it might be a zero length match
        case URX_BACKREF_I:

        case URX_STO_SP:          // Setup for atomic or possessive blocks.  Doesn't change what can match.
        case URX_LD_SP:
            break;

        case URX_CARET:
            if (atStart) {
                fRXPat->fStartType = START_START;
            }
            break;

        case URX_CARET_M:
        case URX_CARET_M_UNIX:
            if (atStart) {
                fRXPat->fStartType = START_LINE;
            }
            break;

        case URX_ONECHAR:
            if (currentLen == 0) {
                // This character could appear at the start of a match.
                //   Add it to the set of possible starting characters.
                fRXPat->fInitialChars->add(URX_VAL(op));
                numInitialStrings += 2;
            }
            currentLen = safeIncrement(currentLen, 1);
            atStart = FALSE;
            break;


        case URX_SETREF:
            if (currentLen == 0) {
                int32_t  sn = URX_VAL(op);
                U_ASSERT(sn > 0 && sn < fRXPat->fSets->size());
                const UnicodeSet *s = (UnicodeSet *)fRXPat->fSets->elementAt(sn);
                fRXPat->fInitialChars->addAll(*s);
                numInitialStrings += 2;
            }
            currentLen = safeIncrement(currentLen, 1);
            atStart = FALSE;
            break;

        case URX_LOOP_SR_I:
            // [Set]*, like a SETREF, above, in what it can match,
            //  but may not match at all, so currentLen is not incremented.
            if (currentLen == 0) {
                int32_t  sn = URX_VAL(op);
                U_ASSERT(sn > 0 && sn < fRXPat->fSets->size());
                const UnicodeSet *s = (UnicodeSet *)fRXPat->fSets->elementAt(sn);
                fRXPat->fInitialChars->addAll(*s);
                numInitialStrings += 2;
            }
            atStart = FALSE;
            break;

        case URX_LOOP_DOT_I:
            if (currentLen == 0) {
                // .* at the start of a pattern.
                //    Any character can begin the match.
                fRXPat->fInitialChars->clear();
                fRXPat->fInitialChars->complement();
                numInitialStrings += 2;
            }
            atStart = FALSE;
            break;


        case URX_STATIC_SETREF:
            if (currentLen == 0) {
                int32_t  sn = URX_VAL(op);
                U_ASSERT(sn>0 && sn<URX_LAST_SET);
                const UnicodeSet &s = RegexStaticSets::gStaticSets->fPropSets[sn];
                fRXPat->fInitialChars->addAll(s);
                numInitialStrings += 2;
            }
            currentLen = safeIncrement(currentLen, 1);
            atStart = FALSE;
            break;



        case URX_STAT_SETREF_N:
            if (currentLen == 0) {
                int32_t  sn = URX_VAL(op);
                UnicodeSet sc;
                sc.addAll(RegexStaticSets::gStaticSets->fPropSets[sn]).complement();
                fRXPat->fInitialChars->addAll(sc);
                numInitialStrings += 2;
            }
            currentLen = safeIncrement(currentLen, 1);
            atStart = FALSE;
            break;



        case URX_BACKSLASH_D:
            // Digit Char
             if (currentLen == 0) {
                 UnicodeSet s;
                 s.applyIntPropertyValue(UCHAR_GENERAL_CATEGORY_MASK, U_GC_ND_MASK, *fStatus);
                 if (URX_VAL(op) != 0) {
                     s.complement();
                 }
                 fRXPat->fInitialChars->addAll(s);
                 numInitialStrings += 2;
            }
            currentLen = safeIncrement(currentLen, 1);
            atStart = FALSE;
            break;


        case URX_BACKSLASH_H:
            // Horiz white space
            if (currentLen == 0) {
                UnicodeSet s;
                s.applyIntPropertyValue(UCHAR_GENERAL_CATEGORY_MASK, U_GC_ZS_MASK, *fStatus);
                s.add((UChar32)9);   // Tab
                if (URX_VAL(op) != 0) {
                    s.complement();
                }
                fRXPat->fInitialChars->addAll(s);
                numInitialStrings += 2;
            }
            currentLen = safeIncrement(currentLen, 1);
            atStart = FALSE;
            break;


        case URX_BACKSLASH_R:       // Any line ending sequence
        case URX_BACKSLASH_V:       // Any line ending code point, with optional negation
            if (currentLen == 0) {
                UnicodeSet s;
                s.add((UChar32)0x0a, (UChar32)0x0d);  // add range
                s.add((UChar32)0x85);
                s.add((UChar32)0x2028, (UChar32)0x2029);
                if (URX_VAL(op) != 0) {
                     // Complement option applies to URX_BACKSLASH_V only.
                     s.complement();
                }
                fRXPat->fInitialChars->addAll(s);
                numInitialStrings += 2;
            }
            currentLen = safeIncrement(currentLen, 1);
            atStart = FALSE;
            break;



        case URX_ONECHAR_I:
            // Case Insensitive Single Character.
            if (currentLen == 0) {
                UChar32  c = URX_VAL(op);
                if (u_hasBinaryProperty(c, UCHAR_CASE_SENSITIVE)) {
                    UnicodeSet starters(c, c);
                    starters.closeOver(USET_CASE_INSENSITIVE);
                    // findCaseInsensitiveStarters(c, &starters);
                    //   For ONECHAR_I, no need to worry about text chars that expand on folding into strings.
                    //   The expanded folding can't match the pattern.
                    fRXPat->fInitialChars->addAll(starters);
                } else {
                    // Char has no case variants.  Just add it as-is to the
                    //   set of possible starting chars.
                    fRXPat->fInitialChars->add(c);
                }
                numInitialStrings += 2;
            }
            currentLen = safeIncrement(currentLen, 1);
            atStart = FALSE;
            break;


        case URX_BACKSLASH_X:   // Grahpeme Cluster.  Minimum is 1, max unbounded.
        case URX_DOTANY_ALL:    // . matches one or two.
        case URX_DOTANY:
        case URX_DOTANY_UNIX:
            if (currentLen == 0) {
                // These constructs are all bad news when they appear at the start
                //   of a match.  Any character can begin the match.
                fRXPat->fInitialChars->clear();
                fRXPat->fInitialChars->complement();
                numInitialStrings += 2;
            }
            currentLen = safeIncrement(currentLen, 1);
            atStart = FALSE;
            break;


        case URX_JMPX:
            loc++;             // Except for extra operand on URX_JMPX, same as URX_JMP.
            U_FALLTHROUGH;
        case URX_JMP:
            {
                int32_t  jmpDest = URX_VAL(op);
                if (jmpDest < loc) {
                    // Loop of some kind.  Can safely ignore, the worst that will happen
                    //  is that we understate the true minimum length
                    currentLen = forwardedLength.elementAti(loc+1);

                } else {
                    // Forward jump.  Propagate the current min length to the target loc of the jump.
                    U_ASSERT(jmpDest <= end+1);
                    if (forwardedLength.elementAti(jmpDest) > currentLen) {
                        forwardedLength.setElementAt(currentLen, jmpDest);
                    }
                }
            }
            atStart = FALSE;
            break;

        case URX_JMP_SAV:
        case URX_JMP_SAV_X:
            // Combo of state save to the next loc, + jmp backwards.
            //   Net effect on min. length computation is nothing.
            atStart = FALSE;
            break;

        case URX_BACKTRACK:
            // Fails are kind of like a branch, except that the min length was
            //   propagated already, by the state save.
            currentLen = forwardedLength.elementAti(loc+1);
            atStart = FALSE;
            break;


        case URX_STATE_SAVE:
            {
                // State Save, for forward jumps, propagate the current minimum.
                //             of the state save.
                int32_t  jmpDest = URX_VAL(op);
                if (jmpDest > loc) {
                    if (currentLen < forwardedLength.elementAti(jmpDest)) {
                        forwardedLength.setElementAt(currentLen, jmpDest);
                    }
                }
            }
            atStart = FALSE;
            break;




        case URX_STRING:
            {
                loc++;
                int32_t stringLenOp = (int32_t)fRXPat->fCompiledPat->elementAti(loc);
                int32_t stringLen   = URX_VAL(stringLenOp);
                U_ASSERT(URX_TYPE(stringLenOp) == URX_STRING_LEN);
                U_ASSERT(stringLenOp >= 2);
                if (currentLen == 0) {
                    // Add the starting character of this string to the set of possible starting
                    //   characters for this pattern.
                    int32_t stringStartIdx = URX_VAL(op);
                    UChar32  c = fRXPat->fLiteralText.char32At(stringStartIdx);
                    fRXPat->fInitialChars->add(c);

                    // Remember this string.  After the entire pattern has been checked,
                    //  if nothing else is identified that can start a match, we'll use it.
                    numInitialStrings++;
                    fRXPat->fInitialStringIdx = stringStartIdx;
                    fRXPat->fInitialStringLen = stringLen;
                }

                currentLen = safeIncrement(currentLen, stringLen);
                atStart = FALSE;
            }
            break;

        case URX_STRING_I:
            {
                // Case-insensitive string.  Unlike exact-match strings, we won't
                //   attempt a string search for possible match positions.  But we
                //   do update the set of possible starting characters.
                loc++;
                int32_t stringLenOp = (int32_t)fRXPat->fCompiledPat->elementAti(loc);
                int32_t stringLen   = URX_VAL(stringLenOp);
                U_ASSERT(URX_TYPE(stringLenOp) == URX_STRING_LEN);
                U_ASSERT(stringLenOp >= 2);
                if (currentLen == 0) {
                    // Add the starting character of this string to the set of possible starting
                    //   characters for this pattern.
                    int32_t stringStartIdx = URX_VAL(op);
                    UChar32  c = fRXPat->fLiteralText.char32At(stringStartIdx);
                    UnicodeSet s;
                    findCaseInsensitiveStarters(c, &s);
                    fRXPat->fInitialChars->addAll(s);
                    numInitialStrings += 2;  // Matching on an initial string not possible.
                }
                currentLen = safeIncrement(currentLen, stringLen);
                atStart = FALSE;
            }
            break;

        case URX_CTR_INIT:
        case URX_CTR_INIT_NG:
            {
                // Loop Init Ops.  These don't change the min length, but they are 4 word ops
                //   so location must be updated accordingly.
                // Loop Init Ops.
                //   If the min loop count == 0
                //      move loc forwards to the end of the loop, skipping over the body.
                //   If the min count is > 0,
                //      continue normal processing of the body of the loop.
                int32_t loopEndLoc   = (int32_t)fRXPat->fCompiledPat->elementAti(loc+1);
                        loopEndLoc   = URX_VAL(loopEndLoc);
                int32_t minLoopCount = (int32_t)fRXPat->fCompiledPat->elementAti(loc+2);
                if (minLoopCount == 0) {
                    // Min Loop Count of 0, treat like a forward branch and
                    //   move the current minimum length up to the target
                    //   (end of loop) location.
                    U_ASSERT(loopEndLoc <= end+1);
                    if (forwardedLength.elementAti(loopEndLoc) > currentLen) {
                        forwardedLength.setElementAt(currentLen, loopEndLoc);
                    }
                }
                loc+=3;  // Skips over operands of CTR_INIT
            }
            atStart = FALSE;
            break;


        case URX_CTR_LOOP:
        case URX_CTR_LOOP_NG:
            // Loop ops.
            //  The jump is conditional, backwards only.
            atStart = FALSE;
            break;

        case URX_LOOP_C:
            // More loop ops.  These state-save to themselves.
            //   don't change the minimum match
            atStart = FALSE;
            break;


        case URX_LA_START:
        case URX_LB_START:
            {
                // Look-around.  Scan forward until the matching look-ahead end,
                //   without processing the look-around block.  This is overly pessimistic.

                // Keep track of the nesting depth of look-around blocks.  Boilerplate code for
                //   lookahead contains two LA_END instructions, so count goes up by two
                //   for each LA_START.
                int32_t  depth = (opType == URX_LA_START? 2: 1);
                for (;;) {
                    loc++;
                    op = (int32_t)fRXPat->fCompiledPat->elementAti(loc);
                    if (URX_TYPE(op) == URX_LA_START) {
                        depth+=2;
                    }
                    if (URX_TYPE(op) == URX_LB_START) {
                        depth++;
                    }
                    if (URX_TYPE(op) == URX_LA_END || URX_TYPE(op)==URX_LBN_END) {
                        depth--;
                        if (depth == 0) {
                            break;
                        }
                    }
                    if (URX_TYPE(op) == URX_STATE_SAVE) {
                        // Need this because neg lookahead blocks will FAIL to outside
                        //   of the block.
                        int32_t  jmpDest = URX_VAL(op);
                        if (jmpDest > loc) {
                            if (currentLen < forwardedLength.elementAti(jmpDest)) {
                                forwardedLength.setElementAt(currentLen, jmpDest);
                            }
                        }
                    }
                    U_ASSERT(loc <= end);
                }
            }
            break;

        case URX_LA_END:
        case URX_LB_CONT:
        case URX_LB_END:
        case URX_LBN_CONT:
        case URX_LBN_END:
            UPRV_UNREACHABLE;     // Shouldn't get here.  These ops should be
                                 //  consumed by the scan in URX_LA_START and LB_START
        default:
            UPRV_UNREACHABLE;
            }

        }


    // We have finished walking through the ops.  Check whether some forward jump
    //   propagated a shorter length to location end+1.
    if (forwardedLength.elementAti(end+1) < currentLen) {
        currentLen = forwardedLength.elementAti(end+1);
    }


    fRXPat->fInitialChars8->init(fRXPat->fInitialChars);


    // Sort out what we should check for when looking for candidate match start positions.
    // In order of preference,
    //     1.   Start of input text buffer.
    //     2.   A literal string.
    //     3.   Start of line in multi-line mode.
    //     4.   A single literal character.
    //     5.   A character from a set of characters.
    //
    if (fRXPat->fStartType == START_START) {
        // Match only at the start of an input text string.
        //    start type is already set.  We're done.
    } else if (numInitialStrings == 1 && fRXPat->fMinMatchLen > 0) {
        // Match beginning only with a literal string.
        UChar32  c = fRXPat->fLiteralText.char32At(fRXPat->fInitialStringIdx);
        U_ASSERT(fRXPat->fInitialChars->contains(c));
        fRXPat->fStartType   = START_STRING;
        fRXPat->fInitialChar = c;
    } else if (fRXPat->fStartType == START_LINE) {
        // Match at start of line in Multi-Line mode.
        // Nothing to do here; everything is already set.
    } else if (fRXPat->fMinMatchLen == 0) {
        // Zero length match possible.  We could start anywhere.
        fRXPat->fStartType = START_NO_INFO;
    } else if (fRXPat->fInitialChars->size() == 1) {
        // All matches begin with the same char.
        fRXPat->fStartType   = START_CHAR;
        fRXPat->fInitialChar = fRXPat->fInitialChars->charAt(0);
        U_ASSERT(fRXPat->fInitialChar != (UChar32)-1);
    } else if (fRXPat->fInitialChars->contains((UChar32)0, (UChar32)0x10ffff) == FALSE &&
        fRXPat->fMinMatchLen > 0) {
        // Matches start with a set of character smaller than the set of all chars.
        fRXPat->fStartType = START_SET;
    } else {
        // Matches can start with anything
        fRXPat->fStartType = START_NO_INFO;
    }

    return;
}



//------------------------------------------------------------------------------
//
//   minMatchLength    Calculate the length of the shortest string that could
//                     match the specified pattern.
//                     Length is in 16 bit code units, not code points.
//
//                     The calculated length may not be exact.  The returned
//                     value may be shorter than the actual minimum; it must
//                     never be longer.
//
//                     start and end are the range of p-code operations to be
//                     examined.  The endpoints are included in the range.
//
//------------------------------------------------------------------------------
int32_t   RegexCompile::minMatchLength(int32_t start, int32_t end) {
    if (U_FAILURE(*fStatus)) {
        return 0;
    }

    U_ASSERT(start <= end);
    U_ASSERT(end < fRXPat->fCompiledPat->size());


    int32_t    loc;
    int32_t    op;
    int32_t    opType;
    int32_t    currentLen = 0;


    // forwardedLength is a vector holding minimum-match-length values that
    //   are propagated forward in the pattern by JMP or STATE_SAVE operations.
    //   It must be one longer than the pattern being checked because some  ops
    //   will jmp to a end-of-block+1 location from within a block, and we must
    //   count those when checking the block.
    UVector32  forwardedLength(end+2, *fStatus);
    forwardedLength.setSize(end+2);
    for (loc=start; loc<=end+1; loc++) {
        forwardedLength.setElementAt(INT32_MAX, loc);
    }

    for (loc = start; loc<=end; loc++) {
        op = (int32_t)fRXPat->fCompiledPat->elementAti(loc);
        opType = URX_TYPE(op);

        // The loop is advancing linearly through the pattern.
        // If the op we are now at was the destination of a branch in the pattern,
        // and that path has a shorter minimum length than the current accumulated value,
        // replace the current accumulated value.
        // U_ASSERT(currentLen>=0 && currentLen < INT32_MAX);  // MinLength == INT32_MAX for some
                                                               //   no-match-possible cases.
        if (forwardedLength.elementAti(loc) < currentLen) {
            currentLen = forwardedLength.elementAti(loc);
            U_ASSERT(currentLen>=0 && currentLen < INT32_MAX);
        }

        switch (opType) {
            // Ops that don't change the total length matched
        case URX_RESERVED_OP:
        case URX_END:
        case URX_STRING_LEN:
        case URX_NOP:
        case URX_START_CAPTURE:
        case URX_END_CAPTURE:
        case URX_BACKSLASH_B:
        case URX_BACKSLASH_BU:
        case URX_BACKSLASH_G:
        case URX_BACKSLASH_Z:
        case URX_CARET:
        case URX_DOLLAR:
        case URX_DOLLAR_M:
        case URX_DOLLAR_D:
        case URX_DOLLAR_MD:
        case URX_RELOC_OPRND:
        case URX_STO_INP_LOC:
        case URX_CARET_M:
        case URX_CARET_M_UNIX:
        case URX_BACKREF:         // BackRef.  Must assume that it might be a zero length match
        case URX_BACKREF_I:

        case URX_STO_SP:          // Setup for atomic or possessive blocks.  Doesn't change what can match.
        case URX_LD_SP:

        case URX_JMP_SAV:
        case URX_JMP_SAV_X:
            break;


            // Ops that match a minimum of one character (one or two 16 bit code units.)
            //
        case URX_ONECHAR:
        case URX_STATIC_SETREF:
        case URX_STAT_SETREF_N:
        case URX_SETREF:
        case URX_BACKSLASH_D:
        case URX_BACKSLASH_H:
        case URX_BACKSLASH_R:
        case URX_BACKSLASH_V:
        case URX_ONECHAR_I:
        case URX_BACKSLASH_X:   // Grahpeme Cluster.  Minimum is 1, max unbounded.
        case URX_DOTANY_ALL:    // . matches one or two.
        case URX_DOTANY:
        case URX_DOTANY_UNIX:
            currentLen = safeIncrement(currentLen, 1);
            break;


        case URX_JMPX:
            loc++;              // URX_JMPX has an extra operand, ignored here,
                                //   otherwise processed identically to URX_JMP.
            U_FALLTHROUGH;
        case URX_JMP:
            {
                int32_t  jmpDest = URX_VAL(op);
                if (jmpDest < loc) {
                    // Loop of some kind.  Can safely ignore, the worst that will happen
                    //  is that we understate the true minimum length
                    currentLen = forwardedLength.elementAti(loc+1);
                } else {
                    // Forward jump.  Propagate the current min length to the target loc of the jump.
                    U_ASSERT(jmpDest <= end+1);
                    if (forwardedLength.elementAti(jmpDest) > currentLen) {
                        forwardedLength.setElementAt(currentLen, jmpDest);
                    }
                }
            }
            break;

        case URX_BACKTRACK:
            {
                // Back-tracks are kind of like a branch, except that the min length was
                //   propagated already, by the state save.
                currentLen = forwardedLength.elementAti(loc+1);
            }
            break;


        case URX_STATE_SAVE:
            {
                // State Save, for forward jumps, propagate the current minimum.
                //             of the state save.
                int32_t  jmpDest = URX_VAL(op);
                if (jmpDest > loc) {
                    if (currentLen < forwardedLength.elementAti(jmpDest)) {
                        forwardedLength.setElementAt(currentLen, jmpDest);
                    }
                }
            }
            break;


        case URX_STRING:
            {
                loc++;
                int32_t stringLenOp = (int32_t)fRXPat->fCompiledPat->elementAti(loc);
                currentLen = safeIncrement(currentLen, URX_VAL(stringLenOp));
            }
            break;


        case URX_STRING_I:
            {
                loc++;
                // TODO: with full case folding, matching input text may be shorter than
                //       the string we have here.  More smarts could put some bounds on it.
                //       Assume a min length of one for now.  A min length of zero causes
                //        optimization failures for a pattern like "string"+
                // currentLen += URX_VAL(stringLenOp);
                currentLen = safeIncrement(currentLen, 1);
            }
            break;

        case URX_CTR_INIT:
        case URX_CTR_INIT_NG:
            {
                // Loop Init Ops.
                //   If the min loop count == 0
                //      move loc forwards to the end of the loop, skipping over the body.
                //   If the min count is > 0,
                //      continue normal processing of the body of the loop.
                int32_t loopEndLoc   = (int32_t)fRXPat->fCompiledPat->elementAti(loc+1);
                        loopEndLoc   = URX_VAL(loopEndLoc);
                int32_t minLoopCount = (int32_t)fRXPat->fCompiledPat->elementAti(loc+2);
                if (minLoopCount == 0) {
                    loc = loopEndLoc;
                } else {
                    loc+=3;  // Skips over operands of CTR_INIT
                }
            }
            break;


        case URX_CTR_LOOP:
        case URX_CTR_LOOP_NG:
            // Loop ops.
            //  The jump is conditional, backwards only.
            break;

        case URX_LOOP_SR_I:
        case URX_LOOP_DOT_I:
        case URX_LOOP_C:
            // More loop ops.  These state-save to themselves.
            //   don't change the minimum match - could match nothing at all.
            break;


        case URX_LA_START:
        case URX_LB_START:
            {
                // Look-around.  Scan forward until the matching look-ahead end,
                //   without processing the look-around block.  This is overly pessimistic for look-ahead,
                //   it assumes that the look-ahead match might be zero-length.
                //   TODO:  Positive lookahead could recursively do the block, then continue
                //          with the longer of the block or the value coming in.  Ticket 6060
                int32_t  depth = (opType == URX_LA_START? 2: 1);
                for (;;) {
                    loc++;
                    op = (int32_t)fRXPat->fCompiledPat->elementAti(loc);
                    if (URX_TYPE(op) == URX_LA_START) {
                        // The boilerplate for look-ahead includes two LA_END insturctions,
                        //    Depth will be decremented by each one when it is seen.
                        depth += 2;
                    }
                    if (URX_TYPE(op) == URX_LB_START) {
                        depth++;
                    }
                    if (URX_TYPE(op) == URX_LA_END) {
                        depth--;
                        if (depth == 0) {
                            break;
                        }
                    }
                    if (URX_TYPE(op)==URX_LBN_END) {
                        depth--;
                        if (depth == 0) {
                            break;
                        }
                    }
                    if (URX_TYPE(op) == URX_STATE_SAVE) {
                        // Need this because neg lookahead blocks will FAIL to outside
                        //   of the block.
                        int32_t  jmpDest = URX_VAL(op);
                        if (jmpDest > loc) {
                            if (currentLen < forwardedLength.elementAti(jmpDest)) {
                                forwardedLength.setElementAt(currentLen, jmpDest);
                            }
                        }
                    }
                    U_ASSERT(loc <= end);
                }
            }
            break;

        case URX_LA_END:
        case URX_LB_CONT:
        case URX_LB_END:
        case URX_LBN_CONT:
        case URX_LBN_END:
            // Only come here if the matching URX_LA_START or URX_LB_START was not in the
            //   range being sized, which happens when measuring size of look-behind blocks.
            break;

        default:
            UPRV_UNREACHABLE;
            }

        }

    // We have finished walking through the ops.  Check whether some forward jump
    //   propagated a shorter length to location end+1.
    if (forwardedLength.elementAti(end+1) < currentLen) {
        currentLen = forwardedLength.elementAti(end+1);
        U_ASSERT(currentLen>=0 && currentLen < INT32_MAX);
    }

    return currentLen;
}

//------------------------------------------------------------------------------
//
//   maxMatchLength    Calculate the length of the longest string that could
//                     match the specified pattern.
//                     Length is in 16 bit code units, not code points.
//
//                     The calculated length may not be exact.  The returned
//                     value may be longer than the actual maximum; it must
//                     never be shorter.
//
//------------------------------------------------------------------------------
int32_t   RegexCompile::maxMatchLength(int32_t start, int32_t end) {
    if (U_FAILURE(*fStatus)) {
        return 0;
    }
    U_ASSERT(start <= end);
    U_ASSERT(end < fRXPat->fCompiledPat->size());

    int32_t    loc;
    int32_t    op;
    int32_t    opType;
    int32_t    currentLen = 0;
    UVector32  forwardedLength(end+1, *fStatus);
    forwardedLength.setSize(end+1);

    for (loc=start; loc<=end; loc++) {
        forwardedLength.setElementAt(0, loc);
    }

    for (loc = start; loc<=end; loc++) {
        op = (int32_t)fRXPat->fCompiledPat->elementAti(loc);
        opType = URX_TYPE(op);

        // The loop is advancing linearly through the pattern.
        // If the op we are now at was the destination of a branch in the pattern,
        // and that path has a longer maximum length than the current accumulated value,
        // replace the current accumulated value.
        if (forwardedLength.elementAti(loc) > currentLen) {
            currentLen = forwardedLength.elementAti(loc);
        }

        switch (opType) {
            // Ops that don't change the total length matched
        case URX_RESERVED_OP:
        case URX_END:
        case URX_STRING_LEN:
        case URX_NOP:
        case URX_START_CAPTURE:
        case URX_END_CAPTURE:
        case URX_BACKSLASH_B:
        case URX_BACKSLASH_BU:
        case URX_BACKSLASH_G:
        case URX_BACKSLASH_Z:
        case URX_CARET:
        case URX_DOLLAR:
        case URX_DOLLAR_M:
        case URX_DOLLAR_D:
        case URX_DOLLAR_MD:
        case URX_RELOC_OPRND:
        case URX_STO_INP_LOC:
        case URX_CARET_M:
        case URX_CARET_M_UNIX:

        case URX_STO_SP:          // Setup for atomic or possessive blocks.  Doesn't change what can match.
        case URX_LD_SP:

        case URX_LB_END:
        case URX_LB_CONT:
        case URX_LBN_CONT:
        case URX_LBN_END:
            break;


            // Ops that increase that cause an unbounded increase in the length
            //   of a matched string, or that increase it a hard to characterize way.
            //   Call the max length unbounded, and stop further checking.
        case URX_BACKREF:         // BackRef.  Must assume that it might be a zero length match
        case URX_BACKREF_I:
        case URX_BACKSLASH_X:   // Grahpeme Cluster.  Minimum is 1, max unbounded.
            currentLen = INT32_MAX;
            break;


            // Ops that match a max of one character (possibly two 16 bit code units.)
            //
        case URX_STATIC_SETREF:
        case URX_STAT_SETREF_N:
        case URX_SETREF:
        case URX_BACKSLASH_D:
        case URX_BACKSLASH_H:
        case URX_BACKSLASH_R:
        case URX_BACKSLASH_V:
        case URX_ONECHAR_I:
        case URX_DOTANY_ALL:
        case URX_DOTANY:
        case URX_DOTANY_UNIX:
            currentLen = safeIncrement(currentLen, 2);
            break;

            // Single literal character.  Increase current max length by one or two,
            //       depending on whether the char is in the supplementary range.
        case URX_ONECHAR:
            currentLen = safeIncrement(currentLen, 1);
            if (URX_VAL(op) > 0x10000) {
                currentLen = safeIncrement(currentLen, 1);
            }
            break;

            // Jumps.
            //
        case URX_JMP:
        case URX_JMPX:
        case URX_JMP_SAV:
        case URX_JMP_SAV_X:
            {
                int32_t  jmpDest = URX_VAL(op);
                if (jmpDest < loc) {
                    // Loop of some kind.  Max match length is unbounded.
                    currentLen = INT32_MAX;
                } else {
                    // Forward jump.  Propagate the current min length to the target loc of the jump.
                    if (forwardedLength.elementAti(jmpDest) < currentLen) {
                        forwardedLength.setElementAt(currentLen, jmpDest);
                    }
                    currentLen = 0;
                }
            }
            break;

        case URX_BACKTRACK:
            // back-tracks are kind of like a branch, except that the max length was
            //   propagated already, by the state save.
            currentLen = forwardedLength.elementAti(loc+1);
            break;


        case URX_STATE_SAVE:
            {
                // State Save, for forward jumps, propagate the current minimum.
                //               of the state save.
                //             For backwards jumps, they create a loop, maximum
                //               match length is unbounded.
                int32_t  jmpDest = URX_VAL(op);
                if (jmpDest > loc) {
                    if (currentLen > forwardedLength.elementAti(jmpDest)) {
                        forwardedLength.setElementAt(currentLen, jmpDest);
                    }
                } else {
                    currentLen = INT32_MAX;
                }
            }
            break;




        case URX_STRING:
            {
                loc++;
                int32_t stringLenOp = (int32_t)fRXPat->fCompiledPat->elementAti(loc);
                currentLen = safeIncrement(currentLen, URX_VAL(stringLenOp));
                break;
            }

        case URX_STRING_I:
            // TODO:  This code assumes that any user string that matches will be no longer
            //        than our compiled string, with case insensitive matching.
            //        Our compiled string has been case-folded already.
            //
            //        Any matching user string will have no more code points than our
            //        compiled (folded) string.  Folding may add code points, but
            //        not remove them.
            //
            //        There is a potential problem if a supplemental code point
            //        case-folds to a BMP code point.  In this case our compiled string
            //        could be shorter (in code units) than a matching user string.
            //
            //        At this time (Unicode 6.1) there are no such characters, and this case
            //        is not being handled.  A test, intltest regex/Bug9283, will fail if
            //        any problematic characters are added to Unicode.
            //
            //        If this happens, we can make a set of the BMP chars that the
            //        troublesome supplementals fold to, scan our string, and bump the
            //        currentLen one extra for each that is found.
            //
            {
                loc++;
                int32_t stringLenOp = (int32_t)fRXPat->fCompiledPat->elementAti(loc);
                currentLen = safeIncrement(currentLen, URX_VAL(stringLenOp));
            }
            break;

        case URX_CTR_INIT:
        case URX_CTR_INIT_NG:
            // For Loops, recursively call this function on the pattern for the loop body,
            //   then multiply the result by the maximum loop count.
            {
                int32_t  loopEndLoc = URX_VAL(fRXPat->fCompiledPat->elementAti(loc+1));
                if (loopEndLoc == loc+4) {
                    // Loop has an empty body. No affect on max match length.
                    // Continue processing with code after the loop end.
                    loc = loopEndLoc;
                    break;
                }

                int32_t maxLoopCount = static_cast<int32_t>(fRXPat->fCompiledPat->elementAti(loc+3));
                if (maxLoopCount == -1) {
                    // Unbounded Loop. No upper bound on match length.
                    currentLen = INT32_MAX;
                    break;
                }

                U_ASSERT(loopEndLoc >= loc+4);
                int64_t blockLen = maxMatchLength(loc+4, loopEndLoc-1);  // Recursive call.
                int64_t updatedLen = (int64_t)currentLen + blockLen * maxLoopCount; 
                if (updatedLen >= INT32_MAX) {
                    currentLen = INT32_MAX;
                    break;
                }
                currentLen = (int32_t)updatedLen;
                loc = loopEndLoc;
                break;
            }

        case URX_CTR_LOOP:
        case URX_CTR_LOOP_NG:
            // These opcodes will be skipped over by code for URX_CTR_INIT.
            // We shouldn't encounter them here.
            UPRV_UNREACHABLE;

        case URX_LOOP_SR_I:
        case URX_LOOP_DOT_I:
        case URX_LOOP_C:
            // For anything to do with loops, make the match length unbounded.
            currentLen = INT32_MAX;
            break;



        case URX_LA_START:
        case URX_LA_END:
            // Look-ahead.  Just ignore, treat the look-ahead block as if
            // it were normal pattern.  Gives a too-long match length,
            //  but good enough for now.
            break;

            // End of look-ahead ops should always be consumed by the processing at
            //  the URX_LA_START op.
            // UPRV_UNREACHABLE;

        case URX_LB_START:
            {
                // Look-behind.  Scan forward until the matching look-around end,
                //   without processing the look-behind block.
                int32_t dataLoc = URX_VAL(op);
                for (loc = loc + 1; loc < end; ++loc) {
                    op = (int32_t)fRXPat->fCompiledPat->elementAti(loc);
                    int32_t opType = URX_TYPE(op);
                    if ((opType == URX_LA_END || opType == URX_LBN_END) && (URX_VAL(op) == dataLoc)) {
                        break;
                    }
                }
                U_ASSERT(loc < end);
            }
            break;

        default:
            UPRV_UNREACHABLE;
        }


        if (currentLen == INT32_MAX) {
            //  The maximum length is unbounded.
            //  Stop further processing of the pattern.
            break;
        }

    }
    return currentLen;

}


//------------------------------------------------------------------------------
//
//   stripNOPs    Remove any NOP operations from the compiled pattern code.
//                Extra NOPs are inserted for some constructs during the initial
//                code generation to provide locations that may be patched later.
//                Many end up unneeded, and are removed by this function.
//
//                In order to minimize the number of passes through the pattern,
//                back-reference fixup is also performed here (adjusting
//                back-reference operands to point to the correct frame offsets).
//
//------------------------------------------------------------------------------
void RegexCompile::stripNOPs() {

    if (U_FAILURE(*fStatus)) {
        return;
    }

    int32_t    end = fRXPat->fCompiledPat->size();
    UVector32  deltas(end, *fStatus);

    // Make a first pass over the code, computing the amount that things
    //   will be offset at each location in the original code.
    int32_t   loc;
    int32_t   d = 0;
    for (loc=0; loc<end; loc++) {
        deltas.addElement(d, *fStatus);
        int32_t op = (int32_t)fRXPat->fCompiledPat->elementAti(loc);
        if (URX_TYPE(op) == URX_NOP) {
            d++;
        }
    }

    UnicodeString caseStringBuffer;

    // Make a second pass over the code, removing the NOPs by moving following
    //  code up, and patching operands that refer to code locations that
    //  are being moved.  The array of offsets from the first step is used
    //  to compute the new operand values.
    int32_t src;
    int32_t dst = 0;
    for (src=0; src<end; src++) {
        int32_t op = (int32_t)fRXPat->fCompiledPat->elementAti(src);
        int32_t opType = URX_TYPE(op);
        switch (opType) {
        case URX_NOP:
            break;

        case URX_STATE_SAVE:
        case URX_JMP:
        case URX_CTR_LOOP:
        case URX_CTR_LOOP_NG:
        case URX_RELOC_OPRND:
        case URX_JMPX:
        case URX_JMP_SAV:
        case URX_JMP_SAV_X:
            // These are instructions with operands that refer to code locations.
            {
                int32_t  operandAddress = URX_VAL(op);
                U_ASSERT(operandAddress>=0 && operandAddress<deltas.size());
                int32_t fixedOperandAddress = operandAddress - deltas.elementAti(operandAddress);
                op = buildOp(opType, fixedOperandAddress);
                fRXPat->fCompiledPat->setElementAt(op, dst);
                dst++;
                break;
            }

        case URX_BACKREF:
        case URX_BACKREF_I:
            {
                int32_t where = URX_VAL(op);
                if (where > fRXPat->fGroupMap->size()) {
                    error(U_REGEX_INVALID_BACK_REF);
                    break;
                }
                where = fRXPat->fGroupMap->elementAti(where-1);
                op    = buildOp(opType, where);
                fRXPat->fCompiledPat->setElementAt(op, dst);
                dst++;

                fRXPat->fNeedsAltInput = TRUE;
                break;
            }
        case URX_RESERVED_OP:
        case URX_RESERVED_OP_N:
        case URX_BACKTRACK:
        case URX_END:
        case URX_ONECHAR:
        case URX_STRING:
        case URX_STRING_LEN:
        case URX_START_CAPTURE:
        case URX_END_CAPTURE:
        case URX_STATIC_SETREF:
        case URX_STAT_SETREF_N:
        case URX_SETREF:
        case URX_DOTANY:
        case URX_FAIL:
        case URX_BACKSLASH_B:
        case URX_BACKSLASH_BU:
        case URX_BACKSLASH_G:
        case URX_BACKSLASH_X:
        case URX_BACKSLASH_Z:
        case URX_DOTANY_ALL:
        case URX_BACKSLASH_D:
        case URX_CARET:
        case URX_DOLLAR:
        case URX_CTR_INIT:
        case URX_CTR_INIT_NG:
        case URX_DOTANY_UNIX:
        case URX_STO_SP:
        case URX_LD_SP:
        case URX_STO_INP_LOC:
        case URX_LA_START:
        case URX_LA_END:
        case URX_ONECHAR_I:
        case URX_STRING_I:
        case URX_DOLLAR_M:
        case URX_CARET_M:
        case URX_CARET_M_UNIX:
        case URX_LB_START:
        case URX_LB_CONT:
        case URX_LB_END:
        case URX_LBN_CONT:
        case URX_LBN_END:
        case URX_LOOP_SR_I:
        case URX_LOOP_DOT_I:
        case URX_LOOP_C:
        case URX_DOLLAR_D:
        case URX_DOLLAR_MD:
        case URX_BACKSLASH_H:
        case URX_BACKSLASH_R:
        case URX_BACKSLASH_V:
            // These instructions are unaltered by the relocation.
            fRXPat->fCompiledPat->setElementAt(op, dst);
            dst++;
            break;

        default:
            // Some op is unaccounted for.
            UPRV_UNREACHABLE;
        }
    }

    fRXPat->fCompiledPat->setSize(dst);
}




//------------------------------------------------------------------------------
//
//  Error         Report a rule parse error.
//                Only report it if no previous error has been recorded.
//
//------------------------------------------------------------------------------
void RegexCompile::error(UErrorCode e) {
    if (U_SUCCESS(*fStatus) || e == U_MEMORY_ALLOCATION_ERROR) {
        *fStatus = e;
        // Hmm. fParseErr (UParseError) line & offset fields are int32_t in public
        // API (see common/unicode/parseerr.h), while fLineNum and fCharNum are
        // int64_t. If the values of the latter are out of range for the former,
        // set them to the appropriate "field not supported" values.
        if (fLineNum > 0x7FFFFFFF) {
            fParseErr->line   = 0;
            fParseErr->offset = -1;
        } else if (fCharNum > 0x7FFFFFFF) {
            fParseErr->line   = (int32_t)fLineNum;
            fParseErr->offset = -1;
        } else {
            fParseErr->line   = (int32_t)fLineNum;
            fParseErr->offset = (int32_t)fCharNum;
        }

        UErrorCode status = U_ZERO_ERROR; // throwaway status for extracting context

        // Fill in the context.
        //   Note: extractBetween() pins supplied indicies to the string bounds.
        uprv_memset(fParseErr->preContext,  0, sizeof(fParseErr->preContext));
        uprv_memset(fParseErr->postContext, 0, sizeof(fParseErr->postContext));
        utext_extract(fRXPat->fPattern, fScanIndex-U_PARSE_CONTEXT_LEN+1, fScanIndex, fParseErr->preContext, U_PARSE_CONTEXT_LEN, &status);
        utext_extract(fRXPat->fPattern, fScanIndex, fScanIndex+U_PARSE_CONTEXT_LEN-1, fParseErr->postContext, U_PARSE_CONTEXT_LEN, &status);
    }
}


//
//  Assorted Unicode character constants.
//     Numeric because there is no portable way to enter them as literals.
//     (Think EBCDIC).
//
static const UChar      chCR        = 0x0d;      // New lines, for terminating comments.
static const UChar      chLF        = 0x0a;      // Line Feed
static const UChar      chPound     = 0x23;      // '#', introduces a comment.
static const UChar      chDigit0    = 0x30;      // '0'
static const UChar      chDigit7    = 0x37;      // '9'
static const UChar      chColon     = 0x3A;      // ':'
static const UChar      chE         = 0x45;      // 'E'
static const UChar      chQ         = 0x51;      // 'Q'
//static const UChar      chN         = 0x4E;      // 'N'
static const UChar      chP         = 0x50;      // 'P'
static const UChar      chBackSlash = 0x5c;      // '\'  introduces a char escape
//static const UChar      chLBracket  = 0x5b;      // '['
static const UChar      chRBracket  = 0x5d;      // ']'
static const UChar      chUp        = 0x5e;      // '^'
static const UChar      chLowerP    = 0x70;
static const UChar      chLBrace    = 0x7b;      // '{'
static const UChar      chRBrace    = 0x7d;      // '}'
static const UChar      chNEL       = 0x85;      //    NEL newline variant
static const UChar      chLS        = 0x2028;    //    Unicode Line Separator


//------------------------------------------------------------------------------
//
//  nextCharLL    Low Level Next Char from the regex pattern.
//                Get a char from the string, keep track of input position
//                     for error reporting.
//
//------------------------------------------------------------------------------
UChar32  RegexCompile::nextCharLL() {
    UChar32       ch;

    if (fPeekChar != -1) {
        ch = fPeekChar;
        fPeekChar = -1;
        return ch;
    }

    // assume we're already in the right place
    ch = UTEXT_NEXT32(fRXPat->fPattern);
    if (ch == U_SENTINEL) {
        return ch;
    }

    if (ch == chCR ||
        ch == chNEL ||
        ch == chLS   ||
        (ch == chLF && fLastChar != chCR)) {
        // Character is starting a new line.  Bump up the line number, and
        //  reset the column to 0.
        fLineNum++;
        fCharNum=0;
    }
    else {
        // Character is not starting a new line.  Except in the case of a
        //   LF following a CR, increment the column position.
        if (ch != chLF) {
            fCharNum++;
        }
    }
    fLastChar = ch;
    return ch;
}

//------------------------------------------------------------------------------
//
//   peekCharLL    Low Level Character Scanning, sneak a peek at the next
//                 character without actually getting it.
//
//------------------------------------------------------------------------------
UChar32  RegexCompile::peekCharLL() {
    if (fPeekChar == -1) {
        fPeekChar = nextCharLL();
    }
    return fPeekChar;
}


//------------------------------------------------------------------------------
//
//   nextChar     for pattern scanning.  At this level, we handle stripping
//                out comments and processing some backslash character escapes.
//                The rest of the pattern grammar is handled at the next level up.
//
//------------------------------------------------------------------------------
void RegexCompile::nextChar(RegexPatternChar &c) {
  tailRecursion:
    fScanIndex = UTEXT_GETNATIVEINDEX(fRXPat->fPattern);
    c.fChar    = nextCharLL();
    c.fQuoted  = FALSE;

    if (fQuoteMode) {
        c.fQuoted = TRUE;
        if ((c.fChar==chBackSlash && peekCharLL()==chE && ((fModeFlags & UREGEX_LITERAL) == 0)) ||
            c.fChar == (UChar32)-1) {
            fQuoteMode = FALSE;  //  Exit quote mode,
            nextCharLL();        // discard the E
            // nextChar(c);      // recurse to get the real next char
            goto tailRecursion;  // Note: fuzz testing produced testcases that
                                 //       resulted in stack overflow here.
        }
    }
    else if (fInBackslashQuote) {
        // The current character immediately follows a '\'
        // Don't check for any further escapes, just return it as-is.
        // Don't set c.fQuoted, because that would prevent the state machine from
        //    dispatching on the character.
        fInBackslashQuote = FALSE;
    }
    else
    {
        // We are not in a \Q quoted region \E of the source.
        //
        if (fModeFlags & UREGEX_COMMENTS) {
            //
            // We are in free-spacing and comments mode.
            //  Scan through any white space and comments, until we
            //  reach a significant character or the end of inut.
            for (;;) {
                if (c.fChar == (UChar32)-1) {
                    break;     // End of Input
                }
                if  (c.fChar == chPound && fEOLComments == TRUE) {
                    // Start of a comment.  Consume the rest of it, until EOF or a new line
                    for (;;) {
                        c.fChar = nextCharLL();
                        if (c.fChar == (UChar32)-1 ||  // EOF
                            c.fChar == chCR        ||
                            c.fChar == chLF        ||
                            c.fChar == chNEL       ||
                            c.fChar == chLS)       {
                            break;
                        }
                    }
                }
                // TODO:  check what Java & Perl do with non-ASCII white spaces.  Ticket 6061.
                if (PatternProps::isWhiteSpace(c.fChar) == FALSE) {
                    break;
                }
                c.fChar = nextCharLL();
            }
        }

        //
        //  check for backslash escaped characters.
        //
        if (c.fChar == chBackSlash) {
            int64_t pos = UTEXT_GETNATIVEINDEX(fRXPat->fPattern);
            if (RegexStaticSets::gStaticSets->fUnescapeCharSet.contains(peekCharLL())) {
                //
                // A '\' sequence that is handled by ICU's standard unescapeAt function.
                //   Includes \uxxxx, \n, \r, many others.
                //   Return the single equivalent character.
                //
                nextCharLL();                 // get & discard the peeked char.
                c.fQuoted = TRUE;

                if (UTEXT_FULL_TEXT_IN_CHUNK(fRXPat->fPattern, fPatternLength)) {
                    int32_t endIndex = (int32_t)pos;
                    c.fChar = u_unescapeAt(uregex_ucstr_unescape_charAt, &endIndex, (int32_t)fPatternLength, (void *)fRXPat->fPattern->chunkContents);

                    if (endIndex == pos) {
                        error(U_REGEX_BAD_ESCAPE_SEQUENCE);
                    }
                    fCharNum += endIndex - pos;
                    UTEXT_SETNATIVEINDEX(fRXPat->fPattern, endIndex);
                } else {
                    int32_t offset = 0;
                    struct URegexUTextUnescapeCharContext context = U_REGEX_UTEXT_UNESCAPE_CONTEXT(fRXPat->fPattern);

                    UTEXT_SETNATIVEINDEX(fRXPat->fPattern, pos);
                    c.fChar = u_unescapeAt(uregex_utext_unescape_charAt, &offset, INT32_MAX, &context);

                    if (offset == 0) {
                        error(U_REGEX_BAD_ESCAPE_SEQUENCE);
                    } else if (context.lastOffset == offset) {
                        UTEXT_PREVIOUS32(fRXPat->fPattern);
                    } else if (context.lastOffset != offset-1) {
                        utext_moveIndex32(fRXPat->fPattern, offset - context.lastOffset - 1);
                    }
                    fCharNum += offset;
                }
            }
            else if (peekCharLL() == chDigit0) {
                //  Octal Escape, using Java Regexp Conventions
                //    which are \0 followed by 1-3 octal digits.
                //    Different from ICU Unescape handling of Octal, which does not
                //    require the leading 0.
                //  Java also has the convention of only consuming 2 octal digits if
                //    the three digit number would be > 0xff
                //
                c.fChar = 0;
                nextCharLL();    // Consume the initial 0.
                int index;
                for (index=0; index<3; index++) {
                    int32_t ch = peekCharLL();
                    if (ch<chDigit0 || ch>chDigit7) {
                        if (index==0) {
                           // \0 is not followed by any octal digits.
                           error(U_REGEX_BAD_ESCAPE_SEQUENCE);
                        }
                        break;
                    }
                    c.fChar <<= 3;
                    c.fChar += ch&7;
                    if (c.fChar <= 255) {
                        nextCharLL();
                    } else {
                        // The last digit made the number too big.  Forget we saw it.
                        c.fChar >>= 3;
                    }
                }
                c.fQuoted = TRUE;
            }
            else if (peekCharLL() == chQ) {
                //  "\Q"  enter quote mode, which will continue until "\E"
                fQuoteMode = TRUE;
                nextCharLL();        // discard the 'Q'.
                // nextChar(c);      // recurse to get the real next char.
                goto tailRecursion;  // Note: fuzz testing produced test cases that
                //                            resulted in stack overflow here.
            }
            else
            {
                // We are in a '\' escape that will be handled by the state table scanner.
                // Just return the backslash, but remember that the following char is to
                //  be taken literally.
                fInBackslashQuote = TRUE;
            }
        }
    }

    // re-enable # to end-of-line comments, in case they were disabled.
    // They are disabled by the parser upon seeing '(?', but this lasts for
    //  the fetching of the next character only.
    fEOLComments = TRUE;

    // putc(c.fChar, stdout);
}



//------------------------------------------------------------------------------
//
//  scanNamedChar
//            Get a UChar32 from a \N{UNICODE CHARACTER NAME} in the pattern.
//
//             The scan position will be at the 'N'.  On return
//             the scan position should be just after the '}'
//
//             Return the UChar32
//
//------------------------------------------------------------------------------
UChar32  RegexCompile::scanNamedChar() {
    if (U_FAILURE(*fStatus)) {
        return 0;
    }

    nextChar(fC);
    if (fC.fChar != chLBrace) {
        error(U_REGEX_PROPERTY_SYNTAX);
        return 0;
    }

    UnicodeString  charName;
    for (;;) {
        nextChar(fC);
        if (fC.fChar == chRBrace) {
            break;
        }
        if (fC.fChar == -1) {
            error(U_REGEX_PROPERTY_SYNTAX);
            return 0;
        }
        charName.append(fC.fChar);
    }

    char name[100];
    if (!uprv_isInvariantUString(charName.getBuffer(), charName.length()) ||
         (uint32_t)charName.length()>=sizeof(name)) {
        // All Unicode character names have only invariant characters.
        // The API to get a character, given a name, accepts only char *, forcing us to convert,
        //   which requires this error check
        error(U_REGEX_PROPERTY_SYNTAX);
        return 0;
    }
    charName.extract(0, charName.length(), name, sizeof(name), US_INV);

    UChar32  theChar = u_charFromName(U_UNICODE_CHAR_NAME, name, fStatus);
    if (U_FAILURE(*fStatus)) {
        error(U_REGEX_PROPERTY_SYNTAX);
    }

    nextChar(fC);      // Continue overall regex pattern processing with char after the '}'
    return theChar;
}

//------------------------------------------------------------------------------
//
//  scanProp   Construct a UnicodeSet from the text at the current scan
//             position, which will be of the form \p{whaterver}
//
//             The scan position will be at the 'p' or 'P'.  On return
//             the scan position should be just after the '}'
//
//             Return a UnicodeSet, constructed from the \P pattern,
//             or NULL if the pattern is invalid.
//
//------------------------------------------------------------------------------
UnicodeSet *RegexCompile::scanProp() {
    UnicodeSet    *uset = NULL;

    if (U_FAILURE(*fStatus)) {
        return NULL;
    }
    (void)chLowerP;   // Suppress compiler unused variable warning.
    U_ASSERT(fC.fChar == chLowerP || fC.fChar == chP);
    UBool negated = (fC.fChar == chP);

    UnicodeString propertyName;
    nextChar(fC);
    if (fC.fChar != chLBrace) {
        error(U_REGEX_PROPERTY_SYNTAX);
        return NULL;
    }
    for (;;) {
        nextChar(fC);
        if (fC.fChar == chRBrace) {
            break;
        }
        if (fC.fChar == -1) {
            // Hit the end of the input string without finding the closing '}'
            error(U_REGEX_PROPERTY_SYNTAX);
            return NULL;
        }
        propertyName.append(fC.fChar);
    }
    uset = createSetForProperty(propertyName, negated);
    nextChar(fC);    // Move input scan to position following the closing '}'
    return uset;
}

//------------------------------------------------------------------------------
//
//  scanPosixProp   Construct a UnicodeSet from the text at the current scan
//             position, which is expected be of the form [:property expression:]
//
//             The scan position will be at the opening ':'.  On return
//             the scan position must be on the closing ']'
//
//             Return a UnicodeSet constructed from the pattern,
//             or NULL if this is not a valid POSIX-style set expression.
//             If not a property expression, restore the initial scan position
//                (to the opening ':')
//
//               Note:  the opening '[:' is not sufficient to guarantee that
//                      this is a [:property:] expression.
//                      [:'+=,] is a perfectly good ordinary set expression that
//                              happens to include ':' as one of its characters.
//
//------------------------------------------------------------------------------
UnicodeSet *RegexCompile::scanPosixProp() {
    UnicodeSet    *uset = NULL;

    if (U_FAILURE(*fStatus)) {
        return NULL;
    }

    U_ASSERT(fC.fChar == chColon);

    // Save the scanner state.
    // TODO:  move this into the scanner, with the state encapsulated in some way.  Ticket 6062
    int64_t     savedScanIndex        = fScanIndex;
    int64_t     savedNextIndex        = UTEXT_GETNATIVEINDEX(fRXPat->fPattern);
    UBool       savedQuoteMode        = fQuoteMode;
    UBool       savedInBackslashQuote = fInBackslashQuote;
    UBool       savedEOLComments      = fEOLComments;
    int64_t     savedLineNum          = fLineNum;
    int64_t     savedCharNum          = fCharNum;
    UChar32     savedLastChar         = fLastChar;
    UChar32     savedPeekChar         = fPeekChar;
    RegexPatternChar savedfC          = fC;

    // Scan for a closing ].   A little tricky because there are some perverse
    //   edge cases possible.  "[:abc\Qdef:] \E]"  is a valid non-property expression,
    //   ending on the second closing ].

    UnicodeString propName;
    UBool         negated  = FALSE;

    // Check for and consume the '^' in a negated POSIX property, e.g.  [:^Letter:]
    nextChar(fC);
    if (fC.fChar == chUp) {
       negated = TRUE;
       nextChar(fC);
    }

    // Scan for the closing ":]", collecting the property name along the way.
    UBool  sawPropSetTerminator = FALSE;
    for (;;) {
        propName.append(fC.fChar);
        nextChar(fC);
        if (fC.fQuoted || fC.fChar == -1) {
            // Escaped characters or end of input - either says this isn't a [:Property:]
            break;
        }
        if (fC.fChar == chColon) {
            nextChar(fC);
            if (fC.fChar == chRBracket) {
                sawPropSetTerminator = TRUE;
            }
            break;
        }
    }

    if (sawPropSetTerminator) {
        uset = createSetForProperty(propName, negated);
    }
    else
    {
        // No closing ":]".
        //  Restore the original scan position.
        //  The main scanner will retry the input as a normal set expression,
        //    not a [:Property:] expression.
        fScanIndex        = savedScanIndex;
        fQuoteMode        = savedQuoteMode;
        fInBackslashQuote = savedInBackslashQuote;
        fEOLComments      = savedEOLComments;
        fLineNum          = savedLineNum;
        fCharNum          = savedCharNum;
        fLastChar         = savedLastChar;
        fPeekChar         = savedPeekChar;
        fC                = savedfC;
        UTEXT_SETNATIVEINDEX(fRXPat->fPattern, savedNextIndex);
    }
    return uset;
}

static inline void addIdentifierIgnorable(UnicodeSet *set, UErrorCode& ec) {
    set->add(0, 8).add(0x0e, 0x1b).add(0x7f, 0x9f);
    addCategory(set, U_GC_CF_MASK, ec);
}

//
//  Create a Unicode Set from a Unicode Property expression.
//     This is common code underlying both \p{...} ane [:...:] expressions.
//     Includes trying the Java "properties" that aren't supported as
//     normal ICU UnicodeSet properties
//
UnicodeSet *RegexCompile::createSetForProperty(const UnicodeString &propName, UBool negated) {

    if (U_FAILURE(*fStatus)) {
        return nullptr;
    }
    LocalPointer<UnicodeSet> set;
    UErrorCode status = U_ZERO_ERROR;

    do {      // non-loop, exists to allow breaks from the block.
        //
        //  First try the property as we received it
        //
        UnicodeString   setExpr;
        uint32_t        usetFlags = 0;
        setExpr.append(u"[\\p{", -1);
        setExpr.append(propName);
        setExpr.append(u"}]", -1);
        if (fModeFlags & UREGEX_CASE_INSENSITIVE) {
            usetFlags |= USET_CASE_INSENSITIVE;
        }
        set.adoptInsteadAndCheckErrorCode(new UnicodeSet(setExpr, usetFlags, NULL, status), status);
        if (U_SUCCESS(status) || status == U_MEMORY_ALLOCATION_ERROR) {
            break;
        }

        //
        //  The incoming property wasn't directly recognized by ICU.

        //  Check [:word:] and [:all:]. These are not recognized as a properties by ICU UnicodeSet.
        //     Java accepts 'word' with mixed case.
        //     Java accepts 'all' only in all lower case.

        status = U_ZERO_ERROR;
        if (propName.caseCompare(u"word", -1, 0) == 0) {
            set.adoptInsteadAndCheckErrorCode(
                RegexStaticSets::gStaticSets->fPropSets[URX_ISWORD_SET].cloneAsThawed(), status);
            break;
        }
        if (propName.compare(u"all", -1) == 0) {
            set.adoptInsteadAndCheckErrorCode(new UnicodeSet(0, 0x10ffff), status);
            break;
        }


        //    Do Java InBlock expressions
        //
        UnicodeString mPropName = propName;
        if (mPropName.startsWith(u"In", 2) && mPropName.length() >= 3) {
            status = U_ZERO_ERROR;
            set.adoptInsteadAndCheckErrorCode(new UnicodeSet(), status);
            if (U_FAILURE(status)) {
                break;
            }
            UnicodeString blockName(mPropName, 2);  // Property with the leading "In" removed.
            set->applyPropertyAlias(UnicodeString(u"Block"), blockName, status);
            break;
        }

        //  Check for the Java form "IsBooleanPropertyValue", which we will recast
        //  as "BooleanPropertyValue". The property value can be either a
        //  a General Category or a Script Name.

        if (propName.startsWith(u"Is", 2) && propName.length()>=3) {
            mPropName.remove(0, 2);      // Strip the "Is"
            if (mPropName.indexOf(u'=') >= 0) {
                // Reject any "Is..." property expression containing an '=', that is,
                // any non-binary property expression.
                status = U_REGEX_PROPERTY_SYNTAX;
                break;
            }

            if (mPropName.caseCompare(u"assigned", -1, 0) == 0) {
                mPropName.setTo(u"unassigned", -1);
                negated = !negated;
            } else if (mPropName.caseCompare(u"TitleCase", -1, 0) == 0) {
                mPropName.setTo(u"Titlecase_Letter", -1);
            }

            mPropName.insert(0, u"[\\p{", -1);
            mPropName.append(u"}]", -1);
            set.adoptInsteadAndCheckErrorCode(new UnicodeSet(mPropName, *fStatus), status);

            if (U_SUCCESS(status) && !set->isEmpty() && (usetFlags & USET_CASE_INSENSITIVE)) {
                set->closeOver(USET_CASE_INSENSITIVE);
            }
            break;

        }

        if (propName.startsWith(u"java", -1)) {
            status = U_ZERO_ERROR;
            set.adoptInsteadAndCheckErrorCode(new UnicodeSet(), status);
            if (U_FAILURE(status)) {
                break;
            }
            //
            //  Try the various Java specific properties.
            //   These all begin with "java"
            //
            if (propName.compare(u"javaDefined", -1) == 0) {
                addCategory(set.getAlias(), U_GC_CN_MASK, status);
                set->complement();
            }
            else if (propName.compare(u"javaDigit", -1) == 0) {
                addCategory(set.getAlias(), U_GC_ND_MASK, status);
            }
            else if (propName.compare(u"javaIdentifierIgnorable", -1) == 0) {
                addIdentifierIgnorable(set.getAlias(), status);
            }
            else if (propName.compare(u"javaISOControl", -1) == 0) {
                set->add(0, 0x1F).add(0x7F, 0x9F);
            }
            else if (propName.compare(u"javaJavaIdentifierPart", -1) == 0) {
                addCategory(set.getAlias(), U_GC_L_MASK, status);
                addCategory(set.getAlias(), U_GC_SC_MASK, status);
                addCategory(set.getAlias(), U_GC_PC_MASK, status);
                addCategory(set.getAlias(), U_GC_ND_MASK, status);
                addCategory(set.getAlias(), U_GC_NL_MASK, status);
                addCategory(set.getAlias(), U_GC_MC_MASK, status);
                addCategory(set.getAlias(), U_GC_MN_MASK, status);
                addIdentifierIgnorable(set.getAlias(), status);
            }
            else if (propName.compare(u"javaJavaIdentifierStart", -1) == 0) {
                addCategory(set.getAlias(), U_GC_L_MASK, status);
                addCategory(set.getAlias(), U_GC_NL_MASK, status);
                addCategory(set.getAlias(), U_GC_SC_MASK, status);
                addCategory(set.getAlias(), U_GC_PC_MASK, status);
            }
            else if (propName.compare(u"javaLetter", -1) == 0) {
                addCategory(set.getAlias(), U_GC_L_MASK, status);
            }
            else if (propName.compare(u"javaLetterOrDigit", -1) == 0) {
                addCategory(set.getAlias(), U_GC_L_MASK, status);
                addCategory(set.getAlias(), U_GC_ND_MASK, status);
            }
            else if (propName.compare(u"javaLowerCase", -1) == 0) {
                addCategory(set.getAlias(), U_GC_LL_MASK, status);
            }
            else if (propName.compare(u"javaMirrored", -1) == 0) {
                set->applyIntPropertyValue(UCHAR_BIDI_MIRRORED, 1, status);
            }
            else if (propName.compare(u"javaSpaceChar", -1) == 0) {
                addCategory(set.getAlias(), U_GC_Z_MASK, status);
            }
            else if (propName.compare(u"javaSupplementaryCodePoint", -1) == 0) {
                set->add(0x10000, UnicodeSet::MAX_VALUE);
            }
            else if (propName.compare(u"javaTitleCase", -1) == 0) {
                addCategory(set.getAlias(), U_GC_LT_MASK, status);
            }
            else if (propName.compare(u"javaUnicodeIdentifierStart", -1) == 0) {
                addCategory(set.getAlias(), U_GC_L_MASK, status);
                addCategory(set.getAlias(), U_GC_NL_MASK, status);
            }
            else if (propName.compare(u"javaUnicodeIdentifierPart", -1) == 0) {
                addCategory(set.getAlias(), U_GC_L_MASK, status);
                addCategory(set.getAlias(), U_GC_PC_MASK, status);
                addCategory(set.getAlias(), U_GC_ND_MASK, status);
                addCategory(set.getAlias(), U_GC_NL_MASK, status);
                addCategory(set.getAlias(), U_GC_MC_MASK, status);
                addCategory(set.getAlias(), U_GC_MN_MASK, status);
                addIdentifierIgnorable(set.getAlias(), status);
            }
            else if (propName.compare(u"javaUpperCase", -1) == 0) {
                addCategory(set.getAlias(), U_GC_LU_MASK, status);
            }
            else if (propName.compare(u"javaValidCodePoint", -1) == 0) {
                set->add(0, UnicodeSet::MAX_VALUE);
            }
            else if (propName.compare(u"javaWhitespace", -1) == 0) {
                addCategory(set.getAlias(), U_GC_Z_MASK, status);
                set->removeAll(UnicodeSet().add(0xa0).add(0x2007).add(0x202f));
                set->add(9, 0x0d).add(0x1c, 0x1f);
            } else {
                status = U_REGEX_PROPERTY_SYNTAX;
            }

            if (U_SUCCESS(status) && !set->isEmpty() && (usetFlags & USET_CASE_INSENSITIVE)) {
                set->closeOver(USET_CASE_INSENSITIVE);
            }
            break;
        }

        // Unrecognized property. ICU didn't like it as it was, and none of the Java compatibility
        // extensions matched it.
        status = U_REGEX_PROPERTY_SYNTAX;
    } while (false);   // End of do loop block. Code above breaks out of the block on success or hard failure.

    if (U_SUCCESS(status)) {
        U_ASSERT(set.isValid());
        if (negated) {
            set->complement();
        }
        return set.orphan();
    } else {
        if (status == U_ILLEGAL_ARGUMENT_ERROR) {
            status = U_REGEX_PROPERTY_SYNTAX;
        }
        error(status);
        return nullptr;
    }
}


//
//  SetEval   Part of the evaluation of [set expressions].
//            Perform any pending (stacked) operations with precedence
//            equal or greater to that of the next operator encountered
//            in the expression.
//
void RegexCompile::setEval(int32_t nextOp) {
    UnicodeSet *rightOperand = NULL;
    UnicodeSet *leftOperand  = NULL;
    for (;;) {
        U_ASSERT(fSetOpStack.empty()==FALSE);
        int32_t pendingSetOperation = fSetOpStack.peeki();
        if ((pendingSetOperation&0xffff0000) < (nextOp&0xffff0000)) {
            break;
        }
        fSetOpStack.popi();
        U_ASSERT(fSetStack.empty() == FALSE);
        rightOperand = (UnicodeSet *)fSetStack.peek();
        switch (pendingSetOperation) {
            case setNegation:
                rightOperand->complement();
                break;
            case setCaseClose:
                // TODO: need a simple close function.  Ticket 6065
                rightOperand->closeOver(USET_CASE_INSENSITIVE);
                rightOperand->removeAllStrings();
                break;
            case setDifference1:
            case setDifference2:
                fSetStack.pop();
                leftOperand = (UnicodeSet *)fSetStack.peek();
                leftOperand->removeAll(*rightOperand);
                delete rightOperand;
                break;
            case setIntersection1:
            case setIntersection2:
                fSetStack.pop();
                leftOperand = (UnicodeSet *)fSetStack.peek();
                leftOperand->retainAll(*rightOperand);
                delete rightOperand;
                break;
            case setUnion:
                fSetStack.pop();
                leftOperand = (UnicodeSet *)fSetStack.peek();
                leftOperand->addAll(*rightOperand);
                delete rightOperand;
                break;
            default:
                UPRV_UNREACHABLE;
            }
        }
    }

void RegexCompile::setPushOp(int32_t op) {
    setEval(op);
    fSetOpStack.push(op, *fStatus);
    fSetStack.push(new UnicodeSet(), *fStatus);
}

U_NAMESPACE_END
#endif  // !UCONFIG_NO_REGULAR_EXPRESSIONS

