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