mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-20 07:17:32 +09:00
Issue #1971 - Part 2: Update ICU source to 63.2.
This commit is contained in:
parent
8df84683be
commit
1e69214382
3160 changed files with 275815 additions and 234203 deletions
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// © 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
******************************************************************************
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* file name: nfsubs.cpp
|
||||
* encoding: US-ASCII
|
||||
* encoding: UTF-8
|
||||
* tab size: 8 (not used)
|
||||
* indentation:4
|
||||
*
|
||||
|
|
@ -19,7 +19,9 @@
|
|||
#include "utypeinfo.h" // for 'typeid' to work
|
||||
|
||||
#include "nfsubs.h"
|
||||
#include "digitlst.h"
|
||||
#include "fmtableimp.h"
|
||||
#include "putilimp.h"
|
||||
#include "number_decimalquantity.h"
|
||||
|
||||
#if U_HAVE_RBNF
|
||||
|
||||
|
|
@ -46,6 +48,8 @@ static const UChar gGreaterGreaterThan[] =
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
using number::impl::DecimalQuantity;
|
||||
|
||||
class SameValueSubstitution : public NFSubstitution {
|
||||
public:
|
||||
SameValueSubstitution(int32_t pos,
|
||||
|
|
@ -68,27 +72,24 @@ public:
|
|||
SameValueSubstitution::~SameValueSubstitution() {}
|
||||
|
||||
class MultiplierSubstitution : public NFSubstitution {
|
||||
double divisor;
|
||||
int64_t ldivisor;
|
||||
int64_t divisor;
|
||||
|
||||
public:
|
||||
MultiplierSubstitution(int32_t _pos,
|
||||
double _divisor,
|
||||
const NFRule *rule,
|
||||
const NFRuleSet* _ruleSet,
|
||||
const UnicodeString& description,
|
||||
UErrorCode& status)
|
||||
: NFSubstitution(_pos, _ruleSet, description, status), divisor(_divisor)
|
||||
: NFSubstitution(_pos, _ruleSet, description, status), divisor(rule->getDivisor())
|
||||
{
|
||||
ldivisor = util64_fromDouble(divisor);
|
||||
if (divisor == 0) {
|
||||
status = U_PARSE_ERROR;
|
||||
}
|
||||
}
|
||||
virtual ~MultiplierSubstitution();
|
||||
|
||||
virtual void setDivisor(int32_t radix, int32_t exponent, UErrorCode& status) {
|
||||
divisor = uprv_pow(radix, exponent);
|
||||
ldivisor = util64_fromDouble(divisor);
|
||||
virtual void setDivisor(int32_t radix, int16_t exponent, UErrorCode& status) {
|
||||
divisor = util64_pow(radix, exponent);
|
||||
|
||||
if(divisor == 0) {
|
||||
status = U_PARSE_ERROR;
|
||||
|
|
@ -98,14 +99,14 @@ public:
|
|||
virtual UBool operator==(const NFSubstitution& rhs) const;
|
||||
|
||||
virtual int64_t transformNumber(int64_t number) const {
|
||||
return number / ldivisor;
|
||||
return number / divisor;
|
||||
}
|
||||
|
||||
virtual double transformNumber(double number) const {
|
||||
if (getRuleSet()) {
|
||||
return uprv_floor(number / divisor);
|
||||
} else {
|
||||
return number/divisor;
|
||||
return number / divisor;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -113,7 +114,7 @@ public:
|
|||
return newRuleValue * divisor;
|
||||
}
|
||||
|
||||
virtual double calcUpperBound(double /*oldUpperBound*/) const { return divisor; }
|
||||
virtual double calcUpperBound(double /*oldUpperBound*/) const { return static_cast<double>(divisor); }
|
||||
|
||||
virtual UChar tokenChar() const { return (UChar)0x003c; } // '<'
|
||||
|
||||
|
|
@ -125,21 +126,19 @@ public:
|
|||
MultiplierSubstitution::~MultiplierSubstitution() {}
|
||||
|
||||
class ModulusSubstitution : public NFSubstitution {
|
||||
double divisor;
|
||||
int64_t ldivisor;
|
||||
int64_t divisor;
|
||||
const NFRule* ruleToUse;
|
||||
public:
|
||||
ModulusSubstitution(int32_t pos,
|
||||
double _divisor,
|
||||
const NFRule* rule,
|
||||
const NFRule* rulePredecessor,
|
||||
const NFRuleSet* ruleSet,
|
||||
const UnicodeString& description,
|
||||
UErrorCode& status);
|
||||
virtual ~ModulusSubstitution();
|
||||
|
||||
virtual void setDivisor(int32_t radix, int32_t exponent, UErrorCode& status) {
|
||||
divisor = uprv_pow(radix, exponent);
|
||||
ldivisor = util64_fromDouble(divisor);
|
||||
virtual void setDivisor(int32_t radix, int16_t exponent, UErrorCode& status) {
|
||||
divisor = util64_pow(radix, exponent);
|
||||
|
||||
if (divisor == 0) {
|
||||
status = U_PARSE_ERROR;
|
||||
|
|
@ -151,21 +150,22 @@ public:
|
|||
virtual void doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t pos, int32_t recursionCount, UErrorCode& status) const;
|
||||
virtual void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos, int32_t recursionCount, UErrorCode& status) const;
|
||||
|
||||
virtual int64_t transformNumber(int64_t number) const { return number % ldivisor; }
|
||||
virtual double transformNumber(double number) const { return uprv_fmod(number, divisor); }
|
||||
virtual int64_t transformNumber(int64_t number) const { return number % divisor; }
|
||||
virtual double transformNumber(double number) const { return uprv_fmod(number, static_cast<double>(divisor)); }
|
||||
|
||||
virtual UBool doParse(const UnicodeString& text,
|
||||
ParsePosition& parsePosition,
|
||||
double baseValue,
|
||||
double upperBound,
|
||||
UBool lenientParse,
|
||||
uint32_t nonNumericalExecutedRuleMask,
|
||||
Formattable& result) const;
|
||||
|
||||
virtual double composeRuleValue(double newRuleValue, double oldRuleValue) const {
|
||||
return oldRuleValue - uprv_fmod(oldRuleValue, divisor) + newRuleValue;
|
||||
return oldRuleValue - uprv_fmod(oldRuleValue, static_cast<double>(divisor)) + newRuleValue;
|
||||
}
|
||||
|
||||
virtual double calcUpperBound(double /*oldUpperBound*/) const { return divisor; }
|
||||
virtual double calcUpperBound(double /*oldUpperBound*/) const { return static_cast<double>(divisor); }
|
||||
|
||||
virtual UBool isModulusSubstitution() const { return TRUE; }
|
||||
|
||||
|
|
@ -225,6 +225,7 @@ public:
|
|||
double baseValue,
|
||||
double upperBound,
|
||||
UBool lenientParse,
|
||||
uint32_t nonNumericalExecutedRuleMask,
|
||||
Formattable& result) const;
|
||||
|
||||
virtual double composeRuleValue(double newRuleValue, double oldRuleValue) const { return newRuleValue + oldRuleValue; }
|
||||
|
|
@ -296,6 +297,7 @@ public:
|
|||
double baseValue,
|
||||
double upperBound,
|
||||
UBool /*lenientParse*/,
|
||||
uint32_t nonNumericalExecutedRuleMask,
|
||||
Formattable& result) const;
|
||||
|
||||
virtual double composeRuleValue(double newRuleValue, double oldRuleValue) const { return newRuleValue / oldRuleValue; }
|
||||
|
|
@ -353,7 +355,7 @@ NFSubstitution::makeSubstitution(int32_t pos,
|
|||
|
||||
// otherwise, return a MultiplierSubstitution
|
||||
else {
|
||||
return new MultiplierSubstitution(pos, rule->getDivisor(), ruleSet,
|
||||
return new MultiplierSubstitution(pos, rule, ruleSet,
|
||||
description, status);
|
||||
}
|
||||
|
||||
|
|
@ -383,7 +385,7 @@ NFSubstitution::makeSubstitution(int32_t pos,
|
|||
|
||||
// otherwise, return a ModulusSubstitution
|
||||
else {
|
||||
return new ModulusSubstitution(pos, rule->getDivisor(), predecessor,
|
||||
return new ModulusSubstitution(pos, rule, predecessor,
|
||||
ruleSet, description, status);
|
||||
}
|
||||
|
||||
|
|
@ -491,7 +493,7 @@ NFSubstitution::~NFSubstitution()
|
|||
* @param exponent The exponent of the divisor
|
||||
*/
|
||||
void
|
||||
NFSubstitution::setDivisor(int32_t /*radix*/, int32_t /*exponent*/, UErrorCode& /*status*/) {
|
||||
NFSubstitution::setDivisor(int32_t /*radix*/, int16_t /*exponent*/, UErrorCode& /*status*/) {
|
||||
// a no-op for all substitutions except multiplier and modulus substitutions
|
||||
}
|
||||
|
||||
|
|
@ -572,23 +574,38 @@ void
|
|||
NFSubstitution::doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t _pos, int32_t recursionCount, UErrorCode& status) const
|
||||
{
|
||||
if (ruleSet != NULL) {
|
||||
// perform a transformation on the number that is dependent
|
||||
// Perform a transformation on the number that is dependent
|
||||
// on the type of substitution this is, then just call its
|
||||
// rule set's format() method to format the result
|
||||
ruleSet->format(transformNumber(number), toInsertInto, _pos + this->pos, recursionCount, status);
|
||||
} else if (numberFormat != NULL) {
|
||||
// or perform the transformation on the number (preserving
|
||||
// the result's fractional part if the formatter it set
|
||||
// to show it), then use that formatter's format() method
|
||||
// to format the result
|
||||
double numberToFormat = transformNumber((double)number);
|
||||
if (numberFormat->getMaximumFractionDigits() == 0) {
|
||||
numberToFormat = uprv_floor(numberToFormat);
|
||||
}
|
||||
if (number <= MAX_INT64_IN_DOUBLE) {
|
||||
// or perform the transformation on the number (preserving
|
||||
// the result's fractional part if the formatter it set
|
||||
// to show it), then use that formatter's format() method
|
||||
// to format the result
|
||||
double numberToFormat = transformNumber((double)number);
|
||||
if (numberFormat->getMaximumFractionDigits() == 0) {
|
||||
numberToFormat = uprv_floor(numberToFormat);
|
||||
}
|
||||
|
||||
UnicodeString temp;
|
||||
numberFormat->format(numberToFormat, temp, status);
|
||||
toInsertInto.insert(_pos + this->pos, temp);
|
||||
UnicodeString temp;
|
||||
numberFormat->format(numberToFormat, temp, status);
|
||||
toInsertInto.insert(_pos + this->pos, temp);
|
||||
}
|
||||
else {
|
||||
// We have gone beyond double precision. Something has to give.
|
||||
// We're favoring accuracy of the large number over potential rules
|
||||
// that round like a CompactDecimalFormat, which is not a common use case.
|
||||
//
|
||||
// Perform a transformation on the number that is dependent
|
||||
// on the type of substitution this is, then just call its
|
||||
// rule set's format() method to format the result
|
||||
int64_t numberToFormat = transformNumber(number);
|
||||
UnicodeString temp;
|
||||
numberFormat->format(numberToFormat, temp, status);
|
||||
toInsertInto.insert(_pos + this->pos, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -678,6 +695,7 @@ NFSubstitution::doParse(const UnicodeString& text,
|
|||
double baseValue,
|
||||
double upperBound,
|
||||
UBool lenientParse,
|
||||
uint32_t nonNumericalExecutedRuleMask,
|
||||
Formattable& result) const
|
||||
{
|
||||
#ifdef RBNF_DEBUG
|
||||
|
|
@ -698,7 +716,7 @@ NFSubstitution::doParse(const UnicodeString& text,
|
|||
// on), then also try parsing the text using a default-
|
||||
// constructed NumberFormat
|
||||
if (ruleSet != NULL) {
|
||||
ruleSet->parse(text, parsePosition, upperBound, result);
|
||||
ruleSet->parse(text, parsePosition, upperBound, nonNumericalExecutedRuleMask, result);
|
||||
if (lenientParse && !ruleSet->isFractionRuleSet() && parsePosition.getIndex() == 0) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
NumberFormat* fmt = NumberFormat::createInstance(status);
|
||||
|
|
@ -809,22 +827,20 @@ UBool MultiplierSubstitution::operator==(const NFSubstitution& rhs) const
|
|||
* regular rule.
|
||||
*/
|
||||
ModulusSubstitution::ModulusSubstitution(int32_t _pos,
|
||||
double _divisor,
|
||||
const NFRule* rule,
|
||||
const NFRule* predecessor,
|
||||
const NFRuleSet* _ruleSet,
|
||||
const UnicodeString& description,
|
||||
UErrorCode& status)
|
||||
: NFSubstitution(_pos, _ruleSet, description, status)
|
||||
, divisor(_divisor)
|
||||
, divisor(rule->getDivisor())
|
||||
, ruleToUse(NULL)
|
||||
{
|
||||
ldivisor = util64_fromDouble(_divisor);
|
||||
|
||||
// the owning rule's divisor controls the behavior of this
|
||||
// substitution: rather than keeping a backpointer to the rule,
|
||||
// we keep a copy of the divisor
|
||||
|
||||
if (ldivisor == 0) {
|
||||
if (divisor == 0) {
|
||||
status = U_PARSE_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -922,18 +938,19 @@ ModulusSubstitution::doParse(const UnicodeString& text,
|
|||
double baseValue,
|
||||
double upperBound,
|
||||
UBool lenientParse,
|
||||
uint32_t nonNumericalExecutedRuleMask,
|
||||
Formattable& result) const
|
||||
{
|
||||
// if this isn't a >>> substitution, we can just use the
|
||||
// inherited parse() routine to do the parsing
|
||||
if (ruleToUse == NULL) {
|
||||
return NFSubstitution::doParse(text, parsePosition, baseValue, upperBound, lenientParse, result);
|
||||
return NFSubstitution::doParse(text, parsePosition, baseValue, upperBound, lenientParse, nonNumericalExecutedRuleMask, result);
|
||||
|
||||
// but if it IS a >>> substitution, we have to do it here: we
|
||||
// use the specific rule's doParse() method, and then we have to
|
||||
// do some of the other work of NFRuleSet.parse()
|
||||
} else {
|
||||
ruleToUse->doParse(text, parsePosition, FALSE, upperBound, result);
|
||||
ruleToUse->doParse(text, parsePosition, FALSE, upperBound, nonNumericalExecutedRuleMask, result);
|
||||
|
||||
if (parsePosition.getIndex() != 0) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
|
@ -1055,13 +1072,12 @@ FractionalPartSubstitution::doSubstitution(double number, UnicodeString& toInser
|
|||
// numberToFormat /= 10;
|
||||
// }
|
||||
|
||||
DigitList dl;
|
||||
dl.set(number);
|
||||
dl.roundFixedPoint(20); // round to 20 fraction digits.
|
||||
dl.reduce(); // Removes any trailing zeros.
|
||||
DecimalQuantity dl;
|
||||
dl.setToDouble(number);
|
||||
dl.roundToMagnitude(-20, UNUM_ROUND_HALFEVEN, status); // round to 20 fraction digits.
|
||||
|
||||
UBool pad = FALSE;
|
||||
for (int32_t didx = dl.getCount()-1; didx>=dl.getDecimalAt(); didx--) {
|
||||
for (int32_t didx = dl.getLowerDisplayMagnitude(); didx<0; didx++) {
|
||||
// Loop iterates over fraction digits, starting with the LSD.
|
||||
// include both real digits from the number, and zeros
|
||||
// to the left of the MSD but to the right of the decimal point.
|
||||
|
|
@ -1070,7 +1086,7 @@ FractionalPartSubstitution::doSubstitution(double number, UnicodeString& toInser
|
|||
} else {
|
||||
pad = TRUE;
|
||||
}
|
||||
int64_t digit = didx>=0 ? dl.getDigit(didx) - '0' : 0;
|
||||
int64_t digit = dl.getDigit(didx);
|
||||
getRuleSet()->format(digit, toInsertInto, _pos + getPos(), recursionCount, status);
|
||||
}
|
||||
|
||||
|
|
@ -1109,12 +1125,13 @@ FractionalPartSubstitution::doParse(const UnicodeString& text,
|
|||
double baseValue,
|
||||
double /*upperBound*/,
|
||||
UBool lenientParse,
|
||||
uint32_t nonNumericalExecutedRuleMask,
|
||||
Formattable& resVal) const
|
||||
{
|
||||
// if we're not in byDigits mode, we can just use the inherited
|
||||
// doParse()
|
||||
if (!byDigits) {
|
||||
return NFSubstitution::doParse(text, parsePosition, baseValue, 0, lenientParse, resVal);
|
||||
return NFSubstitution::doParse(text, parsePosition, baseValue, 0, lenientParse, nonNumericalExecutedRuleMask, resVal);
|
||||
|
||||
// if we ARE in byDigits mode, parse the text one digit at a time
|
||||
// using this substitution's owning rule set (we do this by setting
|
||||
|
|
@ -1127,12 +1144,13 @@ FractionalPartSubstitution::doParse(const UnicodeString& text,
|
|||
int32_t digit;
|
||||
// double p10 = 0.1;
|
||||
|
||||
DigitList dl;
|
||||
DecimalQuantity dl;
|
||||
int32_t totalDigits = 0;
|
||||
NumberFormat* fmt = NULL;
|
||||
while (workText.length() > 0 && workPos.getIndex() != 0) {
|
||||
workPos.setIndex(0);
|
||||
Formattable temp;
|
||||
getRuleSet()->parse(workText, workPos, 10, temp);
|
||||
getRuleSet()->parse(workText, workPos, 10, nonNumericalExecutedRuleMask, temp);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
digit = temp.getLong(status);
|
||||
// digit = temp.getType() == Formattable::kLong ?
|
||||
|
|
@ -1155,7 +1173,8 @@ FractionalPartSubstitution::doParse(const UnicodeString& text,
|
|||
}
|
||||
|
||||
if (workPos.getIndex() != 0) {
|
||||
dl.append((char)('0' + digit));
|
||||
dl.appendDigit(static_cast<int8_t>(digit), 0, true);
|
||||
totalDigits++;
|
||||
// result += digit * p10;
|
||||
// p10 /= 10;
|
||||
parsePosition.setIndex(parsePosition.getIndex() + workPos.getIndex());
|
||||
|
|
@ -1168,7 +1187,8 @@ FractionalPartSubstitution::doParse(const UnicodeString& text,
|
|||
}
|
||||
delete fmt;
|
||||
|
||||
result = dl.getCount() == 0 ? 0 : dl.getDouble();
|
||||
dl.adjustMagnitude(-totalDigits);
|
||||
result = dl.toDouble();
|
||||
result = composeRuleValue(result, baseValue);
|
||||
resVal.setDouble(result);
|
||||
return TRUE;
|
||||
|
|
@ -1240,6 +1260,7 @@ NumeratorSubstitution::doParse(const UnicodeString& text,
|
|||
double baseValue,
|
||||
double upperBound,
|
||||
UBool /*lenientParse*/,
|
||||
uint32_t nonNumericalExecutedRuleMask,
|
||||
Formattable& result) const
|
||||
{
|
||||
// we don't have to do anything special to do the parsing here,
|
||||
|
|
@ -1258,7 +1279,7 @@ NumeratorSubstitution::doParse(const UnicodeString& text,
|
|||
|
||||
while (workText.length() > 0 && workPos.getIndex() != 0) {
|
||||
workPos.setIndex(0);
|
||||
getRuleSet()->parse(workText, workPos, 1, temp); // parse zero or nothing at all
|
||||
getRuleSet()->parse(workText, workPos, 1, nonNumericalExecutedRuleMask, temp); // parse zero or nothing at all
|
||||
if (workPos.getIndex() == 0) {
|
||||
// we failed, either there were no more zeros, or the number was formatted with digits
|
||||
// either way, we're done
|
||||
|
|
@ -1280,7 +1301,7 @@ NumeratorSubstitution::doParse(const UnicodeString& text,
|
|||
}
|
||||
|
||||
// we've parsed off the zeros, now let's parse the rest from our current position
|
||||
NFSubstitution::doParse(workText, parsePosition, withZeros ? 1 : baseValue, upperBound, FALSE, result);
|
||||
NFSubstitution::doParse(workText, parsePosition, withZeros ? 1 : baseValue, upperBound, FALSE, nonNumericalExecutedRuleMask, result);
|
||||
|
||||
if (withZeros) {
|
||||
// any base value will do in this case. is there a way to
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue