// Copyright (C) 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
**********************************************************************
*   Copyright (C) 2004-2016, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*   file name:  uregex.h
*   encoding:   US-ASCII
*   indentation:4
*
*   created on: 2004mar09
*   created by: Andy Heninger
*
*   ICU Regular Expressions, API for C
*/

/**
 * \file
 * \brief C API: Regular Expressions
 *
 * <p>This is a C wrapper around the C++ RegexPattern and RegexMatcher classes.</p>
 */

#ifndef UREGEX_H
#define UREGEX_H

#include "unicode/utext.h"
#include "unicode/utypes.h"

#if !UCONFIG_NO_REGULAR_EXPRESSIONS

#include "unicode/localpointer.h"
#include "unicode/parseerr.h"

struct URegularExpression;
/**
  * Structure representing a compiled regular expression, plus the results
  *    of a match operation.
  * @stable ICU 3.0
  */
typedef struct URegularExpression URegularExpression;


/**
 * Constants for Regular Expression Match Modes.
 * @stable ICU 2.4
 */
typedef enum URegexpFlag{

#ifndef U_HIDE_DRAFT_API 
    /** Forces normalization of pattern and strings. 
    Not implemented yet, just a placeholder, hence draft. 
    @draft ICU 2.4 */
    UREGEX_CANON_EQ         = 128,
#endif /* U_HIDE_DRAFT_API */
    /**  Enable case insensitive matching.  @stable ICU 2.4 */
    UREGEX_CASE_INSENSITIVE = 2,

    /**  Allow white space and comments within patterns  @stable ICU 2.4 */
    UREGEX_COMMENTS         = 4,

    /**  If set, '.' matches line terminators,  otherwise '.' matching stops at line end.
      *  @stable ICU 2.4 */
    UREGEX_DOTALL           = 32,
    
    /**  If set, treat the entire pattern as a literal string.  
      *  Metacharacters or escape sequences in the input sequence will be given 
      *  no special meaning. 
      *
      *  The flag UREGEX_CASE_INSENSITIVE retains its impact
      *  on matching when used in conjunction with this flag.
      *  The other flags become superfluous.
      *
      * @stable ICU 4.0
      */
    UREGEX_LITERAL = 16,

    /**   Control behavior of "$" and "^"
      *    If set, recognize line terminators within string,
      *    otherwise, match only at start and end of input string.
      *   @stable ICU 2.4 */
    UREGEX_MULTILINE        = 8,
    
    /**   Unix-only line endings.
      *   When this mode is enabled, only \\u000a is recognized as a line ending
      *    in the behavior of ., ^, and $.
      *   @stable ICU 4.0
      */
    UREGEX_UNIX_LINES = 1,

    /**  Unicode word boundaries.
      *     If set, \b uses the Unicode TR 29 definition of word boundaries.
      *     Warning: Unicode word boundaries are quite different from
      *     traditional regular expression word boundaries.  See
      *     http://unicode.org/reports/tr29/#Word_Boundaries
      *     @stable ICU 2.8
      */
    UREGEX_UWORD            = 256,

     /**  Error on Unrecognized backslash escapes.
       *     If set, fail with an error on patterns that contain
       *     backslash-escaped ASCII letters without a known special
       *     meaning.  If this flag is not set, these
       *     escaped letters represent themselves.
       *     @stable ICU 4.0
       */
     UREGEX_ERROR_ON_UNKNOWN_ESCAPES = 512

}  URegexpFlag;

/**
  *  Open (compile) an ICU regular expression.  Compiles the regular expression in
  *  string form into an internal representation using the specified match mode flags.
  *  The resulting regular expression handle can then be used to perform various
  *   matching operations.
  * 
  *
  * @param pattern        The Regular Expression pattern to be compiled. 
  * @param patternLength  The length of the pattern, or -1 if the pattern is
  *                       NUL terminated.
  * @param flags          Flags that alter the default matching behavior for
  *                       the regular expression, UREGEX_CASE_INSENSITIVE, for
  *                       example.  For default behavior, set this parameter to zero.
  *                       See <code>enum URegexpFlag</code>.  All desired flags
  *                       are bitwise-ORed together.
  * @param pe             Receives the position (line and column numbers) of any syntax
  *                       error within the source regular expression string.  If this
  *                       information is not wanted, pass NULL for this parameter.
  * @param status         Receives error detected by this function.
  * @stable ICU 3.0
  *
  */
U_STABLE URegularExpression * U_EXPORT2
uregex_open( const  UChar          *pattern,
                    int32_t         patternLength,
                    uint32_t        flags,
                    UParseError    *pe,
                    UErrorCode     *status);

/**
  *  Open (compile) an ICU regular expression.  Compiles the regular expression in
  *  string form into an internal representation using the specified match mode flags.
  *  The resulting regular expression handle can then be used to perform various
  *   matching operations.
  *  <p>
  *  The contents of the pattern UText will be extracted and saved. Ownership of the
  *   UText struct itself remains with the caller. This is to match the behavior of
  *   uregex_open().
  *
  * @param pattern        The Regular Expression pattern to be compiled. 
  * @param flags          Flags that alter the default matching behavior for
  *                       the regular expression, UREGEX_CASE_INSENSITIVE, for
  *                       example.  For default behavior, set this parameter to zero.
  *                       See <code>enum URegexpFlag</code>.  All desired flags
  *                       are bitwise-ORed together.
  * @param pe             Receives the position (line and column numbers) of any syntax
  *                       error within the source regular expression string.  If this
  *                       information is not wanted, pass NULL for this parameter.
  * @param status         Receives error detected by this function.
  *
  * @stable ICU 4.6
  */
U_STABLE URegularExpression *  U_EXPORT2
uregex_openUText(UText          *pattern,
                 uint32_t        flags,
                 UParseError    *pe,
                 UErrorCode     *status);

/**
  *  Open (compile) an ICU regular expression.  The resulting regular expression
  *   handle can then be used to perform various matching operations.
  *  <p>
  *   This function is the same as uregex_open, except that the pattern
  *   is supplied as an 8 bit char * string in the default code page.
  *
  * @param pattern        The Regular Expression pattern to be compiled, 
  *                       NUL terminated.  
  * @param flags          Flags that alter the default matching behavior for
  *                       the regular expression, UREGEX_CASE_INSENSITIVE, for
  *                       example.  For default behavior, set this parameter to zero.
  *                       See <code>enum URegexpFlag</code>.  All desired flags
  *                       are bitwise-ORed together.
  * @param pe             Receives the position (line and column numbers) of any syntax
  *                       error within the source regular expression string.  If this
  *                       information is not wanted, pass NULL for this parameter.
  * @param status         Receives errors detected by this function.
  * @return               The URegularExpression object representing the compiled
  *                       pattern.
  *
  * @stable ICU 3.0
  */
#if !UCONFIG_NO_CONVERSION
U_STABLE URegularExpression * U_EXPORT2
uregex_openC( const char           *pattern,
                    uint32_t        flags,
                    UParseError    *pe,
                    UErrorCode     *status);
#endif



/**
  *  Close the regular expression, recovering all resources (memory) it
  *   was holding.
  *
  * @param regexp   The regular expression to be closed.
  * @stable ICU 3.0
  */
U_STABLE void U_EXPORT2 
uregex_close(URegularExpression *regexp);

#if U_SHOW_CPLUSPLUS_API

U_NAMESPACE_BEGIN

/**
 * \class LocalURegularExpressionPointer
 * "Smart pointer" class, closes a URegularExpression via uregex_close().
 * For most methods see the LocalPointerBase base class.
 *
 * @see LocalPointerBase
 * @see LocalPointer
 * @stable ICU 4.4
 */
U_DEFINE_LOCAL_OPEN_POINTER(LocalURegularExpressionPointer, URegularExpression, uregex_close);

U_NAMESPACE_END

#endif

/**
 * Make a copy of a compiled regular expression.  Cloning a regular
 * expression is faster than opening a second instance from the source
 * form of the expression, and requires less memory.
 * <p>
 * Note that the current input string and the position of any matched text
 *  within it are not cloned; only the pattern itself and the
 *  match mode flags are copied.
 * <p>
 * Cloning can be particularly useful to threaded applications that perform
 * multiple match operations in parallel.  Each concurrent RE
 * operation requires its own instance of a URegularExpression.
 *
 * @param regexp   The compiled regular expression to be cloned.
 * @param status   Receives indication of any errors encountered
 * @return the cloned copy of the compiled regular expression.
 * @stable ICU 3.0
 */
U_STABLE URegularExpression * U_EXPORT2 
uregex_clone(const URegularExpression *regexp, UErrorCode *status);

/**
 *  Returns a pointer to the source form of the pattern for this regular expression.
 *  This function will work even if the pattern was originally specified as a UText.
 *
 * @param regexp     The compiled regular expression.
 * @param patLength  This output parameter will be set to the length of the
 *                   pattern string.  A NULL pointer may be used here if the
 *                   pattern length is not needed, as would be the case if
 *                   the pattern is known in advance to be a NUL terminated
 *                   string.
 * @param status     Receives errors detected by this function.
 * @return a pointer to the pattern string.  The storage for the string is
 *                   owned by the regular expression object, and must not be
 *                   altered or deleted by the application.  The returned string
 *                   will remain valid until the regular expression is closed.
 * @stable ICU 3.0
 */
U_STABLE const UChar * U_EXPORT2 
uregex_pattern(const URegularExpression *regexp,
                     int32_t            *patLength,
                     UErrorCode         *status);

/**
 *  Returns the source text of the pattern for this regular expression.
 *  This function will work even if the pattern was originally specified as a UChar string.
 *
 * @param regexp     The compiled regular expression.
 * @param status     Receives errors detected by this function.
 * @return the pattern text.  The storage for the text is owned by the regular expression
 *                   object, and must not be altered or deleted.
 *
 * @stable ICU 4.6
 */
U_STABLE UText * U_EXPORT2 
uregex_patternUText(const URegularExpression *regexp,
                          UErrorCode         *status);

/**
  * Get the match mode flags that were specified when compiling this regular expression.
  * @param status   Receives errors detected by this function.
  * @param regexp   The compiled regular expression.
  * @return         The match mode flags
  * @see URegexpFlag
  * @stable ICU 3.0
  */
U_STABLE int32_t U_EXPORT2 
uregex_flags(const  URegularExpression   *regexp,
                    UErrorCode           *status);


/**
  *  Set the subject text string upon which the regular expression will look for matches.
  *  This function may be called any number of times, allowing the regular
  *  expression pattern to be applied to different strings.
  *  <p>
  *  Regular expression matching operations work directly on the application's
  *  string data.  No copy is made.  The subject string data must not be
  *  altered after calling this function until after all regular expression
  *  operations involving this string data are completed.  
  *  <p>
  *  Zero length strings are permitted.  In this case, no subsequent match
  *  operation will dereference the text string pointer.
  *
  * @param regexp     The compiled regular expression.
  * @param text       The subject text string.
  * @param textLength The length of the subject text, or -1 if the string
  *                   is NUL terminated.
  * @param status     Receives errors detected by this function.
  * @stable ICU 3.0
  */
U_STABLE void U_EXPORT2 
uregex_setText(URegularExpression *regexp,
               const UChar        *text,
               int32_t             textLength,
               UErrorCode         *status);


/**
  *  Set the subject text string upon which the regular expression will look for matches.
  *  This function may be called any number of times, allowing the regular
  *  expression pattern to be applied to different strings.
  *  <p>
  *  Regular expression matching operations work directly on the application's
  *  string data; only a shallow clone is made.  The subject string data must not be
  *  altered after calling this function until after all regular expression
  *  operations involving this string data are completed.  
  *
  * @param regexp     The compiled regular expression.
  * @param text       The subject text string.
  * @param status     Receives errors detected by this function.
  *
  * @stable ICU 4.6
  */
U_STABLE void U_EXPORT2 
uregex_setUText(URegularExpression *regexp,
                UText              *text,
                UErrorCode         *status);

/**
  *  Get the subject text that is currently associated with this 
  *   regular expression object.  If the input was supplied using uregex_setText(),
  *   that pointer will be returned.  Otherwise, the characters in the input will
  *   be extracted to a buffer and returned.  In either case, ownership remains
  *   with the regular expression object.
  *
  *  This function will work even if the input was originally specified as a UText.
  *
  * @param regexp      The compiled regular expression.
  * @param textLength  The length of the string is returned in this output parameter. 
  *                    A NULL pointer may be used here if the
  *                    text length is not needed, as would be the case if
  *                    the text is known in advance to be a NUL terminated
  *                    string.
  * @param status      Receives errors detected by this function.
  * @return            Pointer to the subject text string currently associated with
  *                    this regular expression.
  * @stable ICU 3.0
  */
U_STABLE const UChar * U_EXPORT2 
uregex_getText(URegularExpression *regexp,
               int32_t            *textLength,
               UErrorCode         *status);

/**
  *  Get the subject text that is currently associated with this 
  *   regular expression object.
  *
  *  This function will work even if the input was originally specified as a UChar string.
  *
  * @param regexp      The compiled regular expression.
  * @param dest        A mutable UText in which to store the current input.
  *                    If NULL, a new UText will be created as an immutable shallow clone
  *                    of the actual input string.
  * @param status      Receives errors detected by this function.
  * @return            The subject text currently associated with this regular expression.
  *                    If a pre-allocated UText was provided, it will always be used and returned.
  *
  * @stable ICU 4.6
  */
U_STABLE UText * U_EXPORT2 
uregex_getUText(URegularExpression *regexp,
                UText              *dest,
                UErrorCode         *status);

/**
  *  Set the subject text string upon which the regular expression is looking for matches
  *  without changing any other aspect of the matching state.
  *  The new and previous text strings must have the same content.
  *
  *  This function is intended for use in environments where ICU is operating on 
  *  strings that may move around in memory.  It provides a mechanism for notifying
  *  ICU that the string has been relocated, and providing a new UText to access the
  *  string in its new position.
  *
  *  Note that the regular expression implementation never copies the underlying text
  *  of a string being matched, but always operates directly on the original text 
  *  provided by the user. Refreshing simply drops the references to the old text 
  *  and replaces them with references to the new.
  *
  *  Caution:  this function is normally used only by very specialized
  *            system-level code.   One example use case is with garbage collection 
  *            that moves the text in memory. 
  *
  * @param regexp     The compiled regular expression.
  * @param text       The new (moved) text string.
  * @param status     Receives errors detected by this function.
  *
  * @stable ICU 4.8
  */
U_STABLE void U_EXPORT2 
uregex_refreshUText(URegularExpression *regexp,
                    UText              *text,
                    UErrorCode         *status);

/**
  *   Attempts to match the input string against the pattern.
  *   To succeed, the match must extend to the end of the string,
  *   or cover the complete match region.
  *
  *   If startIndex >= zero the match operation starts at the specified
  *   index and must extend to the end of the input string.  Any region
  *   that has been specified is reset.
  *
  *   If startIndex == -1 the match must cover the input region, or the entire
  *   input string if no region has been set.  This directly corresponds to
  *   Matcher.matches() in Java
  *
  *    @param  regexp      The compiled regular expression.
  *    @param  startIndex  The input string (native) index at which to begin matching, or -1
  *                        to match the input Region.
  *    @param  status      Receives errors detected by this function.
  *    @return             TRUE if there is a match
  *    @stable ICU 3.0
  */
U_STABLE UBool U_EXPORT2 
uregex_matches(URegularExpression *regexp,
                int32_t            startIndex,
                UErrorCode        *status);

/**
  *   64bit version of uregex_matches.
  *   Attempts to match the input string against the pattern.
  *   To succeed, the match must extend to the end of the string,
  *   or cover the complete match region.
  *
  *   If startIndex >= zero the match operation starts at the specified
  *   index and must extend to the end of the input string.  Any region
  *   that has been specified is reset.
  *
  *   If startIndex == -1 the match must cover the input region, or the entire
  *   input string if no region has been set.  This directly corresponds to
  *   Matcher.matches() in Java
  *
  *    @param  regexp      The compiled regular expression.
  *    @param  startIndex  The input string (native) index at which to begin matching, or -1
  *                        to match the input Region.
  *    @param  status      Receives errors detected by this function.
  *    @return             TRUE if there is a match
  *   @stable ICU 4.6
  */
U_STABLE UBool U_EXPORT2 
uregex_matches64(URegularExpression *regexp,
                 int64_t            startIndex,
                 UErrorCode        *status);

/**
  *   Attempts to match the input string, starting from the specified index, against the pattern.
  *   The match may be of any length, and is not required to extend to the end
  *   of the input string.  Contrast with uregex_matches().
  *
  *   <p>If startIndex is >= 0 any input region that was set for this
  *   URegularExpression is reset before the operation begins.
  *
  *   <p>If the specified starting index == -1 the match begins at the start of the input 
  *   region, or at the start of the full string if no region has been specified.
  *   This corresponds directly with Matcher.lookingAt() in Java.
  *
  *   <p>If the match succeeds then more information can be obtained via the
  *    <code>uregexp_start()</code>, <code>uregexp_end()</code>,
  *    and <code>uregex_group()</code> functions.</p>
  *
  *    @param   regexp      The compiled regular expression.
  *    @param   startIndex  The input string (native) index at which to begin matching, or
  *                         -1 to match the Input Region
  *    @param   status      A reference to a UErrorCode to receive any errors.
  *    @return  TRUE if there is a match.
  *    @stable ICU 3.0
  */
U_STABLE UBool U_EXPORT2 
uregex_lookingAt(URegularExpression *regexp,
                 int32_t             startIndex,
                 UErrorCode         *status);

/**
  *   64bit version of uregex_lookingAt.
  *   Attempts to match the input string, starting from the specified index, against the pattern.
  *   The match may be of any length, and is not required to extend to the end
  *   of the input string.  Contrast with uregex_matches().
  *
  *   <p>If startIndex is >= 0 any input region that was set for this
  *   URegularExpression is reset before the operation begins.
  *
  *   <p>If the specified starting index == -1 the match begins at the start of the input 
  *   region, or at the start of the full string if no region has been specified.
  *   This corresponds directly with Matcher.lookingAt() in Java.
  *
  *   <p>If the match succeeds then more information can be obtained via the
  *    <code>uregexp_start()</code>, <code>uregexp_end()</code>,
  *    and <code>uregex_group()</code> functions.</p>
  *
  *    @param   regexp      The compiled regular expression.
  *    @param   startIndex  The input string (native) index at which to begin matching, or
  *                         -1 to match the Input Region
  *    @param   status      A reference to a UErrorCode to receive any errors.
  *    @return  TRUE if there is a match.
  *    @stable ICU 4.6
  */
U_STABLE UBool U_EXPORT2 
uregex_lookingAt64(URegularExpression *regexp,
                   int64_t             startIndex,
                   UErrorCode         *status);

/**
  *   Find the first matching substring of the input string that matches the pattern.
  *   If startIndex is >= zero the search for a match begins at the specified index,
  *          and any match region is reset.  This corresponds directly with
  *          Matcher.find(startIndex) in Java.
  *
  *   If startIndex == -1 the search begins at the start of the input region,
  *           or at the start of the full string if no region has been specified.
  *
  *   If a match is found, <code>uregex_start(), uregex_end()</code>, and
  *   <code>uregex_group()</code> will provide more information regarding the match.
  *
  *   @param   regexp      The compiled regular expression.
  *   @param   startIndex  The position (native) in the input string to begin the search, or
  *                        -1 to search within the Input Region.
  *   @param   status      A reference to a UErrorCode to receive any errors.
  *   @return              TRUE if a match is found.
  *   @stable ICU 3.0
  */
U_STABLE UBool U_EXPORT2 
uregex_find(URegularExpression *regexp,
            int32_t             startIndex, 
            UErrorCode         *status);

/**
  *   64bit version of uregex_find.
  *   Find the first matching substring of the input string that matches the pattern.
  *   If startIndex is >= zero the search for a match begins at the specified index,
  *          and any match region is reset.  This corresponds directly with
  *          Matcher.find(startIndex) in Java.
  *
  *   If startIndex == -1 the search begins at the start of the input region,
  *           or at the start of the full string if no region has been specified.
  *
  *   If a match is found, <code>uregex_start(), uregex_end()</code>, and
  *   <code>uregex_group()</code> will provide more information regarding the match.
  *
  *   @param   regexp      The compiled regular expression.
  *   @param   startIndex  The position (native) in the input string to begin the search, or
  *                        -1 to search within the Input Region.
  *   @param   status      A reference to a UErrorCode to receive any errors.
  *   @return              TRUE if a match is found.
  *   @stable ICU 4.6
  */
U_STABLE UBool U_EXPORT2 
uregex_find64(URegularExpression *regexp,
              int64_t             startIndex, 
              UErrorCode         *status);

/**
  *  Find the next pattern match in the input string.  Begin searching 
  *  the input at the location following the end of he previous match, 
  *  or at the start of the string (or region) if there is no 
  *  previous match.  If a match is found, <code>uregex_start(), uregex_end()</code>, and
  *  <code>uregex_group()</code> will provide more information regarding the match.
  *
  *  @param   regexp      The compiled regular expression.
  *  @param   status      A reference to a UErrorCode to receive any errors.
  *  @return              TRUE if a match is found.
  *  @see uregex_reset
  *  @stable ICU 3.0
  */
U_STABLE UBool U_EXPORT2 
uregex_findNext(URegularExpression *regexp,
                UErrorCode         *status);

/**
  *   Get the number of capturing groups in this regular expression's pattern.
  *   @param   regexp      The compiled regular expression.
  *   @param   status      A reference to a UErrorCode to receive any errors.
  *   @return the number of capture groups
  *   @stable ICU 3.0
  */
U_STABLE int32_t U_EXPORT2 
uregex_groupCount(URegularExpression *regexp,
                  UErrorCode         *status);

/**
  * Get the group number corresponding to a named capture group.
  * The returned number can be used with any function that access
  * capture groups by number.
  *
  * The function returns an error status if the specified name does not
  * appear in the pattern.
  *
  * @param  regexp      The compiled regular expression.
  * @param  groupName   The capture group name.
  * @param  nameLength  The length of the name, or -1 if the name is a
  *                     nul-terminated string.
  * @param  status      A pointer to a UErrorCode to receive any errors.
  *
  * @stable ICU 55
  */
U_STABLE int32_t U_EXPORT2
uregex_groupNumberFromName(URegularExpression *regexp,
                           const UChar        *groupName,
                           int32_t             nameLength,
                           UErrorCode          *status);


/**
  * Get the group number corresponding to a named capture group.
  * The returned number can be used with any function that access
  * capture groups by number.
  *
  * The function returns an error status if the specified name does not
  * appear in the pattern.
  *
  * @param  regexp      The compiled regular expression.
  * @param  groupName   The capture group name,
  *                     platform invariant characters only.
  * @param  nameLength  The length of the name, or -1 if the name is
  *                     nul-terminated.
  * @param  status      A pointer to a UErrorCode to receive any errors.
  *
  * @stable ICU 55
  */
U_STABLE int32_t U_EXPORT2
uregex_groupNumberFromCName(URegularExpression *regexp,
                            const char         *groupName,
                            int32_t             nameLength,
                            UErrorCode          *status);

/** Extract the string for the specified matching expression or subexpression.
  * Group #0 is the complete string of matched text.
  * Group #1 is the text matched by the first set of capturing parentheses.
  *
  *   @param   regexp       The compiled regular expression.
  *   @param   groupNum     The capture group to extract.  Group 0 is the complete
  *                         match.  The value of this parameter must be
  *                         less than or equal to the number of capture groups in
  *                         the pattern.
  *   @param   dest         Buffer to receive the matching string data
  *   @param   destCapacity Capacity of the dest buffer.
  *   @param   status       A reference to a UErrorCode to receive any errors.
  *   @return               Length of matching data,
  *                         or -1 if no applicable match.
  *   @stable ICU 3.0
  */
U_STABLE int32_t U_EXPORT2 
uregex_group(URegularExpression *regexp,
             int32_t             groupNum,
             UChar              *dest,
             int32_t             destCapacity,
             UErrorCode          *status);

/** Returns a shallow immutable clone of the entire input string with the current index set
  *   to the beginning of the requested capture group.  The capture group length is also
  *   returned via groupLength.
  * Group #0 is the complete string of matched text.
  * Group #1 is the text matched by the first set of capturing parentheses.
  *
  *   @param   regexp       The compiled regular expression.
  *   @param   groupNum     The capture group to extract.  Group 0 is the complete
  *                         match.  The value of this parameter must be
  *                         less than or equal to the number of capture groups in
  *                         the pattern.
  *   @param   dest         A mutable UText in which to store the current input.
  *                         If NULL, a new UText will be created as an immutable shallow clone
  *                         of the entire input string.
  *   @param   groupLength  The group length of the desired capture group. Output parameter.
  *   @param   status       A reference to a UErrorCode to receive any errors.
  *   @return               The subject text currently associated with this regular expression.
  *                         If a pre-allocated UText was provided, it will always be used and returned.

  *
  *   @stable ICU 4.6
  */
U_STABLE UText * U_EXPORT2 
uregex_groupUText(URegularExpression *regexp,
                  int32_t             groupNum,
                  UText              *dest,
                  int64_t            *groupLength,
                  UErrorCode         *status);

/**
  *   Returns the index in the input string of the start of the text matched by the
  *   specified capture group during the previous match operation.  Return -1 if
  *   the capture group was not part of the last match.
  *   Group #0 refers to the complete range of matched text.
  *   Group #1 refers to the text matched by the first set of capturing parentheses.
  *
  *    @param   regexp      The compiled regular expression.
  *    @param   groupNum    The capture group number
  *    @param   status      A reference to a UErrorCode to receive any errors.
  *    @return              the starting (native) position in the input of the text matched 
  *                         by the specified group.
  *    @stable ICU 3.0
  */
U_STABLE int32_t U_EXPORT2 
uregex_start(URegularExpression *regexp,
             int32_t             groupNum,
             UErrorCode          *status);

/**
  *   64bit version of uregex_start.
  *   Returns the index in the input string of the start of the text matched by the
  *   specified capture group during the previous match operation.  Return -1 if
  *   the capture group was not part of the last match.
  *   Group #0 refers to the complete range of matched text.
  *   Group #1 refers to the text matched by the first set of capturing parentheses.
  *
  *    @param   regexp      The compiled regular expression.
  *    @param   groupNum    The capture group number
  *    @param   status      A reference to a UErrorCode to receive any errors.
  *    @return              the starting (native) position in the input of the text matched 
  *                         by the specified group.
  *   @stable ICU 4.6
  */
U_STABLE int64_t U_EXPORT2 
uregex_start64(URegularExpression *regexp,
               int32_t             groupNum,
               UErrorCode          *status);

/**
  *   Returns the index in the input string of the position following the end
  *   of the text matched by the specified capture group.
  *   Return -1 if the capture group was not part of the last match.
  *   Group #0 refers to the complete range of matched text.
  *   Group #1 refers to the text matched by the first set of capturing parentheses.
  *
  *    @param   regexp      The compiled regular expression.
  *    @param   groupNum    The capture group number
  *    @param   status      A reference to a UErrorCode to receive any errors.
  *    @return              the (native) index of the position following the last matched character.
  *    @stable ICU 3.0
  */
U_STABLE int32_t U_EXPORT2 
uregex_end(URegularExpression   *regexp,
           int32_t               groupNum,
           UErrorCode           *status);

/**
  *   64bit version of uregex_end.
  *   Returns the index in the input string of the position following the end
  *   of the text matched by the specified capture group.
  *   Return -1 if the capture group was not part of the last match.
  *   Group #0 refers to the complete range of matched text.
  *   Group #1 refers to the text matched by the first set of capturing parentheses.
  *
  *    @param   regexp      The compiled regular expression.
  *    @param   groupNum    The capture group number
  *    @param   status      A reference to a UErrorCode to receive any errors.
  *    @return              the (native) index of the position following the last matched character.
  *   @stable ICU 4.6
  */
U_STABLE int64_t U_EXPORT2 
uregex_end64(URegularExpression *regexp,
             int32_t               groupNum,
             UErrorCode           *status);

/**
  *  Reset any saved state from the previous match.  Has the effect of
  *  causing uregex_findNext to begin at the specified index, and causing
  *  uregex_start(), uregex_end() and uregex_group() to return an error 
  *  indicating that there is no match information available.  Clears any
  *  match region that may have been set.
  *
  *    @param   regexp      The compiled regular expression.
  *    @param   index       The position (native) in the text at which a
  *                         uregex_findNext() should begin searching.
  *    @param   status      A reference to a UErrorCode to receive any errors.
  *    @stable ICU 3.0
  */
U_STABLE void U_EXPORT2 
uregex_reset(URegularExpression    *regexp,
             int32_t               index,
             UErrorCode            *status);

/**
  *  64bit version of uregex_reset.
  *  Reset any saved state from the previous match.  Has the effect of
  *  causing uregex_findNext to begin at the specified index, and causing
  *  uregex_start(), uregex_end() and uregex_group() to return an error 
  *  indicating that there is no match information available.  Clears any
  *  match region that may have been set.
  *
  *    @param   regexp      The compiled regular expression.
  *    @param   index       The position (native) in the text at which a
  *                         uregex_findNext() should begin searching.
  *    @param   status      A reference to a UErrorCode to receive any errors.
  *    @stable ICU 4.6
  */
U_STABLE void U_EXPORT2 
uregex_reset64(URegularExpression  *regexp,
               int64_t               index,
               UErrorCode            *status);

/**
  * Sets the limits of the matching region for this URegularExpression.
  * The region is the part of the input string that will be considered when matching.
  * Invoking this method resets any saved state from the previous match, 
  * then sets the region to start at the index specified by the start parameter
  * and end at the index specified by the end parameter.
  *
  * Depending on the transparency and anchoring being used (see useTransparentBounds
  * and useAnchoringBounds), certain constructs such as anchors may behave differently
  * at or around the boundaries of the region
  *
  * The function will fail if start is greater than limit, or if either index
  *  is less than zero or greater than the length of the string being matched.
  *
  * @param regexp The compiled regular expression.
  * @param regionStart  The (native) index to begin searches at.
  * @param regionLimit  The (native) index to end searches at (exclusive).
  * @param status A pointer to a UErrorCode to receive any errors.
  * @stable ICU 4.0
  */
U_STABLE void U_EXPORT2
uregex_setRegion(URegularExpression   *regexp,
                 int32_t               regionStart,
                 int32_t               regionLimit,
                 UErrorCode           *status);

/**
  * 64bit version of uregex_setRegion.
  * Sets the limits of the matching region for this URegularExpression.
  * The region is the part of the input string that will be considered when matching.
  * Invoking this method resets any saved state from the previous match, 
  * then sets the region to start at the index specified by the start parameter
  * and end at the index specified by the end parameter.
  *
  * Depending on the transparency and anchoring being used (see useTransparentBounds
  * and useAnchoringBounds), certain constructs such as anchors may behave differently
  * at or around the boundaries of the region
  *
  * The function will fail if start is greater than limit, or if either index
  *  is less than zero or greater than the length of the string being matched.
  *
  * @param regexp The compiled regular expression.
  * @param regionStart  The (native) index to begin searches at.
  * @param regionLimit  The (native) index to end searches at (exclusive).
  * @param status A pointer to a UErrorCode to receive any errors.
  * @stable ICU 4.6
  */
U_STABLE void U_EXPORT2 
uregex_setRegion64(URegularExpression *regexp,
                 int64_t               regionStart,
                 int64_t               regionLimit,
                 UErrorCode           *status);

/**
  *  Set the matching region and the starting index for subsequent matches
  *  in a single operation.
  *  This is useful because the usual function for setting the starting
  *  index, urgex_reset(), also resets any region limits.
  *
  * @param regexp The compiled regular expression.
  * @param regionStart  The (native) index to begin searches at.
  * @param regionLimit  The (native) index to end searches at (exclusive).
  * @param startIndex   The index in the input text at which the next 
  *                     match operation should begin.
  * @param status A pointer to a UErrorCode to receive any errors.
  * @stable ICU 4.6
  */
U_STABLE void U_EXPORT2 
uregex_setRegionAndStart(URegularExpression *regexp,
                 int64_t               regionStart,
                 int64_t               regionLimit,
                 int64_t               startIndex,
                 UErrorCode           *status);

/**
  * Reports the start index of the matching region. Any matches found are limited to
  * to the region bounded by regionStart (inclusive) and regionEnd (exclusive).
  *
  * @param regexp The compiled regular expression.
  * @param status A pointer to a UErrorCode to receive any errors.
  * @return The starting (native) index of this matcher's region.
  * @stable ICU 4.0
  */
U_STABLE int32_t U_EXPORT2
uregex_regionStart(const  URegularExpression   *regexp,
                          UErrorCode           *status);

/**
  * 64bit version of uregex_regionStart.
  * Reports the start index of the matching region. Any matches found are limited to
  * to the region bounded by regionStart (inclusive) and regionEnd (exclusive).
  *
  * @param regexp The compiled regular expression.
  * @param status A pointer to a UErrorCode to receive any errors.
  * @return The starting (native) index of this matcher's region.
  * @stable ICU 4.6
  */
U_STABLE int64_t U_EXPORT2 
uregex_regionStart64(const  URegularExpression   *regexp,
                            UErrorCode           *status);

/**
  * Reports the end index (exclusive) of the matching region for this URegularExpression.
  * Any matches found are limited to to the region bounded by regionStart (inclusive)
  * and regionEnd (exclusive).
  *
  * @param regexp The compiled regular expression.
  * @param status A pointer to a UErrorCode to receive any errors.
  * @return The ending point (native) of this matcher's region.
  * @stable ICU 4.0
  */
U_STABLE int32_t U_EXPORT2
uregex_regionEnd(const  URegularExpression   *regexp,
                        UErrorCode           *status);

/**
  * 64bit version of uregex_regionEnd.
  * Reports the end index (exclusive) of the matching region for this URegularExpression.
  * Any matches found are limited to to the region bounded by regionStart (inclusive)
  * and regionEnd (exclusive).
  *
  * @param regexp The compiled regular expression.
  * @param status A pointer to a UErrorCode to receive any errors.
  * @return The ending point (native) of this matcher's region.
  * @stable ICU 4.6
  */
U_STABLE int64_t U_EXPORT2 
uregex_regionEnd64(const  URegularExpression   *regexp,
                          UErrorCode           *status);

/**
  * Queries the transparency of region bounds for this URegularExpression.
  * See useTransparentBounds for a description of transparent and opaque bounds.
  * By default, matching boundaries are opaque.
  *
  * @param regexp The compiled regular expression.
  * @param status A pointer to a UErrorCode to receive any errors.
  * @return TRUE if this matcher is using opaque bounds, false if it is not.
  * @stable ICU 4.0
  */
U_STABLE UBool U_EXPORT2
uregex_hasTransparentBounds(const  URegularExpression   *regexp,
                                   UErrorCode           *status);


/**
  * Sets the transparency of region bounds for this URegularExpression.
  * Invoking this function with an argument of TRUE will set matches to use transparent bounds.
  * If the boolean argument is FALSE, then opaque bounds will be used.
  *
  * Using transparent bounds, the boundaries of the matching region are transparent
  * to lookahead, lookbehind, and boundary matching constructs. Those constructs can
  * see text beyond the boundaries of the region while checking for a match.
  *
  * With opaque bounds, no text outside of the matching region is visible to lookahead,
  * lookbehind, and boundary matching constructs.
  *
  * By default, opaque bounds are used.
  *
  * @param   regexp The compiled regular expression.
  * @param   b      TRUE for transparent bounds; FALSE for opaque bounds
  * @param   status A pointer to a UErrorCode to receive any errors.
  * @stable ICU 4.0
  **/
U_STABLE void U_EXPORT2  
uregex_useTransparentBounds(URegularExpression   *regexp, 
                            UBool                b,
                            UErrorCode           *status);


/**
  * Return true if this URegularExpression is using anchoring bounds.
  * By default, anchoring region bounds are used.
  *
  * @param  regexp The compiled regular expression.
  * @param  status A pointer to a UErrorCode to receive any errors.
  * @return TRUE if this matcher is using anchoring bounds.
  * @stable ICU 4.0
  */
U_STABLE UBool U_EXPORT2
uregex_hasAnchoringBounds(const  URegularExpression   *regexp,
                                 UErrorCode           *status);


/**
  * Set whether this URegularExpression is using Anchoring Bounds for its region.
  * With anchoring bounds, pattern anchors such as ^ and $ will match at the start
  * and end of the region.  Without Anchoring Bounds, anchors will only match at
  * the positions they would in the complete text.
  *
  * Anchoring Bounds are the default for regions.
  *
  * @param regexp The compiled regular expression.
  * @param b      TRUE if to enable anchoring bounds; FALSE to disable them.
  * @param status A pointer to a UErrorCode to receive any errors.
  * @stable ICU 4.0
  */
U_STABLE void U_EXPORT2
uregex_useAnchoringBounds(URegularExpression   *regexp,
                          UBool                 b,
                          UErrorCode           *status);

/**
  * Return TRUE if the most recent matching operation touched the
  *  end of the text being processed.  In this case, additional input text could
  *  change the results of that match.
  *
  *  @param regexp The compiled regular expression.
  *  @param status A pointer to a UErrorCode to receive any errors.
  *  @return  TRUE if the most recent match hit the end of input
  *  @stable ICU 4.0
  */
U_STABLE UBool U_EXPORT2
uregex_hitEnd(const  URegularExpression   *regexp,
                     UErrorCode           *status);

/**
  * Return TRUE the most recent match succeeded and additional input could cause
  * it to fail. If this function returns false and a match was found, then more input
  * might change the match but the match won't be lost. If a match was not found,
  * then requireEnd has no meaning.
  *
  * @param regexp The compiled regular expression.
  * @param status A pointer to a UErrorCode to receive any errors.
  * @return TRUE  if more input could cause the most recent match to no longer match.
  * @stable ICU 4.0
  */
U_STABLE UBool U_EXPORT2   
uregex_requireEnd(const  URegularExpression   *regexp,
                         UErrorCode           *status);





/**
  *    Replaces every substring of the input that matches the pattern
  *    with the given replacement string.  This is a convenience function that
  *    provides a complete find-and-replace-all operation.
  *
  *    This method scans the input string looking for matches of the pattern. 
  *    Input that is not part of any match is copied unchanged to the
  *    destination buffer.  Matched regions are replaced in the output
  *    buffer by the replacement string.   The replacement string may contain
  *    references to capture groups; these take the form of $1, $2, etc.
  *
  *    @param   regexp             The compiled regular expression.
  *    @param   replacementText    A string containing the replacement text.
  *    @param   replacementLength  The length of the replacement string, or
  *                                -1 if it is NUL terminated.
  *    @param   destBuf            A (UChar *) buffer that will receive the result.
  *    @param   destCapacity       The capacity of the destination buffer.
  *    @param   status             A reference to a UErrorCode to receive any errors.
  *    @return                     The length of the string resulting from the find
  *                                and replace operation.  In the event that the
  *                                destination capacity is inadequate, the return value
  *                                is still the full length of the untruncated string.
  *    @stable ICU 3.0
  */
U_STABLE int32_t U_EXPORT2 
uregex_replaceAll(URegularExpression    *regexp,
                  const UChar           *replacementText,
                  int32_t                replacementLength,
                  UChar                 *destBuf,
                  int32_t                destCapacity,
                  UErrorCode            *status);

/**
  *    Replaces every substring of the input that matches the pattern
  *    with the given replacement string.  This is a convenience function that
  *    provides a complete find-and-replace-all operation.
  *
  *    This method scans the input string looking for matches of the pattern. 
  *    Input that is not part of any match is copied unchanged to the
  *    destination buffer.  Matched regions are replaced in the output
  *    buffer by the replacement string.   The replacement string may contain
  *    references to capture groups; these take the form of $1, $2, etc.
  *
  *    @param   regexp         The compiled regular expression.
  *    @param   replacement    A string containing the replacement text.
  *    @param   dest           A mutable UText that will receive the result.
  *                             If NULL, a new UText will be created (which may not be mutable).
  *    @param   status         A reference to a UErrorCode to receive any errors.
  *    @return                 A UText containing the results of the find and replace.
  *                             If a pre-allocated UText was provided, it will always be used and returned.
  *
  *    @stable ICU 4.6
  */
U_STABLE UText * U_EXPORT2 
uregex_replaceAllUText(URegularExpression *regexp,
                       UText              *replacement,
                       UText              *dest,
                       UErrorCode         *status);

/**
  *    Replaces the first substring of the input that matches the pattern
  *    with the given replacement string.  This is a convenience function that
  *    provides a complete find-and-replace operation.
  *
  *    This method scans the input string looking for a match of the pattern. 
  *    All input that is not part of the match is copied unchanged to the
  *    destination buffer.  The matched region is replaced in the output
  *    buffer by the replacement string.   The replacement string may contain
  *    references to capture groups; these take the form of $1, $2, etc.
  *
  *    @param   regexp             The compiled regular expression.
  *    @param   replacementText    A string containing the replacement text.
  *    @param   replacementLength  The length of the replacement string, or
  *                                -1 if it is NUL terminated.
  *    @param   destBuf            A (UChar *) buffer that will receive the result.
  *    @param   destCapacity       The capacity of the destination buffer.
  *    @param   status             a reference to a UErrorCode to receive any errors.
  *    @return                     The length of the string resulting from the find
  *                                and replace operation.  In the event that the
  *                                destination capacity is inadequate, the return value
  *                                is still the full length of the untruncated string.
  *    @stable ICU 3.0
  */
U_STABLE int32_t U_EXPORT2 
uregex_replaceFirst(URegularExpression  *regexp,
                    const UChar         *replacementText,
                    int32_t              replacementLength,
                    UChar               *destBuf,
                    int32_t              destCapacity,
                    UErrorCode          *status);

/**
  *    Replaces the first substring of the input that matches the pattern
  *    with the given replacement string.  This is a convenience function that
  *    provides a complete find-and-replace operation.
  *
  *    This method scans the input string looking for a match of the pattern. 
  *    All input that is not part of the match is copied unchanged to the
  *    destination buffer.  The matched region is replaced in the output
  *    buffer by the replacement string.   The replacement string may contain
  *    references to capture groups; these take the form of $1, $2, etc.
  *
  *    @param   regexp         The compiled regular expression.
  *    @param   replacement    A string containing the replacement text.
  *    @param   dest           A mutable UText that will receive the result.
  *                             If NULL, a new UText will be created (which may not be mutable).
  *    @param   status         A reference to a UErrorCode to receive any errors.
  *    @return                 A UText containing the results of the find and replace.
  *                             If a pre-allocated UText was provided, it will always be used and returned.
  *
  *    @stable ICU 4.6
  */
U_STABLE UText * U_EXPORT2 
uregex_replaceFirstUText(URegularExpression *regexp,
                         UText              *replacement,
                         UText              *dest,
                         UErrorCode         *status);

/**
  *   Implements a replace operation intended to be used as part of an
  *   incremental find-and-replace.
  *
  *   <p>The input string, starting from the end of the previous match and ending at
  *   the start of the current match, is appended to the destination string.  Then the
  *   replacement string is appended to the output string,
  *   including handling any substitutions of captured text.</p>
  *
  *   <p>A note on preflight computation of buffersize and error handling:
  *   Calls to uregex_appendReplacement() and uregex_appendTail() are
  *   designed to be chained, one after another, with the destination
  *   buffer pointer and buffer capacity updated after each in preparation
  *   to for the next.  If the destination buffer is exhausted partway through such a
  *   sequence, a U_BUFFER_OVERFLOW_ERROR status will be returned.  Normal
  *   ICU conventions are for a function to perform no action if it is
  *   called with an error status, but for this one case, uregex_appendRepacement()
  *   will operate normally so that buffer size computations will complete
  *   correctly.
  *
  *   <p>For simple, prepackaged, non-incremental find-and-replace
  *      operations, see replaceFirst() or replaceAll().</p>
  *
  *   @param   regexp      The regular expression object.  
  *   @param   replacementText The string that will replace the matched portion of the
  *                        input string as it is copied to the destination buffer.
  *                        The replacement text may contain references ($1, for
  *                        example) to capture groups from the match.
  *   @param   replacementLength  The length of the replacement text string,
  *                        or -1 if the string is NUL terminated.
  *   @param   destBuf     The buffer into which the results of the
  *                        find-and-replace are placed.  On return, this pointer
  *                        will be updated to refer to the beginning of the
  *                        unused portion of buffer, leaving it in position for
  *                        a subsequent call to this function.
  *   @param   destCapacity The size of the output buffer,  On return, this
  *                        parameter will be updated to reflect the space remaining
  *                        unused in the output buffer.
  *   @param   status      A reference to a UErrorCode to receive any errors. 
  *   @return              The length of the result string.  In the event that
  *                        destCapacity is inadequate, the full length of the
  *                        untruncated output string is returned.
  *
  *   @stable ICU 3.0
  *
  */
U_STABLE int32_t U_EXPORT2 
uregex_appendReplacement(URegularExpression    *regexp,
                         const UChar           *replacementText,
                         int32_t                replacementLength,
                         UChar                **destBuf,
                         int32_t               *destCapacity,
                         UErrorCode            *status);

/**
  *   Implements a replace operation intended to be used as part of an
  *   incremental find-and-replace.
  *
  *   <p>The input string, starting from the end of the previous match and ending at
  *   the start of the current match, is appended to the destination string.  Then the
  *   replacement string is appended to the output string,
  *   including handling any substitutions of captured text.</p>
  *
  *   <p>For simple, prepackaged, non-incremental find-and-replace
  *      operations, see replaceFirst() or replaceAll().</p>
  *
  *   @param   regexp      The regular expression object.  
  *   @param   replacementText The string that will replace the matched portion of the
  *                        input string as it is copied to the destination buffer.
  *                        The replacement text may contain references ($1, for
  *                        example) to capture groups from the match.
  *   @param   dest        A mutable UText that will receive the result. Must not be NULL.
  *   @param   status      A reference to a UErrorCode to receive any errors. 
  *
  *   @stable ICU 4.6
  */
U_STABLE void U_EXPORT2 
uregex_appendReplacementUText(URegularExpression    *regexp,
                              UText                 *replacementText,
                              UText                 *dest,
                              UErrorCode            *status);

/**
  * As the final step in a find-and-replace operation, append the remainder
  * of the input string, starting at the position following the last match,
  * to the destination string. <code>uregex_appendTail()</code> is intended 
  *  to be invoked after one or more invocations of the
  *  <code>uregex_appendReplacement()</code> function.
  *
  *   @param   regexp      The regular expression object.  This is needed to 
  *                        obtain the input string and with the position
  *                        of the last match within it.
  *   @param   destBuf     The buffer in which the results of the
  *                        find-and-replace are placed.  On return, the pointer
  *                        will be updated to refer to the beginning of the
  *                        unused portion of buffer.
  *   @param   destCapacity The size of the output buffer,  On return, this
  *                        value will be updated to reflect the space remaining
  *                        unused in the output buffer.
  *   @param   status      A reference to a UErrorCode to receive any errors. 
  *   @return              The length of the result string.  In the event that
  *                        destCapacity is inadequate, the full length of the
  *                        untruncated output string is returned.
  *
  *   @stable ICU 3.0
  */
U_STABLE int32_t U_EXPORT2 
uregex_appendTail(URegularExpression    *regexp,
                  UChar                **destBuf,
                  int32_t               *destCapacity,
                  UErrorCode            *status);

/**
  * As the final step in a find-and-replace operation, append the remainder
  * of the input string, starting at the position following the last match,
  * to the destination string. <code>uregex_appendTailUText()</code> is intended 
  *  to be invoked after one or more invocations of the
  *  <code>uregex_appendReplacementUText()</code> function.
  *
  *   @param   regexp      The regular expression object.  This is needed to 
  *                        obtain the input string and with the position
  *                        of the last match within it.
  *   @param   dest        A mutable UText that will receive the result. Must not be NULL.
  *
  *   @param status        Error code
  *
  *   @return              The destination UText.
  *
  *   @stable ICU 4.6
  */
U_STABLE UText * U_EXPORT2 
uregex_appendTailUText(URegularExpression    *regexp,
                       UText                 *dest,
                       UErrorCode            *status);

 /**
   * Split a string into fields.  Somewhat like split() from Perl.
   *  The pattern matches identify delimiters that separate the input
   *  into fields.  The input data between the matches becomes the
   *  fields themselves.
   *
   *  Each of the fields is copied from the input string to the destination
   *  buffer, and NUL terminated.  The position of each field within
   *  the destination buffer is returned in the destFields array.
   *
   *  If the delimiter pattern includes capture groups, the captured text will
   *  also appear in the destination array of output strings, interspersed
   *  with the fields.  This is similar to Perl, but differs from Java, 
   *  which ignores the presence of capture groups in the pattern.
   * 
   *  Trailing empty fields will always be returned, assuming sufficient
   *  destination capacity.  This differs from the default behavior for Java
   *  and Perl where trailing empty fields are not returned.
   *
   *  The number of strings produced by the split operation is returned.
   *  This count includes the strings from capture groups in the delimiter pattern.
   *  This behavior differs from Java, which ignores capture groups.
   * 
   *    @param   regexp      The compiled regular expression.
   *    @param   destBuf     A (UChar *) buffer to receive the fields that
   *                         are extracted from the input string. These
   *                         field pointers will refer to positions within the
   *                         destination buffer supplied by the caller.  Any
   *                         extra positions within the destFields array will be
   *                         set to NULL.
   *    @param   destCapacity The capacity of the destBuf.
   *    @param   requiredCapacity  The actual capacity required of the destBuf.
   *                         If destCapacity is too small, requiredCapacity will return 
   *                         the total capacity required to hold all of the output, and
   *                         a U_BUFFER_OVERFLOW_ERROR will be returned.
   *    @param   destFields  An array to be filled with the position of each
   *                         of the extracted fields within destBuf.
   *    @param   destFieldsCapacity  The number of elements in the destFields array.
   *                If the number of fields found is less than destFieldsCapacity,
   *                the extra destFields elements are set to zero.
   *                If destFieldsCapacity is too small, the trailing part of the
   *                input, including any field delimiters, is treated as if it
   *                were the last field - it is copied to the destBuf, and
   *                its position is in the destBuf is stored in the last element
   *                of destFields.  This behavior mimics that of Perl.  It is not
   *                an error condition, and no error status is returned when all destField
   *                positions are used.
   * @param status  A reference to a UErrorCode to receive any errors.
   * @return        The number of fields into which the input string was split.
   * @stable ICU 3.0
   */
U_STABLE int32_t U_EXPORT2 
uregex_split(   URegularExpression      *regexp,
                  UChar                 *destBuf,
                  int32_t                destCapacity,
                  int32_t               *requiredCapacity,
                  UChar                 *destFields[],
                  int32_t                destFieldsCapacity,
                  UErrorCode            *status);

  /**
   * Split a string into fields.  Somewhat like split() from Perl.
   * The pattern matches identify delimiters that separate the input
   *  into fields.  The input data between the matches becomes the
   *  fields themselves.
   * <p>
   * The behavior of this function is not very closely aligned with uregex_split();
   * instead, it is based on (and implemented directly on top of) the C++ split method.
   *
   * @param regexp  The compiled regular expression.
   * @param destFields    An array of mutable UText structs to receive the results of the split.
   *                If a field is NULL, a new UText is allocated to contain the results for
   *                that field. This new UText is not guaranteed to be mutable.
   * @param destFieldsCapacity  The number of elements in the destination array.
   *                If the number of fields found is less than destCapacity, the
   *                extra strings in the destination array are not altered.
   *                If the number of destination strings is less than the number
   *                of fields, the trailing part of the input string, including any
   *                field delimiters, is placed in the last destination string.
   *                This behavior mimics that of Perl.  It is not  an error condition, and no
   *                error status is returned when all destField positions are used.
   * @param status  A reference to a UErrorCode to receive any errors.
   * @return        The number of fields into which the input string was split.
   *
   * @stable ICU 4.6
   */
U_STABLE int32_t U_EXPORT2 
uregex_splitUText(URegularExpression    *regexp,
                  UText                 *destFields[],
                  int32_t                destFieldsCapacity,
                  UErrorCode            *status);

/**
 * Set a processing time limit for match operations with this URegularExpression.
 *
 * Some patterns, when matching certain strings, can run in exponential time.
 * For practical purposes, the match operation may appear to be in an
 * infinite loop.
 * When a limit is set a match operation will fail with an error if the
 * limit is exceeded.
 * <p>
 * The units of the limit are steps of the match engine.
 * Correspondence with actual processor time will depend on the speed
 * of the processor and the details of the specific pattern, but will
 * typically be on the order of milliseconds.
 * <p>
 * By default, the matching time is not limited.
 * <p>
 *
 * @param   regexp      The compiled regular expression.
 * @param   limit       The limit value, or 0 for no limit.
 * @param   status      A reference to a UErrorCode to receive any errors.
 * @stable ICU 4.0
 */
U_STABLE void U_EXPORT2
uregex_setTimeLimit(URegularExpression      *regexp,
                    int32_t                  limit,
                    UErrorCode              *status);

/**
 * Get the time limit for for matches with this URegularExpression.
 * A return value of zero indicates that there is no limit.
 *
 * @param   regexp      The compiled regular expression.
 * @param   status      A reference to a UErrorCode to receive any errors.
 * @return the maximum allowed time for a match, in units of processing steps.
 * @stable ICU 4.0
 */
U_STABLE int32_t U_EXPORT2
uregex_getTimeLimit(const URegularExpression      *regexp,
                          UErrorCode              *status);

/**
 * Set the amount of heap storage available for use by the match backtracking stack.
 * <p>
 * ICU uses a backtracking regular expression engine, with the backtrack stack
 * maintained on the heap.  This function sets the limit to the amount of memory
 * that can be used  for this purpose.  A backtracking stack overflow will
 * result in an error from the match operation that caused it.
 * <p>
 * A limit is desirable because a malicious or poorly designed pattern can use
 * excessive memory, potentially crashing the process.  A limit is enabled
 * by default.
 * <p>
 * @param   regexp      The compiled regular expression.
 * @param   limit       The maximum size, in bytes, of the matching backtrack stack.
 *                      A value of zero means no limit.
 *                      The limit must be greater than or equal to zero.
 * @param   status      A reference to a UErrorCode to receive any errors.
 *
 * @stable ICU 4.0
 */
U_STABLE void U_EXPORT2
uregex_setStackLimit(URegularExpression      *regexp,
                     int32_t                  limit,
                     UErrorCode              *status);

/**
 * Get the size of the heap storage available for use by the back tracking stack.
 *
 * @return  the maximum backtracking stack size, in bytes, or zero if the
 *          stack size is unlimited.
 * @stable ICU 4.0
 */
U_STABLE int32_t U_EXPORT2
uregex_getStackLimit(const URegularExpression      *regexp,
                           UErrorCode              *status);


/**
 * Function pointer for a regular expression matching callback function.
 * When set, a callback function will be called periodically during matching
 * operations.  If the call back function returns FALSE, the matching
 * operation will be terminated early.
 *
 * Note:  the callback function must not call other functions on this
 *        URegularExpression.
 *
 * @param context  context pointer.  The callback function will be invoked
 *                 with the context specified at the time that
 *                 uregex_setMatchCallback() is called.
 * @param steps    the accumulated processing time, in match steps, 
 *                 for this matching operation.
 * @return         TRUE to continue the matching operation.
 *                 FALSE to terminate the matching operation.
 * @stable ICU 4.0
 */
U_CDECL_BEGIN
typedef UBool U_CALLCONV URegexMatchCallback (
                   const void *context,
                   int32_t     steps);
U_CDECL_END

/**
 * Set a callback function for this URegularExpression.
 * During matching operations the function will be called periodically,
 * giving the application the opportunity to terminate a long-running
 * match.
 *
 * @param   regexp      The compiled regular expression.
 * @param   callback    A pointer to the user-supplied callback function.
 * @param   context     User context pointer.  The value supplied at the
 *                      time the callback function is set will be saved
 *                      and passed to the callback each time that it is called.
 * @param   status      A reference to a UErrorCode to receive any errors.
 * @stable ICU 4.0
 */
U_STABLE void U_EXPORT2
uregex_setMatchCallback(URegularExpression      *regexp,
                        URegexMatchCallback     *callback,
                        const void              *context,
                        UErrorCode              *status);


/**
 *  Get the callback function for this URegularExpression.
 *
 * @param   regexp      The compiled regular expression.
 * @param   callback    Out parameter, receives a pointer to the user-supplied 
 *                      callback function.
 * @param   context     Out parameter, receives the user context pointer that
 *                      was set when uregex_setMatchCallback() was called.
 * @param   status      A reference to a UErrorCode to receive any errors.
 * @stable ICU 4.0
 */
U_STABLE void U_EXPORT2
uregex_getMatchCallback(const URegularExpression    *regexp,
                        URegexMatchCallback        **callback,
                        const void                 **context,
                        UErrorCode                  *status);

/**
 * Function pointer for a regular expression find callback function.
 * 
 * When set, a callback function will be called during a find operation
 * and for operations that depend on find, such as findNext, split and some replace
 * operations like replaceFirst.
 * The callback will usually be called after each attempt at a match, but this is not a
 * guarantee that the callback will be invoked at each character.  For finds where the
 * match engine is invoked at each character, this may be close to true, but less likely
 * for more optimized loops where the pattern is known to only start, and the match
 * engine invoked, at certain characters.
 * When invoked, this callback will specify the index at which a match operation is about
 * to be attempted, giving the application the opportunity to terminate a long-running
 * find operation.
 * 
 * If the call back function returns FALSE, the find operation will be terminated early.
 *
 * Note:  the callback function must not call other functions on this
 *        URegularExpression
 *
 * @param context  context pointer.  The callback function will be invoked
 *                 with the context specified at the time that
 *                 uregex_setFindProgressCallback() is called.
 * @param matchIndex  the next index at which a match attempt will be attempted for this
 *                 find operation.  If this callback interrupts the search, this is the
 *                 index at which a find/findNext operation may be re-initiated.
 * @return         TRUE to continue the matching operation.
 *                 FALSE to terminate the matching operation.
 * @stable ICU 4.6
 */
U_CDECL_BEGIN
typedef UBool U_CALLCONV URegexFindProgressCallback (
                   const void *context,
                   int64_t     matchIndex);
U_CDECL_END


/**
 *  Set the find progress callback function for this URegularExpression.
 *
 * @param   regexp      The compiled regular expression.
 * @param   callback    A pointer to the user-supplied callback function.
 * @param   context     User context pointer.  The value supplied at the
 *                      time the callback function is set will be saved
 *                      and passed to the callback each time that it is called.
 * @param   status      A reference to a UErrorCode to receive any errors.
 * @stable ICU 4.6
 */
U_STABLE void U_EXPORT2
uregex_setFindProgressCallback(URegularExpression              *regexp,
                                URegexFindProgressCallback      *callback,
                                const void                      *context,
                                UErrorCode                      *status);

/**
 *  Get the find progress callback function for this URegularExpression.
 *
 * @param   regexp      The compiled regular expression.
 * @param   callback    Out parameter, receives a pointer to the user-supplied 
 *                      callback function.
 * @param   context     Out parameter, receives the user context pointer that
 *                      was set when uregex_setFindProgressCallback() was called.
 * @param   status      A reference to a UErrorCode to receive any errors.
 * @stable ICU 4.6
 */
U_STABLE void U_EXPORT2
uregex_getFindProgressCallback(const URegularExpression          *regexp,
                                URegexFindProgressCallback        **callback,
                                const void                        **context,
                                UErrorCode                        *status);

#endif   /*  !UCONFIG_NO_REGULAR_EXPRESSIONS  */
#endif   /*  UREGEX_H  */
