Issue #1971 - Part 2: Update ICU source to 63.2.

This commit is contained in:
Job Bautista 2022-07-24 21:03:27 +08:00 committed by roytam1
commit 1e69214382
3160 changed files with 275815 additions and 234203 deletions

View file

@ -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
/*
*******************************************************************************
@ -19,6 +19,7 @@
#if !UCONFIG_NO_FORMATTING
#include <cstdlib>
#include <math.h>
#include "unicode/fmtable.h"
#include "unicode/ustring.h"
@ -28,9 +29,8 @@
#include "charstr.h"
#include "cmemory.h"
#include "cstring.h"
#include "decNumber.h"
#include "digitlst.h"
#include "fmtableimp.h"
#include "number_decimalquantity.h"
// *****************************************************************************
// class Formattable
@ -40,6 +40,8 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Formattable)
using number::impl::DecimalQuantity;
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
@ -103,7 +105,7 @@ void Formattable::init() {
fValue.fInt64 = 0;
fType = kLong;
fDecimalStr = NULL;
fDecimalNum = NULL;
fDecimalQuantity = NULL;
fBogus.setToBogus();
}
@ -257,8 +259,8 @@ Formattable::operator=(const Formattable& source)
}
UErrorCode status = U_ZERO_ERROR;
if (source.fDecimalNum != NULL) {
fDecimalNum = new DigitList(*source.fDecimalNum); // TODO: use internal digit list
if (source.fDecimalQuantity != NULL) {
fDecimalQuantity = new DecimalQuantity(*source.fDecimalQuantity);
}
if (source.fDecimalStr != NULL) {
fDecimalStr = new CharString(*source.fDecimalStr, status);
@ -356,14 +358,9 @@ void Formattable::dispose()
delete fDecimalStr;
fDecimalStr = NULL;
FmtStackData *stackData = (FmtStackData*)fStackData;
if(fDecimalNum != &(stackData->stackDecimalNum)) {
delete fDecimalNum;
} else {
fDecimalNum->~DigitList(); // destruct, don't deallocate
}
fDecimalNum = NULL;
delete fDecimalQuantity;
fDecimalQuantity = NULL;
}
Formattable *
@ -465,13 +462,13 @@ Formattable::getInt64(UErrorCode& status) const
} else if (fValue.fDouble < (double)U_INT64_MIN) {
status = U_INVALID_FORMAT_ERROR;
return U_INT64_MIN;
} else if (fabs(fValue.fDouble) > U_DOUBLE_MAX_EXACT_INT && fDecimalNum != NULL) {
int64_t val = fDecimalNum->getInt64();
if (val != 0) {
return val;
} else if (fabs(fValue.fDouble) > U_DOUBLE_MAX_EXACT_INT && fDecimalQuantity != NULL) {
if (fDecimalQuantity->fitsInLong(true)) {
return fDecimalQuantity->toLong();
} else {
// Unexpected
status = U_INVALID_FORMAT_ERROR;
return fValue.fDouble > 0 ? U_INT64_MAX : U_INT64_MIN;
return fDecimalQuantity->isNegative() ? U_INT64_MIN : U_INT64_MAX;
}
} else {
return (int64_t)fValue.fDouble;
@ -714,84 +711,85 @@ StringPiece Formattable::getDecimalNumber(UErrorCode &status) {
CharString *Formattable::internalGetCharString(UErrorCode &status) {
if(fDecimalStr == NULL) {
if (fDecimalNum == NULL) {
if (fDecimalQuantity == NULL) {
// No decimal number for the formattable yet. Which means the value was
// set directly by the user as an int, int64 or double. If the value came
// from parsing, or from the user setting a decimal number, fDecimalNum
// would already be set.
//
fDecimalNum = new DigitList; // TODO: use internal digit list
if (fDecimalNum == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
return NULL;
}
switch (fType) {
case kDouble:
fDecimalNum->set(this->getDouble());
break;
case kLong:
fDecimalNum->set(this->getLong());
break;
case kInt64:
fDecimalNum->set(this->getInt64());
break;
default:
// The formattable's value is not a numeric type.
status = U_INVALID_STATE_ERROR;
return NULL;
}
LocalPointer<DecimalQuantity> dq(new DecimalQuantity(), status);
if (U_FAILURE(status)) { return nullptr; }
populateDecimalQuantity(*dq, status);
if (U_FAILURE(status)) { return nullptr; }
fDecimalQuantity = dq.orphan();
}
fDecimalStr = new CharString;
fDecimalStr = new CharString();
if (fDecimalStr == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
return NULL;
}
fDecimalNum->getDecimal(*fDecimalStr, status);
// Older ICUs called uprv_decNumberToString here, which is not exactly the same as
// DecimalQuantity::toScientificString(). The biggest difference is that uprv_decNumberToString does
// not print scientific notation for magnitudes greater than -5 and smaller than some amount (+5?).
if (fDecimalQuantity->isZero()) {
fDecimalStr->append("0", -1, status);
} else if (fDecimalQuantity->getMagnitude() != INT32_MIN && std::abs(fDecimalQuantity->getMagnitude()) < 5) {
fDecimalStr->appendInvariantChars(fDecimalQuantity->toPlainString(), status);
} else {
fDecimalStr->appendInvariantChars(fDecimalQuantity->toScientificString(), status);
}
}
return fDecimalStr;
}
void
Formattable::populateDecimalQuantity(number::impl::DecimalQuantity& output, UErrorCode& status) const {
if (fDecimalQuantity != nullptr) {
output = *fDecimalQuantity;
return;
}
DigitList *
Formattable::getInternalDigitList() {
FmtStackData *stackData = (FmtStackData*)fStackData;
if(fDecimalNum != &(stackData->stackDecimalNum)) {
delete fDecimalNum;
fDecimalNum = new (&(stackData->stackDecimalNum), kOnStack) DigitList();
} else {
fDecimalNum->clear();
}
return fDecimalNum;
switch (fType) {
case kDouble:
output.setToDouble(this->getDouble());
output.roundToInfinity();
break;
case kLong:
output.setToInt(this->getLong());
break;
case kInt64:
output.setToLong(this->getInt64());
break;
default:
// The formattable's value is not a numeric type.
status = U_INVALID_STATE_ERROR;
}
}
// ---------------------------------------
void
Formattable::adoptDigitList(DigitList *dl) {
if(fDecimalNum==dl) {
fDecimalNum = NULL; // don't delete
}
dispose();
fDecimalNum = dl;
if(dl==NULL) { // allow adoptDigitList(NULL) to clear
return;
}
Formattable::adoptDecimalQuantity(DecimalQuantity *dq) {
if (fDecimalQuantity != NULL) {
delete fDecimalQuantity;
}
fDecimalQuantity = dq;
if (dq == NULL) { // allow adoptDigitList(NULL) to clear
return;
}
// Set the value into the Union of simple type values.
// Cannot use the set() functions because they would delete the fDecimalNum value,
if (fDecimalNum->fitsIntoLong(FALSE)) {
fType = kLong;
fValue.fInt64 = fDecimalNum->getLong();
} else if (fDecimalNum->fitsIntoInt64(FALSE)) {
fType = kInt64;
fValue.fInt64 = fDecimalNum->getInt64();
// Cannot use the set() functions because they would delete the fDecimalNum value.
if (fDecimalQuantity->fitsInLong()) {
fValue.fInt64 = fDecimalQuantity->toLong();
if (fValue.fInt64 <= INT32_MAX && fValue.fInt64 >= INT32_MIN) {
fType = kLong;
} else {
fType = kInt64;
}
} else {
fType = kDouble;
fValue.fDouble = fDecimalNum->getDouble();
fValue.fDouble = fDecimalQuantity->toDouble();
}
}
@ -804,24 +802,12 @@ Formattable::setDecimalNumber(StringPiece numberString, UErrorCode &status) {
}
dispose();
// Copy the input string and nul-terminate it.
// The decNumber library requires nul-terminated input. StringPiece input
// is not guaranteed nul-terminated. Too bad.
// CharString automatically adds the nul.
DigitList *dnum = new DigitList(); // TODO: use getInternalDigitList
if (dnum == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
return;
}
dnum->set(CharString(numberString, status).toStringPiece(), status);
if (U_FAILURE(status)) {
delete dnum;
return; // String didn't contain a decimal number.
}
adoptDigitList(dnum);
auto* dq = new DecimalQuantity();
dq->setToDecNumber(numberString, status);
adoptDecimalQuantity(dq);
// Note that we do not hang on to the caller's input string.
// If we are asked for the string, we will regenerate one from fDecimalNum.
// If we are asked for the string, we will regenerate one from fDecimalQuantity.
}
#if 0