
//
//  file:  regexcmp.cpp
//
//  Copyright (C) 2002-2003 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/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 "uprops.h"
#include "cmemory.h"
#include "cstring.h"
#include "uvectr32.h"
#include "uassert.h"
#include "ucln_in.h"
#include "mutex.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"



U_NAMESPACE_BEGIN





//----------------------------------------------------------------------------------------
//
//  Constructor.
//
//----------------------------------------------------------------------------------------
RegexCompile::RegexCompile(RegexPattern *rxp, UErrorCode &status) : fParenStack(status)
{
    fStatus           = &status;

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

    fMatchOpenParen   = -1;
    fMatchCloseParen  = -1;
    fStringOpStart    = -1;

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



//----------------------------------------------------------------------------------------
//
//  Destructor
//
//----------------------------------------------------------------------------------------
RegexCompile::~RegexCompile() {
}



//----------------------------------------------------------------------------------------
//
//   cleanup.    Called (indirectly) by u_cleanup to free all cached memory
//
//----------------------------------------------------------------------------------------
void RegexCompile::cleanup() {
    delete RegexStaticSets::gStaticSets;
    RegexStaticSets::gStaticSets = NULL;
}


//---------------------------------------------------------------------------------
//
//  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
{
    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.length() == 0);

    // Prepare the RegexPattern object to receive the compiled pattern.
    //   TODO:  remove per-instance field, and just use globals directly.  (But check perf)
    fRXPat->fPattern        = pat;
    fRXPat->fStaticSets     = RegexStaticSets::gStaticSets->fPropSets;
    fRXPat->fStaticSets8    = RegexStaticSets::gStaticSets->fPropSets8;


    // Initialize the pattern scanning state machine
    fPatternLength = pat.length();
    uint16_t                state = 1;
    const RegexTableEl      *tableEl;
    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
                UnicodeSet *uniset = RegexStaticSets::gStaticSets->fRuleSets[tableEl->fCharClass-128];
                if (uniset->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((EParseAction)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);
            }
        }

    }

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

    // Back-reference fixup
    //
    int32_t loc;
    for (loc=0; loc<fRXPat->fCompiledPat->size(); loc++) {
        int32_t op = fRXPat->fCompiledPat->elementAti(loc);
        int32_t opType = URX_TYPE(op);
        if (opType == URX_BACKREF || opType == 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    = URX_BUILD(opType, where);
            fRXPat->fCompiledPat->setElementAt(op, loc);
        }
    }


    //
    // Compute the number of digits requried for the largest capture group number.
    //
    fRXPat->fMaxCaptureDigits = 1;
    int32_t  n = 10;
    for (;;) {
        if (n > fRXPat->fGroupMap->size()) {
            break;
        }
        fRXPat->fMaxCaptureDigits++;
        n *= 10;
    }

    //
    // 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 and the
    //   position in the compiled pattern.
    //
    fRXPat->fFrameSize+=2;

    //
    // 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 passes
    //  
    matchStartType();  
    OptDotStar();
    stripNOPs();

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

    //
    // A stupid bit of non-sense to prevent code coverage testing from complaining
    //   about the pattern.dump() debug function.  Go through the motions of dumping,
    //   even though, without the #define set, it will do nothing.
    //
#ifndef REGEX_DUMP_DEBUG
    static UBool phonyDumpDone = FALSE;
    if (phonyDumpDone==FALSE) {
        fRXPat->dump();
        phonyDumpDone = TRUE;
    }
#endif

}





//----------------------------------------------------------------------------------------
//
//  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(EParseAction 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
        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_STATE_SAVE, 2), *fStatus);
        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_JMP,  3), *fStatus);
        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_FAIL, 0), *fStatus);
        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP,  0), *fStatus);
        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP,  0), *fStatus);

        fParenStack.push(-1, *fStatus);     // Begin a Paren Stack Frame
        fParenStack.push( 3, *fStatus);     // Push location of first NOP
        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.
        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_END, 0), *fStatus);

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



    case doOrOperator:
        // Scanning a '|', as in (A|B)
        {
            // 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 = fRXPat->fCompiledPat->elementAti(savePosition);
            U_ASSERT(URX_TYPE(op) == URX_NOP);  // original contents of reserved location
            op = URX_BUILD(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.
            op = URX_BUILD(URX_JMP, 0);
            fRXPat->fCompiledPat->addElement(op, *fStatus);

            // 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.
            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);
            fParenStack.push(fRXPat->fCompiledPat->size()-1, *fStatus);
        }
        break;


    case doOpenCaptureParen:
        // Open Paren.
        //   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   positino.
        //         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_CAPure is encountered.
        {
            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);
            int32_t  varsLoc    = fRXPat->fFrameSize;    // Reserve three slots in match stack frame.
            fRXPat->fFrameSize += 3;
            int32_t  cop        = URX_BUILD(URX_START_CAPTURE, varsLoc);
            fRXPat->fCompiledPat->addElement(cop, *fStatus);
            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);

            // 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);
        }
         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.
        {
            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);
            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);

            // 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.
        {
            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);
            int32_t  varLoc    = fRXPat->fDataSize;    // Reserve a data location for saving the
            fRXPat->fDataSize += 1;                    //  state stack ptr.
            int32_t  stoOp     = URX_BUILD(URX_STO_SP, varLoc);
            fRXPat->fCompiledPat->addElement(stoOp, *fStatus);
            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);

            // 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  )
        // Compiles to
        //    1    START_LA     dataLoc
        //    2.   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.
        //    3.   NOP              may be replaced if there is are '|' ops in the block.
        //    4.     code for parenthesized stuff.
        //    5.   ENDLA
        //     
        //  Two data slots are reserved, for saving the stack ptr and the input position.
        {
            int32_t dataLoc = fRXPat->fDataSize;
            fRXPat->fDataSize += 2; 
            int32_t op = URX_BUILD(URX_LA_START, dataLoc);
            fRXPat->fCompiledPat->addElement(op, *fStatus);

            op = URX_BUILD(URX_NOP, 0);
            fRXPat->fCompiledPat->addElement(op, *fStatus);
            fRXPat->fCompiledPat->addElement(op, *fStatus);

            // 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.    START_LA    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.    END_LA                // Cut back stack, remove saved state from step 2.
        //    6.    FAIL                  // code in block succeeded, so neg. lookahead fails.
        //    7.    ...
        {
            int32_t dataLoc = fRXPat->fDataSize;
            fRXPat->fDataSize += 2; 
            int32_t op = URX_BUILD(URX_LA_START, dataLoc);
            fRXPat->fCompiledPat->addElement(op, *fStatus);

            op = URX_BUILD(URX_STATE_SAVE, 0);    // dest address will be patched later.
            fRXPat->fCompiledPat->addElement(op, *fStatus);

            op = URX_BUILD(URX_NOP, 0);
            fRXPat->fCompiledPat->addElement(op, *fStatus);

            // 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 and #6 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:    Start index of match current match attempt.
            //              3:    Original Input String len.  

            // Allocate data space
            int32_t dataLoc = fRXPat->fDataSize;
            fRXPat->fDataSize += 4; 
            
            // Emit URX_LB_START
            int32_t op = URX_BUILD(URX_LB_START, dataLoc);
            fRXPat->fCompiledPat->addElement(op, *fStatus);
            
            // Emit URX_LB_CONT
            op = URX_BUILD(URX_LB_CONT, dataLoc);
            fRXPat->fCompiledPat->addElement(op, *fStatus);
            fRXPat->fCompiledPat->addElement(0,  *fStatus);    // MinMatchLength.  To be filled later.
            fRXPat->fCompiledPat->addElement(0,  *fStatus);    // MaxMatchLength.  To be filled later.
            
            // Emit the NOP
            op = URX_BUILD(URX_NOP, 0);
            fRXPat->fCompiledPat->addElement(op, *fStatus);
            fRXPat->fCompiledPat->addElement(op, *fStatus);
            
            // 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:    Start index of match current match attempt.
            //              3:    Original Input String len.  

            // Allocate data space
            int32_t dataLoc = fRXPat->fDataSize;
            fRXPat->fDataSize += 4; 
            
            // Emit URX_LB_START
            int32_t op = URX_BUILD(URX_LB_START, dataLoc);
            fRXPat->fCompiledPat->addElement(op, *fStatus);
            
            // Emit URX_LBN_CONT
            op = URX_BUILD(URX_LBN_CONT, dataLoc);
            fRXPat->fCompiledPat->addElement(op, *fStatus);
            fRXPat->fCompiledPat->addElement(0,  *fStatus);    // MinMatchLength.  To be filled later.
            fRXPat->fCompiledPat->addElement(0,  *fStatus);    // MaxMatchLength.  To be filled later.
            fRXPat->fCompiledPat->addElement(0,  *fStatus);    // Continue Loc.    To be filled later.
            
            // Emit the NOP
            op = URX_BUILD(URX_NOP, 0);
            fRXPat->fCompiledPat->addElement(op, *fStatus);
            fRXPat->fCompiledPat->addElement(op, *fStatus);
            
            // 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 = fRXPat->fCompiledPat->elementAti(topLoc);

                if (URX_TYPE(repeatedOp) == URX_SETREF) {
                    // Emit optimized code for [char set]+
                    int32_t loopOpI = URX_BUILD(URX_LOOP_SR_I, URX_VAL(repeatedOp));
                    fRXPat->fCompiledPat->addElement(loopOpI, *fStatus);
                    frameLoc = fRXPat->fFrameSize;
                    fRXPat->fFrameSize++;
                    int32_t loopOpC = URX_BUILD(URX_LOOP_C, frameLoc);
                    fRXPat->fCompiledPat->addElement(loopOpC, *fStatus);
                    break;
                }

                if (URX_TYPE(repeatedOp) == URX_DOTANY ||
                    URX_TYPE(repeatedOp) == URX_DOTANY_ALL) {
                    // Emit Optimized code for .+ operations.
                    int32_t loopOpI = URX_BUILD(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;
                    }
                    fRXPat->fCompiledPat->addElement(loopOpI, *fStatus);
                    frameLoc = fRXPat->fFrameSize;
                    fRXPat->fFrameSize++;
                    int32_t loopOpC = URX_BUILD(URX_LOOP_C, frameLoc);
                    fRXPat->fCompiledPat->addElement(loopOpC, *fStatus);
                    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 =  fRXPat->fFrameSize;
                fRXPat->fFrameSize++;

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

                op = URX_BUILD(URX_JMP_SAV_X, topLoc+1);
                fRXPat->fCompiledPat->addElement(op, *fStatus);
            } else {
                // Simpler code when the repeated body must match something non-empty
                int32_t  jmpOp  = URX_BUILD(URX_JMP_SAV, topLoc);
                fRXPat->fCompiledPat->addElement(jmpOp, *fStatus);
            }
        }
        break;

    case doNGPlus:
        //  Non-greedy '+?'  compiles to
        //     1.   stuff to be repeated  (already built)
        //     2.   state-save  1
        //     3.   ...
        {
            int32_t topLoc      = blockTopLoc(FALSE);
            int32_t saveStateOp = URX_BUILD(URX_STATE_SAVE, topLoc);
            fRXPat->fCompiledPat->addElement(saveStateOp, *fStatus);
        }
        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  = URX_BUILD(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  = URX_BUILD(URX_JMP, jmp2_loc+1);
            fRXPat->fCompiledPat->setElementAt(jmp1_op, jmp1_loc);

            int32_t  jmp2_op  = URX_BUILD(URX_JMP, jmp2_loc+2);
            fRXPat->fCompiledPat->addElement(jmp2_op, *fStatus);

            int32_t  save_op  = URX_BUILD(URX_STATE_SAVE, jmp1_loc+1);
            fRXPat->fCompiledPat->addElement(save_op, *fStatus);
        }
        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 = fRXPat->fCompiledPat->elementAti(topLoc);

                if (URX_TYPE(repeatedOp) == URX_SETREF) {
                    // Emit optimized code for a [char set]* 
                    int32_t loopOpI = URX_BUILD(URX_LOOP_SR_I, URX_VAL(repeatedOp));
                    fRXPat->fCompiledPat->setElementAt(loopOpI, topLoc);
                    dataLoc = fRXPat->fFrameSize;
                    fRXPat->fFrameSize++;
                    int32_t loopOpC = URX_BUILD(URX_LOOP_C, dataLoc);
                    fRXPat->fCompiledPat->addElement(loopOpC, *fStatus);
                    break;
                }

                if (URX_TYPE(repeatedOp) == URX_DOTANY ||
                    URX_TYPE(repeatedOp) == URX_DOTANY_ALL) {
                    // Emit Optimized code for .* operations.
                    int32_t loopOpI = URX_BUILD(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;
                    }
                    fRXPat->fCompiledPat->setElementAt(loopOpI, topLoc);
                    dataLoc = fRXPat->fFrameSize;
                    fRXPat->fFrameSize++;
                    int32_t loopOpC = URX_BUILD(URX_LOOP_C, dataLoc);
                    fRXPat->fCompiledPat->addElement(loopOpC, *fStatus);
                    break;
                }
            }

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

            int32_t   saveStateLoc = blockTopLoc(TRUE);
            int32_t   jmpOp        = URX_BUILD(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 =  fRXPat->fFrameSize;
                fRXPat->fFrameSize++;

                int32_t op = URX_BUILD(URX_STO_INP_LOC, dataLoc);
                fRXPat->fCompiledPat->setElementAt(op, saveStateLoc+1);
                jmpOp      = URX_BUILD(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 store it into the compiled code.
            int32_t saveStateOp = URX_BUILD(URX_STATE_SAVE, continueLoc);
            fRXPat->fCompiledPat->setElementAt(saveStateOp, saveStateLoc);

            // Append the URX_JMP_SAV or URX_JMPX operation to the compiled pattern.
            fRXPat->fCompiledPat->addElement(jmpOp, *fStatus);
        }
        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   = URX_BUILD(URX_JMP, saveLoc);
            int32_t     stateSaveOp = URX_BUILD(URX_STATE_SAVE, jmpLoc+1);
            fRXPat->fCompiledPat->setElementAt(jmpOp, jmpLoc);
            fRXPat->fCompiledPat->addElement(stateSaveOp, *fStatus);
        }
        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);
            fIntervalLow = fIntervalLow*10 + digitValue;
            if (fIntervalLow < 0) {
                error(U_REGEX_NUMBER_TOO_BIG);
            }
        }
        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);
            fIntervalUpper = fIntervalUpper*10 + digitValue;
            if (fIntervalLow < 0) {
                error(U_REGEX_NUMBER_TOO_BIG);
            }
        }
        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, becuase 
            //    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    = fRXPat->fDataSize;    // Reserve a data location for saving the
            fRXPat->fDataSize += 1;                    //  state stack ptr.
            int32_t  op        = URX_BUILD(URX_STO_SP, varLoc);
            fRXPat->fCompiledPat->setElementAt(op, topLoc);

            int32_t loopOp = 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
            op = URX_BUILD(URX_LD_SP, varLoc);
            fRXPat->fCompiledPat->addElement(op, *fStatus);
        }

        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 doDotAny:
        // scanned a ".",  match any single character.
        {
            int32_t   op;
            if (fModeFlags & UREGEX_DOTALL) {
                op = URX_BUILD(URX_DOTANY_ALL, 0);
            } else {
                op = URX_BUILD(URX_DOTANY, 0);
            }
            fRXPat->fCompiledPat->addElement(op, *fStatus);
        }
        break;

    case doCaret: 
        {
            int32_t op = (fModeFlags & UREGEX_MULTILINE)? URX_CARET_M : URX_CARET;
            fRXPat->fCompiledPat->addElement(URX_BUILD(op, 0), *fStatus);
        }
        break;


    case doDollar:  
        {
            int32_t op = (fModeFlags & UREGEX_MULTILINE)? URX_DOLLAR_M : URX_DOLLAR;
            fRXPat->fCompiledPat->addElement(URX_BUILD(op, 0), *fStatus);
        }
        break;

    case doBackslashA:
        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_CARET, 0), *fStatus);
        break;

    case doBackslashB:
        {
            int32_t op = (fModeFlags & UREGEX_UWORD)? URX_BACKSLASH_BU : URX_BACKSLASH_B;
            fRXPat->fCompiledPat->addElement(URX_BUILD(op, 1), *fStatus);
        }
        break;

    case doBackslashb:
        {
            int32_t op = (fModeFlags & UREGEX_UWORD)? URX_BACKSLASH_BU : URX_BACKSLASH_B;
            fRXPat->fCompiledPat->addElement(URX_BUILD(op, 0), *fStatus);
        }
        break;

    case doBackslashD:
        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_D, 1), *fStatus);
        break;

    case doBackslashd:
        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_D, 0), *fStatus);
        break;

    case doBackslashG:
        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_G, 0), *fStatus);
        break;

    case doBackslashS:
        fRXPat->fCompiledPat->addElement(
            URX_BUILD(URX_STAT_SETREF_N, URX_ISSPACE_SET), *fStatus);
        break;

    case doBackslashs:
        fRXPat->fCompiledPat->addElement(
            URX_BUILD(URX_STATIC_SETREF, URX_ISSPACE_SET), *fStatus);
        break;

    case doBackslashW:
        fRXPat->fCompiledPat->addElement(
            URX_BUILD(URX_STAT_SETREF_N, URX_ISWORD_SET), *fStatus);
        break;

    case doBackslashw:
        fRXPat->fCompiledPat->addElement(
            URX_BUILD(URX_STATIC_SETREF, URX_ISWORD_SET), *fStatus);
        break;

    case doBackslashX:
        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_X, 0), *fStatus);
        break;


    case doBackslashZ:
        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_DOLLAR, 0), *fStatus);
        break;

    case doBackslashz:
        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_Z, 0), *fStatus);
        break;

    case doEscapeError:
        error(U_REGEX_BAD_ESCAPE_SEQUENCE);
        break;

    case doExit:
        returnVal = FALSE;
        break;

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


    case doScanUnicodeSet:
        {
            UnicodeSet *theSet = scanSet();
            compileSet(theSet);
        }
        break;

    case doEnterQuoteMode:
        // Just scanned a \Q.  Put character scanner into quote mode.
        fQuoteMode = TRUE;
        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->fRuleDigits->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);
            int32_t  op;
            if (fModeFlags & UREGEX_CASE_INSENSITIVE) {
                op = URX_BUILD(URX_BACKREF_I, groupNum);
            } else {
                op = URX_BUILD(URX_BACKREF, groupNum);
            }
            fRXPat->fCompiledPat->addElement(op, *fStatus);
        }
        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
        //
        {
            // Emit the STO_SP
            int32_t   topLoc = blockTopLoc(TRUE);
            int32_t   stoLoc = fRXPat->fDataSize;
            fRXPat->fDataSize++;       // Reserve the data location for storing save stack ptr.
            int32_t   op     = URX_BUILD(URX_STO_SP, stoLoc);
            fRXPat->fCompiledPat->setElementAt(op, topLoc);

            // Emit the STATE_SAVE
            op = URX_BUILD(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+2);
            fRXPat->fCompiledPat->addElement(op, *fStatus);
            
            // Emit the JMP
            op = URX_BUILD(URX_JMP, topLoc+1);
            fRXPat->fCompiledPat->addElement(op, *fStatus);

            // Emit the LD_SP
            op = URX_BUILD(URX_LD_SP, stoLoc);
            fRXPat->fCompiledPat->addElement(op, *fStatus);
        }
        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 = fRXPat->fDataSize;
            fRXPat->fDataSize++;       // Reserve the data location for storing save stack ptr.
            int32_t   op     = URX_BUILD(URX_STO_SP, stoLoc);
            fRXPat->fCompiledPat->setElementAt(op, topLoc);

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

            // Append the JMP operation. 
            op = URX_BUILD(URX_JMP, topLoc+1);
            fRXPat->fCompiledPat->addElement(op, *fStatus);

            // Emit the LD_SP       loc
            op = URX_BUILD(URX_LD_SP, stoLoc);
            fRXPat->fCompiledPat->addElement(op, *fStatus);
        }
        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 = fRXPat->fDataSize;
            fRXPat->fDataSize++;       // Reserve the data location for storing save stack ptr.
            int32_t   op     = URX_BUILD(URX_STO_SP, stoLoc);
            fRXPat->fCompiledPat->setElementAt(op, topLoc);

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

            // Emit the LD_SP
            op = URX_BUILD(URX_LD_SP, stoLoc);
            fRXPat->fCompiledPat->addElement(op, *fStatus);
        }
        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 0x6d: /* 'm' */   bit = UREGEX_MULTILINE;        break;
            case 0x73: /* 's' */   bit = UREGEX_DOTALL;           break;
            case 0x77: /* 'w' */   bit = UREGEX_UWORD;            break;
            case 0x78: /* 'x' */   bit = UREGEX_COMMENTS;         break;
            case 0x2d: /* '-' */   fSetModeFlag = FALSE;          break;
            default:
                U_ASSERT(FALSE);   // Should never happen.  Other chars are filtered out
                                   // by the scanner.
            }
            if (fSetModeFlag) {
                fNewModeFlags |= bit;
            } else {
                fNewModeFlags &= ~bit;
            }
        }
        break;

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

        // Prevent any string from spanning across the change of match mode.
        //   Otherwise the pattern "abc(?i)def" would make a single string of "abcdef" 
        fixLiterals();     
        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.
        {
            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);
            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);

            // 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.
            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;



    default:
        U_ASSERT(FALSE);
        error(U_REGEX_INTERNAL_ERROR);
        break;
    }

    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.
//                         If we are in a pattern string already, add the new char to it.
//                         If we aren't in a pattern string, begin one now.
//
//------------------------------------------------------------------------------
void RegexCompile::literalChar(UChar32 c)  {
    int32_t           op;            // An operation in the compiled pattern.
    int32_t           opType;
    int32_t           patternLoc;   // A position in the compiled pattern.
    int32_t           stringLen;


    // If the last thing compiled into the pattern was not a literal char,
    //   force this new literal char to begin a new string, and not append to the previous.
    op     = fRXPat->fCompiledPat->lastElementi();
    opType = URX_TYPE(op);
    if (!(opType == URX_STRING_LEN || opType == URX_ONECHAR || opType == URX_ONECHAR_I)) {
        fixLiterals();
    }

    if (fStringOpStart == -1) {
        // First char of a string in the pattern.
        // Emit a OneChar op into the compiled pattern.
        emitONE_CHAR(c);

        // Also add it to the string pool, in case we get a second adjacent literal
        //   and want to change form ONE_CHAR to STRING
        fStringOpStart = fRXPat->fLiteralText.length();
        fRXPat->fLiteralText.append(c);
        return;
    }
    
    // We are adding onto an existing string
    fRXPat->fLiteralText.append(c);

    op     = fRXPat->fCompiledPat->lastElementi();
    opType = URX_TYPE(op);
    U_ASSERT(opType == URX_ONECHAR || opType == URX_ONECHAR_I || opType == URX_STRING_LEN);

    // If the most recently emitted op is a URX_ONECHAR, 
    if (opType == URX_ONECHAR || opType == URX_ONECHAR_I) {
        if (U16_IS_TRAIL(c) && U16_IS_LEAD(URX_VAL(op))) {
            // The most recently emitted op is a ONECHAR that was the first half
            //   of a surrogate pair.  Update the ONECHAR's operand to be the
            //   supplementary code point resulting from both halves of the pair.
            c = U16_GET_SUPPLEMENTARY(URX_VAL(op), c);
            op = URX_BUILD(opType, c);
            patternLoc = fRXPat->fCompiledPat->size() - 1;
            fRXPat->fCompiledPat->setElementAt(op, patternLoc);
            return;
        }
        
        // The most recently emitted op is a ONECHAR.
        //  We've now received another adjacent char.  Change the ONECHAR op
        //   to a string op.
        if (fModeFlags & UREGEX_CASE_INSENSITIVE) {
            op     = URX_BUILD(URX_STRING_I, fStringOpStart);
        } else {
            op     = URX_BUILD(URX_STRING, fStringOpStart);
        }
        patternLoc = fRXPat->fCompiledPat->size() - 1;
        fRXPat->fCompiledPat->setElementAt(op, patternLoc);
        op         = URX_BUILD(URX_STRING_LEN, 0);
        fRXPat->fCompiledPat->addElement(op, *fStatus);
    }
    
    // The pattern contains a URX_SRING / URX_STRING_LEN.  Update the
    //  string length to reflect the new char we just added to the string.
    stringLen  = fRXPat->fLiteralText.length() - fStringOpStart;
    op         = URX_BUILD(URX_STRING_LEN, stringLen);
    patternLoc = fRXPat->fCompiledPat->size() - 1;
    fRXPat->fCompiledPat->setElementAt(op, patternLoc);
}



//------------------------------------------------------------------------------
//
//    emitONE_CHAR         emit a ONE_CHAR op into the generated code.
//                         Choose cased or uncased version, depending on the
//                         match mode and whether the character itself is cased.
//
//------------------------------------------------------------------------------
void RegexCompile::emitONE_CHAR(UChar32  c) {
    int32_t op;
    if ((fModeFlags & UREGEX_CASE_INSENSITIVE) &&
        u_hasBinaryProperty(c, UCHAR_CASE_SENSITIVE)) {
        // We have a cased character, and are in case insensitive matching mode.
        c  = u_foldCase(c, U_FOLD_CASE_DEFAULT);
        op = URX_BUILD(URX_ONECHAR_I, c);
    } else {
        // Uncased char, or case sensitive match mode.
        //  Either way, just generate a literal compare of the char.
        op = URX_BUILD(URX_ONECHAR, c);
    }
    fRXPat->fCompiledPat->addElement(op, *fStatus);
}


//------------------------------------------------------------------------------
//
//    fixLiterals           When compiling something that can follow a literal
//                          string in a pattern, we need to "fix" any preceding
//                          string, which will cause any subsequent literals to
//                          begin a new string, rather than appending to the
//                          old one.
//
//                          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) {
    int32_t  stringStart = fStringOpStart;    // start index of the current literal string
    int32_t  op;                              // An op from/for the compiled pattern.
    int32_t  opType;                          // An opcode type from the compiled pattern.
    int32_t  stringLastCharIdx;
    UChar32  lastChar;
    int32_t  stringNextToLastCharIdx;
    UChar32  nextToLastChar;
    int32_t  stringLen;

    fStringOpStart = -1;    
    if (!split) {
        return;
    }

    // Split:  We need to  ensure that the last item in the compiled pattern does
    //   not refer to a literal string of more than one char.  If it does,
    //   separate the last char from the rest of the string.

    // If the last operation from the compiled pattern is not a string,
    //   nothing needs to be done  
    op     = fRXPat->fCompiledPat->lastElementi();
    opType = URX_TYPE(op);
    if (opType != URX_STRING_LEN) {
        return;
    }
    stringLen = URX_VAL(op);

    //
    // Find the position of the last code point in the string  (might be a surrogate pair)
    //
    stringLastCharIdx = fRXPat->fLiteralText.length();
    stringLastCharIdx = fRXPat->fLiteralText.moveIndex32(stringLastCharIdx, -1);
    lastChar          = fRXPat->fLiteralText.char32At(stringLastCharIdx);

    // The string should always be at least two code points long, meaning that there
    //   should be something before the last char position that we just found.
    U_ASSERT(stringLastCharIdx > stringStart);
    stringNextToLastCharIdx = fRXPat->fLiteralText.moveIndex32(stringLastCharIdx, -1);
    U_ASSERT(stringNextToLastCharIdx >= stringStart);
    nextToLastChar          = fRXPat->fLiteralText.char32At(stringNextToLastCharIdx);

    if (stringNextToLastCharIdx > stringStart) {
        // The length of string remaining after removing one char is two or more.
        // Leave the string in the compiled pattern, shorten it by one char,
        //   and append a URX_ONECHAR op for the last char.
        stringLen -= (fRXPat->fLiteralText.length() - stringLastCharIdx);
        op = URX_BUILD(URX_STRING_LEN, stringLen);
        fRXPat->fCompiledPat->setElementAt(op, fRXPat->fCompiledPat->size() -1);
        emitONE_CHAR(lastChar);
    } else {
        // The original string consisted of exactly two characters.  Replace
        // the existing compiled URX_STRING/URX_STRING_LEN ops with a pair
        // of URX_ONECHARs.
        fRXPat->fCompiledPat->setSize(fRXPat->fCompiledPat->size() -2);
        emitONE_CHAR(nextToLastChar);
        emitONE_CHAR(lastChar);
    }
}






//------------------------------------------------------------------------------
//
//   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) {
    UVector32 *code = fRXPat->fCompiledPat;
    U_ASSERT(where>0 && where < code->size());

    int32_t  nop = URX_BUILD(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 = 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_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 = URX_BUILD(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);
        if (x>where) {
            x++;
            fParenStack.setElementAt(x, loc);
        }
    }

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



//------------------------------------------------------------------------------
//
//   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;
    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);
        uint32_t  opAtTheLoc = fRXPat->fCompiledPat->elementAti(theLoc);
        U_ASSERT(URX_TYPE(opAtTheLoc) == URX_NOP);
    }
    else {
        // Item just compiled is a single thing, a ".", or a single char, or a set reference.
        // No slot for STATE_SAVE was pre-reserved in the compiled code.
        // We need to make space now.
        fixLiterals(TRUE);  // If last item was a string, separate the last char.
        theLoc = fRXPat->fCompiledPat->size()-1;
        if (reserveLoc) {
            int32_t opAtTheLoc = fRXPat->fCompiledPat->elementAti(theLoc);
            int32_t  nop = URX_BUILD(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;
    }

    // Force any literal chars that may follow the close paren to start a new string,
    //   and not attach to any preceding it.
    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 = 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();
    
    // 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 = fRXPat->fCompiledPat->elementAti(fMatchOpenParen+1);
            U_ASSERT(URX_TYPE(captureOp) == URX_START_CAPTURE);

            int32_t   frameVarLocation = URX_VAL(captureOp);
            int32_t   endCaptureOp = URX_BUILD(URX_END_CAPTURE, frameVarLocation);
            fRXPat->fCompiledPat->addElement(endCaptureOp, *fStatus);
        }
        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 = fRXPat->fCompiledPat->elementAti(fMatchOpenParen+1);
            U_ASSERT(URX_TYPE(stoOp) == URX_STO_SP);
            int32_t   stoLoc = URX_VAL(stoOp);
            int32_t   ldOp   = URX_BUILD(URX_LD_SP, stoLoc);
            fRXPat->fCompiledPat->addElement(ldOp, *fStatus);
        }
        break;

    case lookAhead:
        {
            int32_t  startOp = fRXPat->fCompiledPat->elementAti(fMatchOpenParen-1);
            U_ASSERT(URX_TYPE(startOp) == URX_LA_START);
            int32_t dataLoc  = URX_VAL(startOp);
            int32_t op       = URX_BUILD(URX_LA_END, dataLoc);
            fRXPat->fCompiledPat->addElement(op, *fStatus);
        }
        break;

    case negLookAhead:
        {
            // See comment at doOpenLookAheadNeg
            int32_t  startOp = fRXPat->fCompiledPat->elementAti(fMatchOpenParen-1);
            U_ASSERT(URX_TYPE(startOp) == URX_LA_START);
            int32_t dataLoc  = URX_VAL(startOp);
            int32_t op       = URX_BUILD(URX_LA_END, dataLoc);
            fRXPat->fCompiledPat->addElement(op, *fStatus);
             op              = URX_BUILD(URX_FAIL, 0);
            fRXPat->fCompiledPat->addElement(op, *fStatus);

            // Patch the URX_SAVE near the top of the block.
            int32_t saveOp   = fRXPat->fCompiledPat->elementAti(fMatchOpenParen);
            U_ASSERT(URX_TYPE(saveOp) == URX_STATE_SAVE);
            int32_t dest     = fRXPat->fCompiledPat->size();
            saveOp           = URX_BUILD(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 = fRXPat->fCompiledPat->elementAti(fMatchOpenParen-4);
            U_ASSERT(URX_TYPE(startOp) == URX_LB_START);
            int32_t dataLoc  = URX_VAL(startOp);
            int32_t op       = URX_BUILD(URX_LB_END, dataLoc);
            fRXPat->fCompiledPat->addElement(op, *fStatus);
                    op       = URX_BUILD(URX_LA_END, dataLoc);
            fRXPat->fCompiledPat->addElement(op, *fStatus);

            // 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 (maxML == INT32_MAX) {
                error(U_REGEX_LOOK_BEHIND_LIMIT);
                break;
            }
            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 = fRXPat->fCompiledPat->elementAti(fMatchOpenParen-5);
            U_ASSERT(URX_TYPE(startOp) == URX_LB_START);
            int32_t dataLoc  = URX_VAL(startOp);
            int32_t op       = URX_BUILD(URX_LBN_END, dataLoc);
            fRXPat->fCompiledPat->addElement(op, *fStatus);

            // 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 (maxML == INT32_MAX) {
                error(U_REGEX_LOOK_BEHIND_LIMIT);
                break;
            }
            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
            op = URX_BUILD(URX_RELOC_OPRND, fRXPat->fCompiledPat->size());
            fRXPat->fCompiledPat->setElementAt(op,  fMatchOpenParen-1);
        }
        break;



    default:
        U_ASSERT(FALSE);
    }

    // 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;
    }
    int32_t  setSize = theSet->size();
    UChar32  firstSetChar = theSet->charAt(0);
    if (firstSetChar == -1) {
        // Sets that contain only strings, but no individual chars,
        // will end up here.
        error(U_REGEX_SET_CONTAINS_STRING);
        setSize = 0;
    }

    switch (setSize) {
    case 0:      
        {
            // Set of no elements.   Always fails to match.  
            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKTRACK, 0), *fStatus);
            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(firstSetChar);
            delete theSet;
        }
        break;
        
    default: 
        {
            //  The set contains two or more chars.  (the normal case)
            //  Put it into the compiled pattern as a set.
            int32_t setNumber = fRXPat->fSets->size();
            fRXPat->fSets->addElement(theSet, *fStatus);
            int32_t setOp = URX_BUILD(URX_SETREF, setNumber);
            fRXPat->fCompiledPat->addElement(setOp, *fStatus);
        }
    }
}


//----------------------------------------------------------------------------------------
//
//   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.
//
//                      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.
    int32_t   counterLoc = fRXPat->fFrameSize;
    fRXPat->fFrameSize++;

    int32_t   op = URX_BUILD(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 = URX_BUILD(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);

    // Apend 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.
    op = URX_BUILD(LoopOp, topOfBlock);
    fRXPat->fCompiledPat->addElement(op, *fStatus);

    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.
        fRXPat->fCompiledPat->setSize(topOfBlock);
        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 = 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 = URX_BUILD(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) {
            fRXPat->fCompiledPat->addElement(saveOp, *fStatus);
        }
        if (i > fIntervalLow) {
            fRXPat->fCompiledPat->addElement(saveOp, *fStatus);
        }
        fRXPat->fCompiledPat->addElement(op, *fStatus);
    }
    return TRUE;
}



//----------------------------------------------------------------------------------------
//
//   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 = 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);
        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_DOLLAR:
        case URX_RELOC_OPRND:
        case URX_STO_INP_LOC:
        case URX_DOLLAR_M:
        case URX_BACKTRACK:
        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:
            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++;
            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++;
            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 = fRXPat->fStaticSets[sn];
                fRXPat->fInitialChars->addAll(*s);
                numInitialStrings += 2;
            }
            currentLen++;
            atStart = FALSE;
            break;



        case URX_STAT_SETREF_N:    
            if (currentLen == 0) {
                int32_t  sn = URX_VAL(op);
                const UnicodeSet *s = fRXPat->fStaticSets[sn];
                UnicodeSet sc(*s);
                sc.complement();
                fRXPat->fInitialChars->addAll(sc);
                numInitialStrings += 2;
            }
            currentLen++;
            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++;
            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)) {
                    // character may have distinct cased forms.  Add all of them
                    //   to the set of possible starting match chars.
                    UnicodeSet s(c, c);
                    s.closeOver(USET_CASE);
                    fRXPat->fInitialChars->addAll(s);
                } 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++;
            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_ALL_PL:
        case URX_DOTANY_PL:
            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++;
            atStart = FALSE;
            break;


        case URX_JMPX:
            loc++;             // Except for extra operand on URX_JMPX, same as URX_JMP.
        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_FAIL:
            // 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 = 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 += 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 = 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(c, c);
                    s.closeOver(USET_CASE);
                    fRXPat->fInitialChars->addAll(s);
                    numInitialStrings += 2;  // Matching on an initial string not possible.
                }
                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   = fRXPat->fCompiledPat->elementAti(loc+1);
                        loopEndLoc   = URX_VAL(loopEndLoc);
                int32_t minLoopCount = 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.
                int32_t  depth = 0;
                for (;;) {
                    loc++;
                    op = fRXPat->fCompiledPat->elementAti(loc);
                    if (URX_TYPE(op) == URX_LA_START || URX_TYPE(op) == URX_LB_START) {
                        depth++;
                    }
                    if (URX_TYPE(op) == URX_LA_END || URX_TYPE(op)==URX_LBN_END) {
                        if (depth == 0) {
                            break;
                        }
                        depth--;
                    }
                    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:
            U_ASSERT(FALSE);     // Shouldn't get here.  These ops should be 
                                 //  consumed by the scan in URX_LA_START and LB_START

            break;
            
        default:
            U_ASSERT(FALSE);
            }
            
        }


    // 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 = 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);
        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_RELOC_OPRND:
        case URX_STO_INP_LOC:
        case URX_DOLLAR_M:
        case URX_CARET_M:
        case URX_BACKTRACK:
        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_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_PL:
        case URX_DOTANY_ALL_PL:
            currentLen++;
            break;


        case URX_JMPX:
            loc++;              // URX_JMPX has an extra operand, ignored here,
                                //   otherwise processed identically to URX_JMP.
        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_FAIL:
            {
                // Fails are kind of like a branch, except that the min length was
                //   propagated already, by the state save.
                currentLen = forwardedLength.elementAti(loc+1);
                U_ASSERT(currentLen>=0 && currentLen < INT32_MAX);
            }
            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:
        case URX_STRING_I:
            {
                loc++;
                int32_t stringLenOp = fRXPat->fCompiledPat->elementAti(loc);
                currentLen += URX_VAL(stringLenOp);
            }
            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   = fRXPat->fCompiledPat->elementAti(loc+1);
                        loopEndLoc   = URX_VAL(loopEndLoc);
                int32_t minLoopCount = 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.
                //   TODO:  Positive lookahead could recursively do the block, then continue
                //          with the longer of the block or the value coming in.
                int32_t  depth = 0;
                for (;;) {
                    loc++;
                    op = fRXPat->fCompiledPat->elementAti(loc);
                    if (URX_TYPE(op) == URX_LA_START || URX_TYPE(op) == URX_LB_START) {
                        depth++;
                    }
                    if (URX_TYPE(op) == URX_LA_END || URX_TYPE(op)==URX_LBN_END) {
                        if (depth == 0) {
                            break;
                        }
                        depth--;
                    }
                    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:
            U_ASSERT(FALSE);
            }
            
        }

    // 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 = 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_RELOC_OPRND:
        case URX_STO_INP_LOC:
        case URX_DOLLAR_M:
        case URX_CARET_M:
        case URX_BACKTRACK:

        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.
        case URX_DOTANY_PL:
        case URX_DOTANY_ALL_PL:
            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_ONECHAR_I:
        case URX_DOTANY_ALL:  
        case URX_DOTANY:
            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++;
            if (URX_VAL(op) > 0x10000) {
                currentLen++;
            }
            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_FAIL:
            // Fails 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:
        case URX_STRING_I:
            {
                loc++;
                int32_t stringLenOp = fRXPat->fCompiledPat->elementAti(loc);
                currentLen += URX_VAL(stringLenOp);
            }
            break;


        case URX_CTR_INIT:
        case URX_CTR_INIT_NG:
        case URX_CTR_LOOP:
        case URX_CTR_LOOP_NG:
        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.
            //   Note:  INIT instructions are multi-word.  Can ignore because
            //          INT32_MAX length will stop the per-instruction loop.
            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.
            U_ASSERT(FALSE);
            break;
            
        case URX_LB_START:
            {
                // Look-behind.  Scan forward until the matching look-around end,
                //   without processing the look-behind block.  
                int32_t  depth = 0;
                for (;;) {
                    loc++;
                    op = fRXPat->fCompiledPat->elementAti(loc);
                    if (URX_TYPE(op) == URX_LA_START || URX_TYPE(op) == URX_LB_START) {
                        depth++;
                    }
                    if (URX_TYPE(op) == URX_LA_END || URX_TYPE(op)==URX_LBN_END) {
                        if (depth == 0) {
                            break;
                        }
                        depth--;
                    }
                    U_ASSERT(loc < end);  
                }
            }
            break;

        default:
            U_ASSERT(FALSE);
        }

            
        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.
//
//----------------------------------------------------------------------------------------
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 = fRXPat->fCompiledPat->elementAti(loc);
        if (URX_TYPE(op) == URX_NOP) {
            d++;
        }
    }

    // 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 = 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 = URX_BUILD(opType, fixedOperandAddress);
                fRXPat->fCompiledPat->setElementAt(op, dst);
                dst++;
                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_DOTANY_ALL_PL:
        case URX_DOTANY_PL:
        case URX_BACKSLASH_D:
        case URX_CARET:
        case URX_DOLLAR:
        case URX_CTR_INIT:
        case URX_CTR_INIT_NG:
        case URX_STO_SP:
        case URX_LD_SP:
        case URX_BACKREF:
        case URX_STO_INP_LOC:
        case URX_LA_START:
        case URX_LA_END:
        case URX_ONECHAR_I:
        case URX_STRING_I:
        case URX_BACKREF_I:
        case URX_DOLLAR_M:
        case URX_CARET_M:
        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:
            // These instructions are unaltered by the relocation.
            fRXPat->fCompiledPat->setElementAt(op, dst);
            dst++;
            break;

        default:
            // Some op is unaccounted for.
            U_ASSERT(FALSE);
            error(U_REGEX_INTERNAL_ERROR);
        }
    }

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




//----------------------------------------------------------------------------------------
//
//   OptDotStar       Optimize patterns that end with a '.*' or '.+' to
//                    just advance the input to the end.
//
//         Transform this compiled sequence
//            [DOT_ANY | DOT_ANY_ALL]
//            JMP_SAV  to previous instruction
//            [NOP | END_CAPTURE | DOLLAR | BACKSLASH_Z]*
//            END
//
//         To
//            NOP
//            [DOT_ANY_PL | DOT_ANY_ALL_PL]
//            [NOP | END_CAPTURE | DOLLAR | BACKSLASH_Z]*
//            END
//
//----------------------------------------------------------------------------------------
void RegexCompile::OptDotStar() {
    // Scan backwards in the pattern, looking for a JMP_SAV near the end.
    int32_t  jmpLoc;
    int32_t  op = 0;
    int32_t  opType;
    for (jmpLoc=fRXPat->fCompiledPat->size(); jmpLoc--;) {
        U_ASSERT(jmpLoc>0);
        op     = fRXPat->fCompiledPat->elementAti(jmpLoc);
        opType = URX_TYPE(op);
        switch(opType) { 

            
        case URX_END:
        case URX_NOP:
        case URX_END_CAPTURE:
        case URX_DOLLAR_M:
        case URX_DOLLAR:
        case URX_BACKSLASH_Z:
            // These ops may follow the JMP_SAV without preventing us from
            //   doing this optimization.
            continue;

        case URX_JMP_SAV:
            // Got a trailing JMP_SAV that's a candidate for optimization.
            break;

        default:
            // This optimization not possible.
            return;
        }
        break;   // from the for loop.
    }

    // We found in URX_JMP_SAV near the end that is a candidate for optimizing.
    // Is the target address the previous instruction?
    // Is the previous instruction a flavor of URX_DOTANY
    int32_t  loopTopLoc = URX_VAL(op);
    if (loopTopLoc != jmpLoc-1) {
        return;
    }
    int32_t newOp;
    int32_t oldOp     = fRXPat->fCompiledPat->elementAti(loopTopLoc);
    int32_t oldOpType = opType = URX_TYPE(oldOp);
    if (oldOpType == URX_DOTANY) {
        newOp = URX_BUILD(URX_DOTANY_PL, 0);
    }
    else if (oldOpType == URX_DOTANY_ALL) {
        newOp = URX_BUILD(URX_DOTANY_ALL_PL, 0);
    } else {
        return;    // Sequence we were looking for isn't there.
    }

    // Substitute the new instructions into the pattern.
    // The NOP will be removed in a later optimization step.
    fRXPat->fCompiledPat->setElementAt(URX_BUILD(URX_NOP, 0), loopTopLoc);
    fRXPat->fCompiledPat->setElementAt(newOp, jmpLoc);
}


//----------------------------------------------------------------------------------------
//
//  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)) {
        *fStatus = e;
        fParseErr->line   = fLineNum;
        fParseErr->offset = fCharNum;

        // 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));
        fRXPat->fPattern.extractBetween(fScanIndex-U_PARSE_CONTEXT_LEN+1, fScanIndex,
            fParseErr->preContext,  0);
        fRXPat->fPattern.extractBetween(fScanIndex, fScanIndex+U_PARSE_CONTEXT_LEN-1,
            fParseErr->postContext, 0);
    }
}


//
//  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;
static const UChar      chNEL       = 0x85;      //    NEL newline variant
static const UChar      chLS        = 0x2028;    //    Unicode Line Separator
static const UChar      chApos      = 0x27;      //  single quote, for quoted chars.
static const UChar      chPound     = 0x23;      // '#', introduces a comment.
static const UChar      chE         = 0x45;      // 'E'
static const UChar      chBackSlash = 0x5c;      // '\'  introduces a char escape
static const UChar      chLParen    = 0x28;
static const UChar      chRParen    = 0x29;
static const UChar      chLBracket  = 0x5b;
static const UChar      chRBracket  = 0x5d;
static const UChar      chRBrace    = 0x7d;
static const UChar      chUpperN    = 0x4E;
static const UChar      chLowerP    = 0x70;
static const UChar      chUpperP    = 0x50;


//----------------------------------------------------------------------------------------
//
//  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;
    UnicodeString &pattern = fRXPat->fPattern;

    if (fPeekChar != -1) {
        ch = fPeekChar;
        fPeekChar = -1;
        return ch;
    }
    if (fPatternLength==0 || fNextIndex >= fPatternLength) {
        return (UChar32)-1;
    }
    ch         = pattern.char32At(fNextIndex);
    fNextIndex = pattern.moveIndex32(fNextIndex, 1);

    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;
        if (fQuoteMode) {
            error(U_REGEX_RULE_SYNTAX);
            fQuoteMode = FALSE;
        }
    }
    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) {

    fScanIndex = fNextIndex;
    c.fChar    = nextCharLL();
    c.fQuoted  = FALSE;

    if (fQuoteMode) {
        c.fQuoted = TRUE;
        if ((c.fChar==chBackSlash && peekCharLL()==chE) || c.fChar == (UChar32)-1) {
            fQuoteMode = FALSE;  //  Exit quote mode,
            nextCharLL();       // discard the E
            nextChar(c);        // recurse to get the real next char
        }
    }
    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;
                        }
                    }
                }
                if (uprv_isRuleWhiteSpace(c.fChar) == FALSE) {
                    break;
                }
                c.fChar = nextCharLL();
            }
        }

        //
        //  check for backslash escaped characters.
        //
                int32_t startX = fNextIndex;  // start and end positions of the
                int32_t endX   = fNextIndex;  //   sequence following the '\'
        if (c.fChar == chBackSlash) {
            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;
                c.fChar = fRXPat->fPattern.unescapeAt(endX);
                if (startX == endX) {
                    error(U_REGEX_BAD_ESCAPE_SEQUENCE);
                }
                fCharNum += endX - startX;
                fNextIndex = endX;
            }
            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.  TODO:  this is awkward, think about alternatives.
                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);
}



//---------------------------------------------------------------------------------
//
//  scanSet    Construct a UnicodeSet from the text at the current scan
//             position.  Advance the scan position to the first character
//             after the set.
//
//             The scan position is normally under the control of the state machine
//             that controls pattern parsing.  UnicodeSets, however, are parsed by
//             the UnicodeSet constructor, not by the Regex pattern parser.
//
//---------------------------------------------------------------------------------
UnicodeSet *RegexCompile::scanSet() {
    UnicodeSet    *uset = NULL;
    ParsePosition  pos;
    int            startPos;
    int            i;

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

    pos.setIndex(fScanIndex);
    startPos = fScanIndex;
    UErrorCode localStatus = U_ZERO_ERROR;
    uint32_t   usetFlags = 0;
    if (fModeFlags & UREGEX_CASE_INSENSITIVE) {
        usetFlags |= USET_CASE_INSENSITIVE;
    }
    if (fModeFlags & UREGEX_COMMENTS) {
        usetFlags |= USET_IGNORE_SPACE;
    }

    uset = new UnicodeSet(fRXPat->fPattern, pos,
                         usetFlags, NULL, localStatus);
    if (U_FAILURE(localStatus)) {
        //  TODO:  Get more accurate position of the error from UnicodeSet's return info.
        //         UnicodeSet appears to not be reporting correctly at this time.
        REGEX_SCAN_DEBUG_PRINTF( "UnicodeSet parse postion.ErrorIndex = %d\n", pos.getIndex());
        error(localStatus);
        delete uset;
        return NULL;
    }

    // Advance the current scan postion over the UnicodeSet.
    //   Don't just set fScanIndex because the line/char positions maintained
    //   for error reporting would be thrown off.
    i = pos.getIndex();
    for (;;) {
        if (fNextIndex >= i) {
            break;
        }
        nextCharLL();
    }

    return uset;
};


//---------------------------------------------------------------------------------
//
//  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;
    }

    U_ASSERT(fC.fChar == chLowerP || fC.fChar == chUpperP || fC.fChar == chUpperN);

    // enclose the \p{property} from the regex pattern source in  [brackets]
    UnicodeString setPattern;
    setPattern.append(chLBracket);
    setPattern.append(chBackSlash);
    for (;;) {
        setPattern.append(fC.fChar);
        if (fC.fChar == chRBrace) {
            break;
        }
        nextChar(fC);
        if (fC.fChar == -1) {
            // Hit the end of the input string without finding the closing '}'
            error(U_REGEX_PROPERTY_SYNTAX);
            return NULL;
        }
    }
    setPattern.append(chRBracket);

    uint32_t   usetFlags = 0;
    if (fModeFlags & UREGEX_CASE_INSENSITIVE) {
        usetFlags |= USET_CASE_INSENSITIVE;
    }
    if (fModeFlags & UREGEX_COMMENTS) {
        usetFlags |= USET_IGNORE_SPACE;
    }

    // Build the UnicodeSet from the set pattern we just built up in a string.
    uset = new UnicodeSet(setPattern, usetFlags, NULL, *fStatus);
    if (U_FAILURE(*fStatus)) {
        delete uset;
        uset =  NULL;
    }

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

U_NAMESPACE_END
#endif  // !UCONFIG_NO_REGULAR_EXPRESSIONS
