mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-19 23:07:33 +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
|
||||
/*
|
||||
*******************************************************************************
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue