/*
*******************************************************************************
* Copyright (C) 1997-2015, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*/

#if defined(STARBOARD)
#include "starboard/client_porting/poem/assert_poem.h"
#include "starboard/client_porting/poem/string_poem.h"
#endif  // defined(STARBOARD)
#include "uassert.h"
#include "decimalformatpattern.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/dcfmtsym.h"
#include "unicode/format.h"
#include "unicode/utf16.h"
#include "decimalformatpatternimpl.h" 


#ifdef FMT_DEBUG
#define debug(x) printf("%s:%d: %s\n", __FILE__,__LINE__, x);
#else
#define debug(x)
#endif

U_NAMESPACE_BEGIN

// TODO: Travis Keep: Copied from numfmt.cpp
static int32_t kDoubleIntegerDigits  = 309;
static int32_t kDoubleFractionDigits = 340;


// TODO: Travis Keep: Copied from numfmt.cpp
static int32_t gDefaultMaxIntegerDigits = 2000000000;

// TODO: Travis Keep: This function was copied from format.cpp
static void syntaxError(const UnicodeString& pattern,
                         int32_t pos,
                         UParseError& parseError) {
    parseError.offset = pos;
    parseError.line=0;  // we are not using line number

    // for pre-context
    int32_t start = (pos < U_PARSE_CONTEXT_LEN)? 0 : (pos - (U_PARSE_CONTEXT_LEN-1
                                                             /* subtract 1 so that we have room for null*/));
    int32_t stop  = pos;
    pattern.extract(start,stop-start,parseError.preContext,0);
    //null terminate the buffer
    parseError.preContext[stop-start] = 0;

    //for post-context
    start = pos+1;
    stop  = ((pos+U_PARSE_CONTEXT_LEN)<=pattern.length()) ? (pos+(U_PARSE_CONTEXT_LEN-1)) :
        pattern.length();
    pattern.extract(start,stop-start,parseError.postContext,0);
    //null terminate the buffer
    parseError.postContext[stop-start]= 0;
}

DecimalFormatPattern::DecimalFormatPattern()
        : fMinimumIntegerDigits(1),
          fMaximumIntegerDigits(gDefaultMaxIntegerDigits),
          fMinimumFractionDigits(0),
          fMaximumFractionDigits(3),
          fUseSignificantDigits(FALSE),
          fMinimumSignificantDigits(1),
          fMaximumSignificantDigits(6),
          fUseExponentialNotation(FALSE),
          fMinExponentDigits(0),
          fExponentSignAlwaysShown(FALSE),
          fCurrencySignCount(fgCurrencySignCountZero),
          fGroupingUsed(TRUE),
          fGroupingSize(0),
          fGroupingSize2(0),
          fMultiplier(1),
          fDecimalSeparatorAlwaysShown(FALSE),
          fFormatWidth(0),
          fRoundingIncrementUsed(FALSE),
          fRoundingIncrement(),
          fPad(kDefaultPad),
          fNegPatternsBogus(TRUE),
          fPosPatternsBogus(TRUE),
          fNegPrefixPattern(),
          fNegSuffixPattern(),
          fPosPrefixPattern(),
          fPosSuffixPattern(),
          fPadPosition(DecimalFormatPattern::kPadBeforePrefix) {
}


DecimalFormatPatternParser::DecimalFormatPatternParser() :
    fZeroDigit(kPatternZeroDigit),
    fSigDigit(kPatternSignificantDigit),
    fGroupingSeparator((UChar)kPatternGroupingSeparator),
    fDecimalSeparator((UChar)kPatternDecimalSeparator),
    fPercent((UChar)kPatternPercent),
    fPerMill((UChar)kPatternPerMill),
    fDigit((UChar)kPatternDigit),
    fSeparator((UChar)kPatternSeparator),
    fExponent((UChar)kPatternExponent),
    fPlus((UChar)kPatternPlus),
    fMinus((UChar)kPatternMinus),
    fPadEscape((UChar)kPatternPadEscape) {
}

void DecimalFormatPatternParser::useSymbols(
        const DecimalFormatSymbols& symbols) {
    fZeroDigit = symbols.getConstSymbol(
            DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
    fSigDigit = symbols.getConstSymbol(
            DecimalFormatSymbols::kSignificantDigitSymbol).char32At(0);
    fGroupingSeparator = symbols.getConstSymbol(
            DecimalFormatSymbols::kGroupingSeparatorSymbol);
    fDecimalSeparator = symbols.getConstSymbol(
            DecimalFormatSymbols::kDecimalSeparatorSymbol);
    fPercent = symbols.getConstSymbol(
            DecimalFormatSymbols::kPercentSymbol);
    fPerMill = symbols.getConstSymbol(
            DecimalFormatSymbols::kPerMillSymbol);
    fDigit = symbols.getConstSymbol(
            DecimalFormatSymbols::kDigitSymbol);
    fSeparator = symbols.getConstSymbol(
            DecimalFormatSymbols::kPatternSeparatorSymbol);
    fExponent = symbols.getConstSymbol(
            DecimalFormatSymbols::kExponentialSymbol);
    fPlus = symbols.getConstSymbol(
            DecimalFormatSymbols::kPlusSignSymbol);
    fMinus = symbols.getConstSymbol(
            DecimalFormatSymbols::kMinusSignSymbol);
    fPadEscape = symbols.getConstSymbol(
            DecimalFormatSymbols::kPadEscapeSymbol);
}

void
DecimalFormatPatternParser::applyPatternWithoutExpandAffix(
        const UnicodeString& pattern,
        DecimalFormatPattern& out,
        UParseError& parseError,
        UErrorCode& status) {
    if (U_FAILURE(status))
    {
        return;
    }
    out = DecimalFormatPattern();

    // Clear error struct
    parseError.offset = -1;
    parseError.preContext[0] = parseError.postContext[0] = (UChar)0;

    // TODO: Travis Keep: This won't always work.
    UChar nineDigit = (UChar)(fZeroDigit + 9);
    int32_t digitLen = fDigit.length();
    int32_t groupSepLen = fGroupingSeparator.length();
    int32_t decimalSepLen = fDecimalSeparator.length();

    int32_t pos = 0;
    int32_t patLen = pattern.length();
    // Part 0 is the positive pattern.  Part 1, if present, is the negative
    // pattern.
    for (int32_t part=0; part<2 && pos<patLen; ++part) {
        // The subpart ranges from 0 to 4: 0=pattern proper, 1=prefix,
        // 2=suffix, 3=prefix in quote, 4=suffix in quote.  Subpart 0 is
        // between the prefix and suffix, and consists of pattern
        // characters.  In the prefix and suffix, percent, perMill, and
        // currency symbols are recognized and translated.
        int32_t subpart = 1, sub0Start = 0, sub0Limit = 0, sub2Limit = 0;

        // It's important that we don't change any fields of this object
        // prematurely.  We set the following variables for the multiplier,
        // grouping, etc., and then only change the actual object fields if
        // everything parses correctly.  This also lets us register
        // the data from part 0 and ignore the part 1, except for the
        // prefix and suffix.
        UnicodeString prefix;
        UnicodeString suffix;
        int32_t decimalPos = -1;
        int32_t multiplier = 1;
        int32_t digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0, sigDigitCount = 0;
        int8_t groupingCount = -1;
        int8_t groupingCount2 = -1;
        int32_t padPos = -1;
        UChar32 padChar = 0;
        int32_t roundingPos = -1;
        DigitList roundingInc;
        int8_t expDigits = -1;
        UBool expSignAlways = FALSE;

        // The affix is either the prefix or the suffix.
        UnicodeString* affix = &prefix;

        int32_t start = pos;
        UBool isPartDone = FALSE;
        UChar32 ch;

        for (; !isPartDone && pos < patLen; ) {
            // Todo: account for surrogate pairs
            ch = pattern.char32At(pos);
            switch (subpart) {
            case 0: // Pattern proper subpart (between prefix & suffix)
                // Process the digits, decimal, and grouping characters.  We
                // record five pieces of information.  We expect the digits
                // to occur in the pattern ####00.00####, and we record the
                // number of left digits, zero (central) digits, and right
                // digits.  The position of the last grouping character is
                // recorded (should be somewhere within the first two blocks
                // of characters), as is the position of the decimal point,
                // if any (should be in the zero digits).  If there is no
                // decimal point, then there should be no right digits.
                if (pattern.compare(pos, digitLen, fDigit) == 0) {
                    if (zeroDigitCount > 0 || sigDigitCount > 0) {
                        ++digitRightCount;
                    } else {
                        ++digitLeftCount;
                    }
                    if (groupingCount >= 0 && decimalPos < 0) {
                        ++groupingCount;
                    }
                    pos += digitLen;
                } else if ((ch >= fZeroDigit && ch <= nineDigit) ||
                           ch == fSigDigit) {
                    if (digitRightCount > 0) {
                        // Unexpected '0'
                        debug("Unexpected '0'")
                        status = U_UNEXPECTED_TOKEN;
                        syntaxError(pattern,pos,parseError);
                        return;
                    }
                    if (ch == fSigDigit) {
                        ++sigDigitCount;
                    } else {
                        if (ch != fZeroDigit && roundingPos < 0) {
                            roundingPos = digitLeftCount + zeroDigitCount;
                        }
                        if (roundingPos >= 0) {
                            roundingInc.append((char)(ch - fZeroDigit + '0'));
                        }
                        ++zeroDigitCount;
                    }
                    if (groupingCount >= 0 && decimalPos < 0) {
                        ++groupingCount;
                    }
                    pos += U16_LENGTH(ch);
                } else if (pattern.compare(pos, groupSepLen, fGroupingSeparator) == 0) {
                    if (decimalPos >= 0) {
                        // Grouping separator after decimal
                        debug("Grouping separator after decimal")
                        status = U_UNEXPECTED_TOKEN;
                        syntaxError(pattern,pos,parseError);
                        return;
                    }
                    groupingCount2 = groupingCount;
                    groupingCount = 0;
                    pos += groupSepLen;
                } else if (pattern.compare(pos, decimalSepLen, fDecimalSeparator) == 0) {
                    if (decimalPos >= 0) {
                        // Multiple decimal separators
                        debug("Multiple decimal separators")
                        status = U_MULTIPLE_DECIMAL_SEPARATORS;
                        syntaxError(pattern,pos,parseError);
                        return;
                    }
                    // Intentionally incorporate the digitRightCount,
                    // even though it is illegal for this to be > 0
                    // at this point.  We check pattern syntax below.
                    decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
                    pos += decimalSepLen;
                } else {
                    if (pattern.compare(pos, fExponent.length(), fExponent) == 0) {
                        if (expDigits >= 0) {
                            // Multiple exponential symbols
                            debug("Multiple exponential symbols")
                            status = U_MULTIPLE_EXPONENTIAL_SYMBOLS;
                            syntaxError(pattern,pos,parseError);
                            return;
                        }
                        if (groupingCount >= 0) {
                            // Grouping separator in exponential pattern
                            debug("Grouping separator in exponential pattern")
                            status = U_MALFORMED_EXPONENTIAL_PATTERN;
                            syntaxError(pattern,pos,parseError);
                            return;
                        }
                        pos += fExponent.length();
                        // Check for positive prefix
                        if (pos < patLen
                            && pattern.compare(pos, fPlus.length(), fPlus) == 0) {
                            expSignAlways = TRUE;
                            pos += fPlus.length();
                        }
                        // Use lookahead to parse out the exponential part of the
                        // pattern, then jump into suffix subpart.
                        expDigits = 0;
                        while (pos < patLen &&
                               pattern.char32At(pos) == fZeroDigit) {
                            ++expDigits;
                            pos += U16_LENGTH(fZeroDigit);
                        }

                        // 1. Require at least one mantissa pattern digit
                        // 2. Disallow "#+ @" in mantissa
                        // 3. Require at least one exponent pattern digit
                        if (((digitLeftCount + zeroDigitCount) < 1 &&
                             (sigDigitCount + digitRightCount) < 1) ||
                            (sigDigitCount > 0 && digitLeftCount > 0) ||
                            expDigits < 1) {
                            // Malformed exponential pattern
                            debug("Malformed exponential pattern")
                            status = U_MALFORMED_EXPONENTIAL_PATTERN;
                            syntaxError(pattern,pos,parseError);
                            return;
                        }
                    }
                    // Transition to suffix subpart
                    subpart = 2; // suffix subpart
                    affix = &suffix;
                    sub0Limit = pos;
                    continue;
                }
                break;
            case 1: // Prefix subpart
            case 2: // Suffix subpart
                // Process the prefix / suffix characters
                // Process unquoted characters seen in prefix or suffix
                // subpart.

                // Several syntax characters implicitly begins the
                // next subpart if we are in the prefix; otherwise
                // they are illegal if unquoted.
                if (!pattern.compare(pos, digitLen, fDigit) ||
                    !pattern.compare(pos, groupSepLen, fGroupingSeparator) ||
                    !pattern.compare(pos, decimalSepLen, fDecimalSeparator) ||
                    (ch >= fZeroDigit && ch <= nineDigit) ||
                    ch == fSigDigit) {
                    if (subpart == 1) { // prefix subpart
                        subpart = 0; // pattern proper subpart
                        sub0Start = pos; // Reprocess this character
                        continue;
                    } else {
                        status = U_UNQUOTED_SPECIAL;
                        syntaxError(pattern,pos,parseError);
                        return;
                    }
                } else if (ch == kCurrencySign) {
                    affix->append(kQuote); // Encode currency
                    // Use lookahead to determine if the currency sign is
                    // doubled or not.
                    U_ASSERT(U16_LENGTH(kCurrencySign) == 1);
                    if ((pos+1) < pattern.length() && pattern[pos+1] == kCurrencySign) {
                        affix->append(kCurrencySign);
                        ++pos; // Skip over the doubled character
                        if ((pos+1) < pattern.length() &&
                            pattern[pos+1] == kCurrencySign) {
                            affix->append(kCurrencySign);
                            ++pos; // Skip over the doubled character
                            out.fCurrencySignCount = fgCurrencySignCountInPluralFormat;
                        } else {
                            out.fCurrencySignCount = fgCurrencySignCountInISOFormat;
                        }
                    } else {
                        out.fCurrencySignCount = fgCurrencySignCountInSymbolFormat;
                    }
                    // Fall through to append(ch)
                } else if (ch == kQuote) {
                    // A quote outside quotes indicates either the opening
                    // quote or two quotes, which is a quote literal.  That is,
                    // we have the first quote in 'do' or o''clock.
                    U_ASSERT(U16_LENGTH(kQuote) == 1);
                    ++pos;
                    if (pos < pattern.length() && pattern[pos] == kQuote) {
                        affix->append(kQuote); // Encode quote
                        // Fall through to append(ch)
                    } else {
                        subpart += 2; // open quote
                        continue;
                    }
                } else if (pattern.compare(pos, fSeparator.length(), fSeparator) == 0) {
                    // Don't allow separators in the prefix, and don't allow
                    // separators in the second pattern (part == 1).
                    if (subpart == 1 || part == 1) {
                        // Unexpected separator
                        debug("Unexpected separator")
                        status = U_UNEXPECTED_TOKEN;
                        syntaxError(pattern,pos,parseError);
                        return;
                    }
                    sub2Limit = pos;
                    isPartDone = TRUE; // Go to next part
                    pos += fSeparator.length();
                    break;
                } else if (pattern.compare(pos, fPercent.length(), fPercent) == 0) {
                    // Next handle characters which are appended directly.
                    if (multiplier != 1) {
                        // Too many percent/perMill characters
                        debug("Too many percent characters")
                        status = U_MULTIPLE_PERCENT_SYMBOLS;
                        syntaxError(pattern,pos,parseError);
                        return;
                    }
                    affix->append(kQuote); // Encode percent/perMill
                    affix->append(kPatternPercent); // Use unlocalized pattern char
                    multiplier = 100;
                    pos += fPercent.length();
                    break;
                } else if (pattern.compare(pos, fPerMill.length(), fPerMill) == 0) {
                    // Next handle characters which are appended directly.
                    if (multiplier != 1) {
                        // Too many percent/perMill characters
                        debug("Too many perMill characters")
                        status = U_MULTIPLE_PERMILL_SYMBOLS;
                        syntaxError(pattern,pos,parseError);
                        return;
                    }
                    affix->append(kQuote); // Encode percent/perMill
                    affix->append(kPatternPerMill); // Use unlocalized pattern char
                    multiplier = 1000;
                    pos += fPerMill.length();
                    break;
                } else if (pattern.compare(pos, fPadEscape.length(), fPadEscape) == 0) {
                    if (padPos >= 0 ||               // Multiple pad specifiers
                        (pos+1) == pattern.length()) { // Nothing after padEscape
                        debug("Multiple pad specifiers")
                        status = U_MULTIPLE_PAD_SPECIFIERS;
                        syntaxError(pattern,pos,parseError);
                        return;
                    }
                    padPos = pos;
                    pos += fPadEscape.length();
                    padChar = pattern.char32At(pos);
                    pos += U16_LENGTH(padChar);
                    break;
                } else if (pattern.compare(pos, fMinus.length(), fMinus) == 0) {
                    affix->append(kQuote); // Encode minus
                    affix->append(kPatternMinus);
                    pos += fMinus.length();
                    break;
                } else if (pattern.compare(pos, fPlus.length(), fPlus) == 0) {
                    affix->append(kQuote); // Encode plus
                    affix->append(kPatternPlus);
                    pos += fPlus.length();
                    break;
                }
                // Unquoted, non-special characters fall through to here, as
                // well as other code which needs to append something to the
                // affix.
                affix->append(ch);
                pos += U16_LENGTH(ch);
                break;
            case 3: // Prefix subpart, in quote
            case 4: // Suffix subpart, in quote
                // A quote within quotes indicates either the closing
                // quote or two quotes, which is a quote literal.  That is,
                // we have the second quote in 'do' or 'don''t'.
                if (ch == kQuote) {
                    ++pos;
                    if (pos < pattern.length() && pattern[pos] == kQuote) {
                        affix->append(kQuote); // Encode quote
                        // Fall through to append(ch)
                    } else {
                        subpart -= 2; // close quote
                        continue;
                    }
                }
                affix->append(ch);
                pos += U16_LENGTH(ch);
                break;
            }
        }

        if (sub0Limit == 0) {
            sub0Limit = pattern.length();
        }

        if (sub2Limit == 0) {
            sub2Limit = pattern.length();
        }

        /* Handle patterns with no '0' pattern character.  These patterns
         * are legal, but must be recodified to make sense.  "##.###" ->
         * "#0.###".  ".###" -> ".0##".
         *
         * We allow patterns of the form "####" to produce a zeroDigitCount
         * of zero (got that?); although this seems like it might make it
         * possible for format() to produce empty strings, format() checks
         * for this condition and outputs a zero digit in this situation.
         * Having a zeroDigitCount of zero yields a minimum integer digits
         * of zero, which allows proper round-trip patterns.  We don't want
         * "#" to become "#0" when toPattern() is called (even though that's
         * what it really is, semantically).
         */
        if (zeroDigitCount == 0 && sigDigitCount == 0 &&
            digitLeftCount > 0 && decimalPos >= 0) {
            // Handle "###.###" and "###." and ".###"
            int n = decimalPos;
            if (n == 0)
                ++n; // Handle ".###"
            digitRightCount = digitLeftCount - n;
            digitLeftCount = n - 1;
            zeroDigitCount = 1;
        }

        // Do syntax checking on the digits, decimal points, and quotes.
        if ((decimalPos < 0 && digitRightCount > 0 && sigDigitCount == 0) ||
            (decimalPos >= 0 &&
             (sigDigitCount > 0 ||
              decimalPos < digitLeftCount ||
              decimalPos > (digitLeftCount + zeroDigitCount))) ||
            groupingCount == 0 || groupingCount2 == 0 ||
            (sigDigitCount > 0 && zeroDigitCount > 0) ||
            subpart > 2)
        { // subpart > 2 == unmatched quote
            debug("Syntax error")
            status = U_PATTERN_SYNTAX_ERROR;
            syntaxError(pattern,pos,parseError);
            return;
        }

        // Make sure pad is at legal position before or after affix.
        if (padPos >= 0) {
            if (padPos == start) {
                padPos = DecimalFormatPattern::kPadBeforePrefix;
            } else if (padPos+2 == sub0Start) {
                padPos = DecimalFormatPattern::kPadAfterPrefix;
            } else if (padPos == sub0Limit) {
                padPos = DecimalFormatPattern::kPadBeforeSuffix;
            } else if (padPos+2 == sub2Limit) {
                padPos = DecimalFormatPattern::kPadAfterSuffix;
            } else {
                // Illegal pad position
                debug("Illegal pad position")
                status = U_ILLEGAL_PAD_POSITION;
                syntaxError(pattern,pos,parseError);
                return;
            }
        }

        if (part == 0) {
            out.fPosPatternsBogus = FALSE;
            out.fPosPrefixPattern = prefix;
            out.fPosSuffixPattern = suffix;
            out.fNegPatternsBogus = TRUE;
            out.fNegPrefixPattern.remove();
            out.fNegSuffixPattern.remove();

            out.fUseExponentialNotation = (expDigits >= 0);
            if (out.fUseExponentialNotation) {
              out.fMinExponentDigits = expDigits;
            }
            out.fExponentSignAlwaysShown = expSignAlways;
            int32_t digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
            // The effectiveDecimalPos is the position the decimal is at or
            // would be at if there is no decimal.  Note that if
            // decimalPos<0, then digitTotalCount == digitLeftCount +
            // zeroDigitCount.
            int32_t effectiveDecimalPos = decimalPos >= 0 ? decimalPos : digitTotalCount;
            UBool isSigDig = (sigDigitCount > 0);
            out.fUseSignificantDigits = isSigDig;
            if (isSigDig) {
                out.fMinimumSignificantDigits = sigDigitCount;
                out.fMaximumSignificantDigits = sigDigitCount + digitRightCount;
            } else {
                int32_t minInt = effectiveDecimalPos - digitLeftCount;
                out.fMinimumIntegerDigits = minInt;
                out.fMaximumIntegerDigits = out.fUseExponentialNotation
                    ? digitLeftCount + out.fMinimumIntegerDigits
                    : gDefaultMaxIntegerDigits;
                out.fMaximumFractionDigits = decimalPos >= 0
                    ? (digitTotalCount - decimalPos) : 0;
                out.fMinimumFractionDigits = decimalPos >= 0
                    ? (digitLeftCount + zeroDigitCount - decimalPos) : 0;
            }
            out.fGroupingUsed = groupingCount > 0;
            out.fGroupingSize = (groupingCount > 0) ? groupingCount : 0;
            out.fGroupingSize2 = (groupingCount2 > 0 && groupingCount2 != groupingCount)
                ? groupingCount2 : 0;
            out.fMultiplier = multiplier;
            out.fDecimalSeparatorAlwaysShown = decimalPos == 0
                    || decimalPos == digitTotalCount;
            if (padPos >= 0) {
                out.fPadPosition = (DecimalFormatPattern::EPadPosition) padPos;
                // To compute the format width, first set up sub0Limit -
                // sub0Start.  Add in prefix/suffix length later.

                // fFormatWidth = prefix.length() + suffix.length() +
                //    sub0Limit - sub0Start;
                out.fFormatWidth = sub0Limit - sub0Start;
                out.fPad = padChar;
            } else {
                out.fFormatWidth = 0;
            }
            if (roundingPos >= 0) {
                out.fRoundingIncrementUsed = TRUE;
                roundingInc.setDecimalAt(effectiveDecimalPos - roundingPos);
                out.fRoundingIncrement = roundingInc;
            } else {
                out.fRoundingIncrementUsed = FALSE;
            }
        } else {
            out.fNegPatternsBogus = FALSE;
            out.fNegPrefixPattern = prefix;
            out.fNegSuffixPattern = suffix;
        }
    }

    if (pattern.length() == 0) {
        out.fNegPatternsBogus = TRUE;
        out.fNegPrefixPattern.remove();
        out.fNegSuffixPattern.remove();
        out.fPosPatternsBogus = FALSE;
        out.fPosPrefixPattern.remove();
        out.fPosSuffixPattern.remove();

        out.fMinimumIntegerDigits = 0;
        out.fMaximumIntegerDigits = kDoubleIntegerDigits;
        out.fMinimumFractionDigits = 0;
        out.fMaximumFractionDigits = kDoubleFractionDigits;

        out.fUseExponentialNotation = FALSE;
        out.fCurrencySignCount = fgCurrencySignCountZero;
        out.fGroupingUsed = FALSE;
        out.fGroupingSize = 0;
        out.fGroupingSize2 = 0;
        out.fMultiplier = 1;
        out.fDecimalSeparatorAlwaysShown = FALSE;
        out.fFormatWidth = 0;
        out.fRoundingIncrementUsed = FALSE;
    }

    // If there was no negative pattern, or if the negative pattern is
    // identical to the positive pattern, then prepend the minus sign to the
    // positive pattern to form the negative pattern.
    if (out.fNegPatternsBogus ||
        (out.fNegPrefixPattern == out.fPosPrefixPattern
         && out.fNegSuffixPattern == out.fPosSuffixPattern)) {
        out.fNegPatternsBogus = FALSE;
        out.fNegSuffixPattern = out.fPosSuffixPattern;
        out.fNegPrefixPattern.remove();
        out.fNegPrefixPattern.append(kQuote).append(kPatternMinus)
            .append(out.fPosPrefixPattern);
    }
    // TODO: Deprecate/Remove out.fNegSuffixPattern and 3 other fields.
    AffixPattern::parseAffixString( 
            out.fNegSuffixPattern, out.fNegSuffixAffix, status);
    AffixPattern::parseAffixString(
            out.fPosSuffixPattern, out.fPosSuffixAffix, status);
    AffixPattern::parseAffixString(
            out.fNegPrefixPattern, out.fNegPrefixAffix, status);
    AffixPattern::parseAffixString(
            out.fPosPrefixPattern, out.fPosPrefixAffix, status);
}

U_NAMESPACE_END

#endif /* !UCONFIG_NO_FORMATTING */
