164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// Copyright (C) 2016 and later: Unicode, Inc. and others. 264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html 3fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius/* 4fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius******************************************************************************* 5c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert* Copyright (C) 1997-2015, International Business Machines Corporation and * 6fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius* others. All Rights Reserved. * 7fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius******************************************************************************* 8fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius*/ 9fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 10fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "uassert.h" 11fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "decimalformatpattern.h" 12fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 13fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !UCONFIG_NO_FORMATTING 14fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 15fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/dcfmtsym.h" 16fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/format.h" 17fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/utf16.h" 18c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#include "decimalformatpatternimpl.h" 19c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert 20fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 21fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#ifdef FMT_DEBUG 22fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#define debug(x) printf("%s:%d: %s\n", __FILE__,__LINE__, x); 23fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#else 24fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#define debug(x) 25fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif 26fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 27fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_NAMESPACE_BEGIN 28fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 29fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// TODO: Travis Keep: Copied from numfmt.cpp 30fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic int32_t kDoubleIntegerDigits = 309; 31fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic int32_t kDoubleFractionDigits = 340; 32fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 33fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 34fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// TODO: Travis Keep: Copied from numfmt.cpp 35fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic int32_t gDefaultMaxIntegerDigits = 2000000000; 36fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 37fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// TODO: Travis Keep: This function was copied from format.cpp 38fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic void syntaxError(const UnicodeString& pattern, 39fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t pos, 40fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UParseError& parseError) { 41fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius parseError.offset = pos; 42fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius parseError.line=0; // we are not using line number 43fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 44fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // for pre-context 45fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t start = (pos < U_PARSE_CONTEXT_LEN)? 0 : (pos - (U_PARSE_CONTEXT_LEN-1 46fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius /* subtract 1 so that we have room for null*/)); 47fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t stop = pos; 48fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pattern.extract(start,stop-start,parseError.preContext,0); 49fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius //null terminate the buffer 50fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius parseError.preContext[stop-start] = 0; 51fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 52fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius //for post-context 53fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius start = pos+1; 54fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius stop = ((pos+U_PARSE_CONTEXT_LEN)<=pattern.length()) ? (pos+(U_PARSE_CONTEXT_LEN-1)) : 55fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pattern.length(); 56fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pattern.extract(start,stop-start,parseError.postContext,0); 57fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius //null terminate the buffer 58fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius parseError.postContext[stop-start]= 0; 59fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 60fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 61fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusDecimalFormatPattern::DecimalFormatPattern() 62fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius : fMinimumIntegerDigits(1), 63fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fMaximumIntegerDigits(gDefaultMaxIntegerDigits), 64fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fMinimumFractionDigits(0), 65fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fMaximumFractionDigits(3), 66fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fUseSignificantDigits(FALSE), 67fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fMinimumSignificantDigits(1), 68fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fMaximumSignificantDigits(6), 69fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fUseExponentialNotation(FALSE), 70fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fMinExponentDigits(0), 71fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fExponentSignAlwaysShown(FALSE), 72fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fCurrencySignCount(fgCurrencySignCountZero), 73fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fGroupingUsed(TRUE), 74fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fGroupingSize(0), 75fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fGroupingSize2(0), 76fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fMultiplier(1), 77fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fDecimalSeparatorAlwaysShown(FALSE), 78fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fFormatWidth(0), 79fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fRoundingIncrementUsed(FALSE), 80fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fRoundingIncrement(), 81c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert fPad(kDefaultPad), 82fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fNegPatternsBogus(TRUE), 83fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fPosPatternsBogus(TRUE), 84fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fNegPrefixPattern(), 85fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fNegSuffixPattern(), 86fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fPosPrefixPattern(), 87fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fPosSuffixPattern(), 88fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fPadPosition(DecimalFormatPattern::kPadBeforePrefix) { 89fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 90fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 91fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 92fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusDecimalFormatPatternParser::DecimalFormatPatternParser() : 93fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fZeroDigit(kPatternZeroDigit), 94fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fSigDigit(kPatternSignificantDigit), 95fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fGroupingSeparator((UChar)kPatternGroupingSeparator), 96fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fDecimalSeparator((UChar)kPatternDecimalSeparator), 97fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fPercent((UChar)kPatternPercent), 98fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fPerMill((UChar)kPatternPerMill), 99fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fDigit((UChar)kPatternDigit), 100fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fSeparator((UChar)kPatternSeparator), 101fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fExponent((UChar)kPatternExponent), 102fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fPlus((UChar)kPatternPlus), 103fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fMinus((UChar)kPatternMinus), 104fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fPadEscape((UChar)kPatternPadEscape) { 105fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 106fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 107fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid DecimalFormatPatternParser::useSymbols( 108fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const DecimalFormatSymbols& symbols) { 109fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fZeroDigit = symbols.getConstSymbol( 110fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius DecimalFormatSymbols::kZeroDigitSymbol).char32At(0); 111fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fSigDigit = symbols.getConstSymbol( 112fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius DecimalFormatSymbols::kSignificantDigitSymbol).char32At(0); 113fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fGroupingSeparator = symbols.getConstSymbol( 114fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius DecimalFormatSymbols::kGroupingSeparatorSymbol); 115fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fDecimalSeparator = symbols.getConstSymbol( 116fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius DecimalFormatSymbols::kDecimalSeparatorSymbol); 117fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fPercent = symbols.getConstSymbol( 118fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius DecimalFormatSymbols::kPercentSymbol); 119fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fPerMill = symbols.getConstSymbol( 120fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius DecimalFormatSymbols::kPerMillSymbol); 121fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fDigit = symbols.getConstSymbol( 122fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius DecimalFormatSymbols::kDigitSymbol); 123fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fSeparator = symbols.getConstSymbol( 124fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius DecimalFormatSymbols::kPatternSeparatorSymbol); 125fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fExponent = symbols.getConstSymbol( 126fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius DecimalFormatSymbols::kExponentialSymbol); 127fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fPlus = symbols.getConstSymbol( 128fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius DecimalFormatSymbols::kPlusSignSymbol); 129fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fMinus = symbols.getConstSymbol( 130fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius DecimalFormatSymbols::kMinusSignSymbol); 131fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fPadEscape = symbols.getConstSymbol( 132fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius DecimalFormatSymbols::kPadEscapeSymbol); 133fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 134fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 135fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid 136fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusDecimalFormatPatternParser::applyPatternWithoutExpandAffix( 137fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UnicodeString& pattern, 138fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius DecimalFormatPattern& out, 139fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UParseError& parseError, 140fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode& status) { 141fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) 142fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius { 143fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 144fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 145fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out = DecimalFormatPattern(); 146fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 147fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Clear error struct 148fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius parseError.offset = -1; 149fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius parseError.preContext[0] = parseError.postContext[0] = (UChar)0; 150fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 151fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // TODO: Travis Keep: This won't always work. 152fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UChar nineDigit = (UChar)(fZeroDigit + 9); 153fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t digitLen = fDigit.length(); 154fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t groupSepLen = fGroupingSeparator.length(); 155fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t decimalSepLen = fDecimalSeparator.length(); 156fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 157fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t pos = 0; 158fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t patLen = pattern.length(); 159fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Part 0 is the positive pattern. Part 1, if present, is the negative 160fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // pattern. 161fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius for (int32_t part=0; part<2 && pos<patLen; ++part) { 162fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // The subpart ranges from 0 to 4: 0=pattern proper, 1=prefix, 163fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // 2=suffix, 3=prefix in quote, 4=suffix in quote. Subpart 0 is 164fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // between the prefix and suffix, and consists of pattern 165fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // characters. In the prefix and suffix, percent, perMill, and 166fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // currency symbols are recognized and translated. 167fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t subpart = 1, sub0Start = 0, sub0Limit = 0, sub2Limit = 0; 168fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 169fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // It's important that we don't change any fields of this object 170fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // prematurely. We set the following variables for the multiplier, 171fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // grouping, etc., and then only change the actual object fields if 172fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // everything parses correctly. This also lets us register 173fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // the data from part 0 and ignore the part 1, except for the 174fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // prefix and suffix. 175fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString prefix; 176fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString suffix; 177fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t decimalPos = -1; 178fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t multiplier = 1; 179fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0, sigDigitCount = 0; 180fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int8_t groupingCount = -1; 181fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int8_t groupingCount2 = -1; 182fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t padPos = -1; 183fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UChar32 padChar = 0; 184fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t roundingPos = -1; 185fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius DigitList roundingInc; 186fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int8_t expDigits = -1; 187fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UBool expSignAlways = FALSE; 188fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 189fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // The affix is either the prefix or the suffix. 190fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString* affix = &prefix; 191fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 192fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t start = pos; 193fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UBool isPartDone = FALSE; 194fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UChar32 ch; 195fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 196fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius for (; !isPartDone && pos < patLen; ) { 197fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Todo: account for surrogate pairs 198fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ch = pattern.char32At(pos); 199fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius switch (subpart) { 200fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius case 0: // Pattern proper subpart (between prefix & suffix) 201fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Process the digits, decimal, and grouping characters. We 202fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // record five pieces of information. We expect the digits 203fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // to occur in the pattern ####00.00####, and we record the 204fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // number of left digits, zero (central) digits, and right 205fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // digits. The position of the last grouping character is 206fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // recorded (should be somewhere within the first two blocks 207fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // of characters), as is the position of the decimal point, 208fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // if any (should be in the zero digits). If there is no 209fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // decimal point, then there should be no right digits. 210fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (pattern.compare(pos, digitLen, fDigit) == 0) { 211fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (zeroDigitCount > 0 || sigDigitCount > 0) { 212fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ++digitRightCount; 213fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 214fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ++digitLeftCount; 215fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 216fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (groupingCount >= 0 && decimalPos < 0) { 217fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ++groupingCount; 218fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 219fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pos += digitLen; 220fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else if ((ch >= fZeroDigit && ch <= nineDigit) || 221fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ch == fSigDigit) { 222fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (digitRightCount > 0) { 223fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Unexpected '0' 224fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius debug("Unexpected '0'") 225fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_UNEXPECTED_TOKEN; 226fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius syntaxError(pattern,pos,parseError); 227fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 228fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 229fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (ch == fSigDigit) { 230fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ++sigDigitCount; 231fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 232fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (ch != fZeroDigit && roundingPos < 0) { 233fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius roundingPos = digitLeftCount + zeroDigitCount; 234fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 235fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (roundingPos >= 0) { 236fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius roundingInc.append((char)(ch - fZeroDigit + '0')); 237fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 238fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ++zeroDigitCount; 239fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 240fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (groupingCount >= 0 && decimalPos < 0) { 241fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ++groupingCount; 242fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 243fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pos += U16_LENGTH(ch); 244fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else if (pattern.compare(pos, groupSepLen, fGroupingSeparator) == 0) { 245fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (decimalPos >= 0) { 246fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Grouping separator after decimal 247fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius debug("Grouping separator after decimal") 248fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_UNEXPECTED_TOKEN; 249fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius syntaxError(pattern,pos,parseError); 250fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 251fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 252fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius groupingCount2 = groupingCount; 253fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius groupingCount = 0; 254fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pos += groupSepLen; 255fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else if (pattern.compare(pos, decimalSepLen, fDecimalSeparator) == 0) { 256fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (decimalPos >= 0) { 257fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Multiple decimal separators 258fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius debug("Multiple decimal separators") 259fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_MULTIPLE_DECIMAL_SEPARATORS; 260fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius syntaxError(pattern,pos,parseError); 261fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 262fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 263fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Intentionally incorporate the digitRightCount, 264fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // even though it is illegal for this to be > 0 265fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // at this point. We check pattern syntax below. 266fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius decimalPos = digitLeftCount + zeroDigitCount + digitRightCount; 267fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pos += decimalSepLen; 268fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 269fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (pattern.compare(pos, fExponent.length(), fExponent) == 0) { 270fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (expDigits >= 0) { 271fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Multiple exponential symbols 272fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius debug("Multiple exponential symbols") 273fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_MULTIPLE_EXPONENTIAL_SYMBOLS; 274fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius syntaxError(pattern,pos,parseError); 275fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 276fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 277fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (groupingCount >= 0) { 278fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Grouping separator in exponential pattern 279fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius debug("Grouping separator in exponential pattern") 280fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_MALFORMED_EXPONENTIAL_PATTERN; 281fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius syntaxError(pattern,pos,parseError); 282fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 283fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 284fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pos += fExponent.length(); 285fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Check for positive prefix 286fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (pos < patLen 287fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius && pattern.compare(pos, fPlus.length(), fPlus) == 0) { 288fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius expSignAlways = TRUE; 289fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pos += fPlus.length(); 290fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 291fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Use lookahead to parse out the exponential part of the 292fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // pattern, then jump into suffix subpart. 293fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius expDigits = 0; 294fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius while (pos < patLen && 295fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pattern.char32At(pos) == fZeroDigit) { 296fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ++expDigits; 297fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pos += U16_LENGTH(fZeroDigit); 298fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 299fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 300fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // 1. Require at least one mantissa pattern digit 301fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // 2. Disallow "#+ @" in mantissa 302fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // 3. Require at least one exponent pattern digit 303fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (((digitLeftCount + zeroDigitCount) < 1 && 304fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (sigDigitCount + digitRightCount) < 1) || 305fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (sigDigitCount > 0 && digitLeftCount > 0) || 306fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius expDigits < 1) { 307fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Malformed exponential pattern 308fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius debug("Malformed exponential pattern") 309fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_MALFORMED_EXPONENTIAL_PATTERN; 310fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius syntaxError(pattern,pos,parseError); 311fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 312fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 313fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 314fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Transition to suffix subpart 315fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius subpart = 2; // suffix subpart 316fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius affix = &suffix; 317fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius sub0Limit = pos; 318fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius continue; 319fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 320fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius break; 321fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius case 1: // Prefix subpart 322fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius case 2: // Suffix subpart 323fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Process the prefix / suffix characters 324fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Process unquoted characters seen in prefix or suffix 325fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // subpart. 326fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 327fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Several syntax characters implicitly begins the 328fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // next subpart if we are in the prefix; otherwise 329fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // they are illegal if unquoted. 330fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (!pattern.compare(pos, digitLen, fDigit) || 331fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius !pattern.compare(pos, groupSepLen, fGroupingSeparator) || 332fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius !pattern.compare(pos, decimalSepLen, fDecimalSeparator) || 333fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (ch >= fZeroDigit && ch <= nineDigit) || 334fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ch == fSigDigit) { 335fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (subpart == 1) { // prefix subpart 336fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius subpart = 0; // pattern proper subpart 337fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius sub0Start = pos; // Reprocess this character 338fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius continue; 339fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 340fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_UNQUOTED_SPECIAL; 341fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius syntaxError(pattern,pos,parseError); 342fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 343fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 344fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else if (ch == kCurrencySign) { 345fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius affix->append(kQuote); // Encode currency 346fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Use lookahead to determine if the currency sign is 347fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // doubled or not. 348fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius U_ASSERT(U16_LENGTH(kCurrencySign) == 1); 349fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if ((pos+1) < pattern.length() && pattern[pos+1] == kCurrencySign) { 350fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius affix->append(kCurrencySign); 351fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ++pos; // Skip over the doubled character 352fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if ((pos+1) < pattern.length() && 353fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pattern[pos+1] == kCurrencySign) { 354fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius affix->append(kCurrencySign); 355fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ++pos; // Skip over the doubled character 356fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fCurrencySignCount = fgCurrencySignCountInPluralFormat; 357fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 358fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fCurrencySignCount = fgCurrencySignCountInISOFormat; 359fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 360fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 361fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fCurrencySignCount = fgCurrencySignCountInSymbolFormat; 362fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 363fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Fall through to append(ch) 364fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else if (ch == kQuote) { 365fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // A quote outside quotes indicates either the opening 366fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // quote or two quotes, which is a quote literal. That is, 367fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // we have the first quote in 'do' or o''clock. 368fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius U_ASSERT(U16_LENGTH(kQuote) == 1); 369fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ++pos; 370fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (pos < pattern.length() && pattern[pos] == kQuote) { 371fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius affix->append(kQuote); // Encode quote 372fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Fall through to append(ch) 373fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 374fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius subpart += 2; // open quote 375fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius continue; 376fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 377fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else if (pattern.compare(pos, fSeparator.length(), fSeparator) == 0) { 378fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Don't allow separators in the prefix, and don't allow 379fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // separators in the second pattern (part == 1). 380fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (subpart == 1 || part == 1) { 381fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Unexpected separator 382fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius debug("Unexpected separator") 383fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_UNEXPECTED_TOKEN; 384fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius syntaxError(pattern,pos,parseError); 385fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 386fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 387fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius sub2Limit = pos; 388fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius isPartDone = TRUE; // Go to next part 389fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pos += fSeparator.length(); 390fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius break; 391fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else if (pattern.compare(pos, fPercent.length(), fPercent) == 0) { 392fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Next handle characters which are appended directly. 393fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (multiplier != 1) { 394fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Too many percent/perMill characters 395fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius debug("Too many percent characters") 396fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_MULTIPLE_PERCENT_SYMBOLS; 397fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius syntaxError(pattern,pos,parseError); 398fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 399fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 400fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius affix->append(kQuote); // Encode percent/perMill 401fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius affix->append(kPatternPercent); // Use unlocalized pattern char 402fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius multiplier = 100; 403fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pos += fPercent.length(); 404fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius break; 405fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else if (pattern.compare(pos, fPerMill.length(), fPerMill) == 0) { 406fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Next handle characters which are appended directly. 407fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (multiplier != 1) { 408fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Too many percent/perMill characters 409fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius debug("Too many perMill characters") 410fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_MULTIPLE_PERMILL_SYMBOLS; 411fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius syntaxError(pattern,pos,parseError); 412fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 413fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 414fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius affix->append(kQuote); // Encode percent/perMill 415fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius affix->append(kPatternPerMill); // Use unlocalized pattern char 416fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius multiplier = 1000; 417fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pos += fPerMill.length(); 418fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius break; 419fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else if (pattern.compare(pos, fPadEscape.length(), fPadEscape) == 0) { 420fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (padPos >= 0 || // Multiple pad specifiers 421fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (pos+1) == pattern.length()) { // Nothing after padEscape 422fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius debug("Multiple pad specifiers") 423fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_MULTIPLE_PAD_SPECIFIERS; 424fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius syntaxError(pattern,pos,parseError); 425fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 426fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 427fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius padPos = pos; 428fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pos += fPadEscape.length(); 429fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius padChar = pattern.char32At(pos); 430fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pos += U16_LENGTH(padChar); 431fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius break; 432fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else if (pattern.compare(pos, fMinus.length(), fMinus) == 0) { 433fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius affix->append(kQuote); // Encode minus 434fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius affix->append(kPatternMinus); 435fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pos += fMinus.length(); 436fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius break; 437fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else if (pattern.compare(pos, fPlus.length(), fPlus) == 0) { 438fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius affix->append(kQuote); // Encode plus 439fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius affix->append(kPatternPlus); 440fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pos += fPlus.length(); 441fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius break; 442fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 443fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Unquoted, non-special characters fall through to here, as 444fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // well as other code which needs to append something to the 445fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // affix. 446fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius affix->append(ch); 447fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pos += U16_LENGTH(ch); 448fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius break; 449fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius case 3: // Prefix subpart, in quote 450fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius case 4: // Suffix subpart, in quote 451fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // A quote within quotes indicates either the closing 452fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // quote or two quotes, which is a quote literal. That is, 453fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // we have the second quote in 'do' or 'don''t'. 454fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (ch == kQuote) { 455fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ++pos; 456fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (pos < pattern.length() && pattern[pos] == kQuote) { 457fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius affix->append(kQuote); // Encode quote 458fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Fall through to append(ch) 459fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 460fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius subpart -= 2; // close quote 461fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius continue; 462fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 463fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 464fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius affix->append(ch); 465fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pos += U16_LENGTH(ch); 466fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius break; 467fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 468fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 469fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 470fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (sub0Limit == 0) { 471fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius sub0Limit = pattern.length(); 472fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 473fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 474fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (sub2Limit == 0) { 475fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius sub2Limit = pattern.length(); 476fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 477fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 478fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius /* Handle patterns with no '0' pattern character. These patterns 479fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * are legal, but must be recodified to make sense. "##.###" -> 480fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * "#0.###". ".###" -> ".0##". 481fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * 482fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * We allow patterns of the form "####" to produce a zeroDigitCount 483fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * of zero (got that?); although this seems like it might make it 484fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * possible for format() to produce empty strings, format() checks 485fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * for this condition and outputs a zero digit in this situation. 486fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * Having a zeroDigitCount of zero yields a minimum integer digits 487fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * of zero, which allows proper round-trip patterns. We don't want 488fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * "#" to become "#0" when toPattern() is called (even though that's 489fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * what it really is, semantically). 490fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius */ 491fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (zeroDigitCount == 0 && sigDigitCount == 0 && 492fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius digitLeftCount > 0 && decimalPos >= 0) { 493fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Handle "###.###" and "###." and ".###" 494fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int n = decimalPos; 495fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (n == 0) 496fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ++n; // Handle ".###" 497fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius digitRightCount = digitLeftCount - n; 498fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius digitLeftCount = n - 1; 499fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius zeroDigitCount = 1; 500fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 501fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 502fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Do syntax checking on the digits, decimal points, and quotes. 503fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if ((decimalPos < 0 && digitRightCount > 0 && sigDigitCount == 0) || 504fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (decimalPos >= 0 && 505fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (sigDigitCount > 0 || 506fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius decimalPos < digitLeftCount || 507fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius decimalPos > (digitLeftCount + zeroDigitCount))) || 508fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius groupingCount == 0 || groupingCount2 == 0 || 509fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (sigDigitCount > 0 && zeroDigitCount > 0) || 510fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius subpart > 2) 511fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius { // subpart > 2 == unmatched quote 512fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius debug("Syntax error") 513fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_PATTERN_SYNTAX_ERROR; 514fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius syntaxError(pattern,pos,parseError); 515fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 516fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 517fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 518fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Make sure pad is at legal position before or after affix. 519fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (padPos >= 0) { 520fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (padPos == start) { 521fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius padPos = DecimalFormatPattern::kPadBeforePrefix; 522fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else if (padPos+2 == sub0Start) { 523fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius padPos = DecimalFormatPattern::kPadAfterPrefix; 524fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else if (padPos == sub0Limit) { 525fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius padPos = DecimalFormatPattern::kPadBeforeSuffix; 526fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else if (padPos+2 == sub2Limit) { 527fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius padPos = DecimalFormatPattern::kPadAfterSuffix; 528fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 529fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Illegal pad position 530fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius debug("Illegal pad position") 531fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_ILLEGAL_PAD_POSITION; 532fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius syntaxError(pattern,pos,parseError); 533fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 534fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 535fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 536fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 537fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (part == 0) { 538fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fPosPatternsBogus = FALSE; 539fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fPosPrefixPattern = prefix; 540fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fPosSuffixPattern = suffix; 541fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fNegPatternsBogus = TRUE; 542fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fNegPrefixPattern.remove(); 543fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fNegSuffixPattern.remove(); 544fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 545fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fUseExponentialNotation = (expDigits >= 0); 546fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (out.fUseExponentialNotation) { 547fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fMinExponentDigits = expDigits; 548fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 549fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fExponentSignAlwaysShown = expSignAlways; 550fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount; 551fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // The effectiveDecimalPos is the position the decimal is at or 552fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // would be at if there is no decimal. Note that if 553fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // decimalPos<0, then digitTotalCount == digitLeftCount + 554fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // zeroDigitCount. 555fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t effectiveDecimalPos = decimalPos >= 0 ? decimalPos : digitTotalCount; 556fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UBool isSigDig = (sigDigitCount > 0); 557fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fUseSignificantDigits = isSigDig; 558fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (isSigDig) { 559fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fMinimumSignificantDigits = sigDigitCount; 560fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fMaximumSignificantDigits = sigDigitCount + digitRightCount; 561fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 562fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t minInt = effectiveDecimalPos - digitLeftCount; 563fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fMinimumIntegerDigits = minInt; 564fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fMaximumIntegerDigits = out.fUseExponentialNotation 565fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ? digitLeftCount + out.fMinimumIntegerDigits 566fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius : gDefaultMaxIntegerDigits; 567fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fMaximumFractionDigits = decimalPos >= 0 568fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ? (digitTotalCount - decimalPos) : 0; 569fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fMinimumFractionDigits = decimalPos >= 0 570fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ? (digitLeftCount + zeroDigitCount - decimalPos) : 0; 571fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 572fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fGroupingUsed = groupingCount > 0; 573fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fGroupingSize = (groupingCount > 0) ? groupingCount : 0; 574fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fGroupingSize2 = (groupingCount2 > 0 && groupingCount2 != groupingCount) 575fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ? groupingCount2 : 0; 576fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fMultiplier = multiplier; 577fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fDecimalSeparatorAlwaysShown = decimalPos == 0 578fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius || decimalPos == digitTotalCount; 579fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (padPos >= 0) { 580fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fPadPosition = (DecimalFormatPattern::EPadPosition) padPos; 581fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // To compute the format width, first set up sub0Limit - 582fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // sub0Start. Add in prefix/suffix length later. 583fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 584fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // fFormatWidth = prefix.length() + suffix.length() + 585fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // sub0Limit - sub0Start; 586fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fFormatWidth = sub0Limit - sub0Start; 587fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fPad = padChar; 588fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 589fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fFormatWidth = 0; 590fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 591fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (roundingPos >= 0) { 592fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fRoundingIncrementUsed = TRUE; 593fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius roundingInc.setDecimalAt(effectiveDecimalPos - roundingPos); 594fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fRoundingIncrement = roundingInc; 595fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 596fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fRoundingIncrementUsed = FALSE; 597fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 598fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 599fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fNegPatternsBogus = FALSE; 600fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fNegPrefixPattern = prefix; 601fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fNegSuffixPattern = suffix; 602fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 603fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 604fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 605fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (pattern.length() == 0) { 606fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fNegPatternsBogus = TRUE; 607fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fNegPrefixPattern.remove(); 608fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fNegSuffixPattern.remove(); 609fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fPosPatternsBogus = FALSE; 610fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fPosPrefixPattern.remove(); 611fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fPosSuffixPattern.remove(); 612fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 613fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fMinimumIntegerDigits = 0; 614fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fMaximumIntegerDigits = kDoubleIntegerDigits; 615fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fMinimumFractionDigits = 0; 616fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fMaximumFractionDigits = kDoubleFractionDigits; 617fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 618fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fUseExponentialNotation = FALSE; 619fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fCurrencySignCount = fgCurrencySignCountZero; 620fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fGroupingUsed = FALSE; 621fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fGroupingSize = 0; 622fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fGroupingSize2 = 0; 623fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fMultiplier = 1; 624fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fDecimalSeparatorAlwaysShown = FALSE; 625fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fFormatWidth = 0; 626fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fRoundingIncrementUsed = FALSE; 627fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 628fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 629fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // If there was no negative pattern, or if the negative pattern is 630fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // identical to the positive pattern, then prepend the minus sign to the 631fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // positive pattern to form the negative pattern. 632fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (out.fNegPatternsBogus || 633fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (out.fNegPrefixPattern == out.fPosPrefixPattern 634fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius && out.fNegSuffixPattern == out.fPosSuffixPattern)) { 635fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fNegPatternsBogus = FALSE; 636fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fNegSuffixPattern = out.fPosSuffixPattern; 637f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius out.fNegPrefixPattern.remove(); 638fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius out.fNegPrefixPattern.append(kQuote).append(kPatternMinus) 639fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius .append(out.fPosPrefixPattern); 640fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 641c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert // TODO: Deprecate/Remove out.fNegSuffixPattern and 3 other fields. 642c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert AffixPattern::parseAffixString( 643c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert out.fNegSuffixPattern, out.fNegSuffixAffix, status); 644c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert AffixPattern::parseAffixString( 645c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert out.fPosSuffixPattern, out.fPosSuffixAffix, status); 646c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert AffixPattern::parseAffixString( 647c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert out.fNegPrefixPattern, out.fNegPrefixAffix, status); 648c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert AffixPattern::parseAffixString( 649c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert out.fPosPrefixPattern, out.fPosPrefixAffix, status); 650fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 651fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 652fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_NAMESPACE_END 653fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 654fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif /* !UCONFIG_NO_FORMATTING */ 655