Merge github.com:unicode-org/icu into icu63_1

This commit is contained in:
Norbert Runge 2018-09-18 16:32:58 -07:00
commit ca35846a9a
42 changed files with 441 additions and 228 deletions

View file

@ -1668,7 +1668,8 @@ The leftmost codepage (.xxx) wins.
/* Note that we scan the *uncorrected* ID. */
if ((p = uprv_strrchr(posixID, '@')) != NULL) {
if (correctedPOSIXLocale == NULL) {
correctedPOSIXLocale = static_cast<char *>(uprv_malloc(uprv_strlen(posixID)+1));
/* new locale can be 1 char longer than old one if @ -> __ */
correctedPOSIXLocale = static_cast<char *>(uprv_malloc(uprv_strlen(posixID)+2));
/* Exit on memory allocation error. */
if (correctedPOSIXLocale == NULL) {
return NULL;
@ -1685,7 +1686,7 @@ The leftmost codepage (.xxx) wins.
}
if (uprv_strchr(correctedPOSIXLocale,'_') == NULL) {
uprv_strcat(correctedPOSIXLocale, "__"); /* aa@b -> aa__b */
uprv_strcat(correctedPOSIXLocale, "__"); /* aa@b -> aa__b (note this can make the new locale 1 char longer) */
}
else {
uprv_strcat(correctedPOSIXLocale, "_"); /* aa_CC@b -> aa_CC_b */

View file

@ -94,7 +94,7 @@ typedef size_t uintptr_t;
# define U_NL_LANGINFO_CODESET CODESET
#endif
#ifdef U_TZSET
#if defined(U_TZSET) || defined(U_HAVE_TZSET)
/* Use the predefined value. */
#elif U_PLATFORM_USES_ONLY_WIN32_API
// UWP doesn't support tzset or environment variables for tz
@ -132,7 +132,7 @@ typedef size_t uintptr_t;
# define U_TIMEZONE timezone
#endif
#ifdef U_TZNAME
#if defined(U_TZNAME) || defined(U_HAVE_TZNAME)
/* Use the predefined value. */
#elif U_PLATFORM_USES_ONLY_WIN32_API
/* not usable on all windows platforms */

View file

@ -1460,9 +1460,9 @@ _appendLDMLExtensionAsKeywords(const char* ldmlext, ExtensionListEntry** appendT
kwd->value = pType;
if (!_addExtensionToList(&kwdFirst, kwd, FALSE)) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
// duplicate keyword is allowed, Only the first
// is honored.
uprv_free(kwd);
goto cleanup;
}
}

View file

@ -420,6 +420,9 @@
#ifndef __has_cpp_attribute
# define __has_cpp_attribute(x) 0
#endif
#ifndef __has_declspec_attribute
# define __has_declspec_attribute(x) 0
#endif
#ifndef __has_builtin
# define __has_builtin(x) 0
#endif
@ -783,6 +786,8 @@ namespace std {
/* Use the predefined value. */
#elif defined(U_STATIC_IMPLEMENTATION)
# define U_EXPORT
#elif defined(_MSC_VER) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))
# define U_EXPORT __declspec(dllexport)
#elif defined(__GNUC__)
# define U_EXPORT __attribute__((visibility("default")))
#elif (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x550) \
@ -790,8 +795,6 @@ namespace std {
# define U_EXPORT __global
/*#elif defined(__HP_aCC) || defined(__HP_cc)
# define U_EXPORT __declspec(dllexport)*/
#elif defined(_MSC_VER)
# define U_EXPORT __declspec(dllexport)
#else
# define U_EXPORT
#endif
@ -807,7 +810,7 @@ namespace std {
#ifdef U_IMPORT
/* Use the predefined value. */
#elif defined(_MSC_VER)
#elif defined(_MSC_VER) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))
/* Windows needs to export/import data. */
# define U_IMPORT __declspec(dllimport)
#else

View file

@ -6,7 +6,7 @@
// Corporation and others. All Rights Reserved.
//---------------------------------------------------------
// Build tool: com.ibm.icu.dev.tool.currency.NumericCodeData
// Build date: 2018-06-06T22:39:58Z
// Build date: 2018-09-17T17:52:05Z
//---------------------------------------------------------
// >> !!! >> THIS IS A MACHINE-GENERATED FILE << !!! <<
// >> !!! >>> DO NOT EDIT <<< !!! <<
@ -270,9 +270,11 @@ currencyNumericCodes:table(nofallback){
UYN:int{858}
UYP:int{858}
UYU:int{858}
UYW:int{927}
UZS:int{860}
VEB:int{862}
VEF:int{937}
VES:int{928}
VNC:int{704}
VND:int{704}
VUV:int{548}

View file

@ -1057,12 +1057,19 @@ UBool DecimalFormat::areSignificantDigitsUsed() const {
void DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits) {
// These are the default values from the old implementation.
if (useSignificantDigits) {
if (fields->properties->minimumSignificantDigits != -1 ||
fields->properties->maximumSignificantDigits != -1) {
return;
}
} else {
if (fields->properties->minimumSignificantDigits == -1 &&
fields->properties->maximumSignificantDigits == -1) {
return;
}
}
int32_t minSig = useSignificantDigits ? 1 : -1;
int32_t maxSig = useSignificantDigits ? 6 : -1;
if (fields->properties->minimumSignificantDigits == minSig &&
fields->properties->maximumSignificantDigits == maxSig) {
return;
}
fields->properties->minimumSignificantDigits = minSig;
fields->properties->maximumSignificantDigits = maxSig;
touchNoError();

View file

@ -347,12 +347,15 @@ IndianCalendar::inDaylightTime(UErrorCode& status) const
return (UBool)(U_SUCCESS(status) ? (internalGet(UCAL_DST_OFFSET) != 0) : FALSE);
}
// default century
const UDate IndianCalendar::fgSystemDefaultCentury = DBL_MIN;
const int32_t IndianCalendar::fgSystemDefaultCenturyYear = -1;
UDate IndianCalendar::fgSystemDefaultCenturyStart = DBL_MIN;
int32_t IndianCalendar::fgSystemDefaultCenturyStartYear = -1;
/**
* The system maintains a static default century start date and Year. They are
* initialized the first time they are used. Once the system default century date
* and year are set, they do not change.
*/
static UDate gSystemDefaultCenturyStart = DBL_MIN;
static int32_t gSystemDefaultCenturyStartYear = -1;
static icu::UInitOnce gSystemDefaultCenturyInit = U_INITONCE_INITIALIZER;
UBool IndianCalendar::haveDefaultCentury() const
@ -360,88 +363,46 @@ UBool IndianCalendar::haveDefaultCentury() const
return TRUE;
}
UDate IndianCalendar::defaultCenturyStart() const
{
return internalGetDefaultCenturyStart();
}
int32_t IndianCalendar::defaultCenturyStartYear() const
{
return internalGetDefaultCenturyStartYear();
}
UDate
IndianCalendar::internalGetDefaultCenturyStart() const
{
// lazy-evaluate systemDefaultCenturyStart
UBool needsUpdate;
{
Mutex m;
needsUpdate = (fgSystemDefaultCenturyStart == fgSystemDefaultCentury);
}
if (needsUpdate) {
initializeSystemDefaultCentury();
}
// use defaultCenturyStart unless it's the flag value;
// then use systemDefaultCenturyStart
return fgSystemDefaultCenturyStart;
}
int32_t
IndianCalendar::internalGetDefaultCenturyStartYear() const
{
// lazy-evaluate systemDefaultCenturyStartYear
UBool needsUpdate;
{
Mutex m;
needsUpdate = (fgSystemDefaultCenturyStart == fgSystemDefaultCentury);
}
if (needsUpdate) {
initializeSystemDefaultCentury();
}
// use defaultCenturyStart unless it's the flag value;
// then use systemDefaultCenturyStartYear
return fgSystemDefaultCenturyStartYear;
}
void
IndianCalendar::initializeSystemDefaultCentury()
static void U_CALLCONV
initializeSystemDefaultCentury()
{
// initialize systemDefaultCentury and systemDefaultCenturyYear based
// on the current time. They'll be set to 80 years before
// the current time.
// No point in locking as it should be idempotent.
if (fgSystemDefaultCenturyStart == fgSystemDefaultCentury) {
UErrorCode status = U_ZERO_ERROR;
UErrorCode status = U_ZERO_ERROR;
IndianCalendar calendar(Locale("@calendar=Indian"),status);
if (U_SUCCESS(status)) {
calendar.setTime(Calendar::getNow(), status);
calendar.add(UCAL_YEAR, -80, status);
IndianCalendar calendar ( Locale ( "@calendar=Indian" ), status);
if ( U_SUCCESS ( status ) ) {
calendar.setTime ( Calendar::getNow(), status );
calendar.add ( UCAL_YEAR, -80, status );
UDate newStart = calendar.getTime(status);
int32_t newYear = calendar.get(UCAL_YEAR, status);
UDate newStart = calendar.getTime ( status );
int32_t newYear = calendar.get ( UCAL_YEAR, status );
{
Mutex m;
fgSystemDefaultCenturyStart = newStart;
fgSystemDefaultCenturyStartYear = newYear;
}
}
// We have no recourse upon failure unless we want to propagate the failure
// out.
gSystemDefaultCenturyStart = newStart;
gSystemDefaultCenturyStartYear = newYear;
}
// We have no recourse upon failure.
}
UDate
IndianCalendar::defaultCenturyStart() const
{
// lazy-evaluate systemDefaultCenturyStart
umtx_initOnce(gSystemDefaultCenturyInit, &initializeSystemDefaultCentury);
return gSystemDefaultCenturyStart;
}
int32_t
IndianCalendar::defaultCenturyStartYear() const
{
// lazy-evaluate systemDefaultCenturyStartYear
umtx_initOnce(gSystemDefaultCenturyInit, &initializeSystemDefaultCentury);
return gSystemDefaultCenturyStartYear;
}
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndianCalendar)
U_NAMESPACE_END

View file

@ -68,7 +68,7 @@ U_NAMESPACE_BEGIN
*/
class IndianCalendar : public Calendar {
class U_I18N_API IndianCalendar : public Calendar {
public:
/**
* Useful constants for IndianCalendar.
@ -274,10 +274,10 @@ public:
* @return The class ID for all objects of this class.
* @internal
*/
U_I18N_API static UClassID U_EXPORT2 getStaticClassID(void);
static UClassID U_EXPORT2 getStaticClassID(void);
/**
* return the calendar type, "buddhist".
* return the calendar type, "indian".
*
* @return calendar type
* @internal
@ -320,49 +320,6 @@ protected:
* @internal
*/
virtual int32_t defaultCenturyStartYear() const;
private: // default century stuff.
/**
* The system maintains a static default century start date. This is initialized
* the first time it is used. Before then, it is set to SYSTEM_DEFAULT_CENTURY to
* indicate an uninitialized state. Once the system default century date and year
* are set, they do not change.
*/
static UDate fgSystemDefaultCenturyStart;
/**
* See documentation for systemDefaultCenturyStart.
*/
static int32_t fgSystemDefaultCenturyStartYear;
/**
* Default value that indicates the defaultCenturyStartYear is unitialized
*/
static const int32_t fgSystemDefaultCenturyYear;
/**
* start of default century, as a date
*/
static const UDate fgSystemDefaultCentury;
/**
* Returns the beginning date of the 100-year window that dates
* with 2-digit years are considered to fall within.
*/
UDate internalGetDefaultCenturyStart(void) const;
/**
* Returns the first year of the 100-year window that dates with
* 2-digit years are considered to fall within.
*/
int32_t internalGetDefaultCenturyStartYear(void) const;
/**
* Initializes the 100-year window that dates with 2-digit years
* are considered to fall within so that its start date is 80 years
* before the current time.
*/
static void initializeSystemDefaultCentury(void);
};
U_NAMESPACE_END

View file

@ -407,7 +407,8 @@ LocalizedNumberFormatter::LocalizedNumberFormatter(NFS<LNF>&& src) U_NOEXCEPT
LocalizedNumberFormatter& LocalizedNumberFormatter::operator=(const LNF& other) {
NFS<LNF>::operator=(static_cast<const NFS<LNF>&>(other));
// No additional fields to assign (let call count and compiled formatter reset to defaults)
// Reset to default values.
clear();
return *this;
}
@ -419,20 +420,26 @@ LocalizedNumberFormatter& LocalizedNumberFormatter::operator=(LNF&& src) U_NOEXC
// Formatter is compiled
lnfMoveHelper(static_cast<LNF&&>(src));
} else {
// Reset to default values.
auto* callCount = reinterpret_cast<u_atomic_int32_t*>(fUnsafeCallCount);
umtx_storeRelease(*callCount, 0);
fCompiled = nullptr;
clear();
}
return *this;
}
void LocalizedNumberFormatter::clear() {
// Reset to default values.
auto* callCount = reinterpret_cast<u_atomic_int32_t*>(fUnsafeCallCount);
umtx_storeRelease(*callCount, 0);
delete fCompiled;
fCompiled = nullptr;
}
void LocalizedNumberFormatter::lnfMoveHelper(LNF&& src) {
// Copy over the compiled formatter and set call count to INT32_MIN as in computeCompiled().
// Don't copy the call count directly because doing so requires a loadAcquire/storeRelease.
// The bits themselves appear to be platform-dependent, so copying them might not be safe.
auto* callCount = reinterpret_cast<u_atomic_int32_t*>(fUnsafeCallCount);
umtx_storeRelease(*callCount, INT32_MIN);
delete fCompiled;
fCompiled = src.fCompiled;
// Reset the source object to leave it in a safe state.
auto* srcCallCount = reinterpret_cast<u_atomic_int32_t*>(src.fUnsafeCallCount);

View file

@ -225,8 +225,8 @@ MacroProps NumberPropertyMapper::oldToNew(const DecimalFormatProperties& propert
// TODO: Overriding here is a bit of a hack. Should this logic go earlier?
if (macros.precision.fType == Precision::PrecisionType::RND_FRACTION) {
// For the purposes of rounding, get the original min/max int/frac, since the local
// variables
// have been manipulated for display purposes.
// variables have been manipulated for display purposes.
int maxInt_ = properties.maximumIntegerDigits;
int minInt_ = properties.minimumIntegerDigits;
int minFrac_ = properties.minimumFractionDigits;
int maxFrac_ = properties.maximumFractionDigits;
@ -237,9 +237,15 @@ MacroProps NumberPropertyMapper::oldToNew(const DecimalFormatProperties& propert
// Patterns like "#.##E0" (no zeros in the mantissa), which mean round to maxFrac+1
macros.precision = Precision::constructSignificant(1, maxFrac_ + 1).withMode(roundingMode);
} else {
// All other scientific patterns, which mean round to minInt+maxFrac
macros.precision = Precision::constructSignificant(
minInt_ + minFrac_, minInt_ + maxFrac_).withMode(roundingMode);
int maxSig_ = minInt_ + maxFrac_;
// Bug #20058: if maxInt_ > minInt_ > 1, then minInt_ should be 1.
if (maxInt_ > minInt_ && minInt_ > 1) {
minInt_ = 1;
}
int minSig_ = minInt_ + minFrac_;
// To avoid regression, maxSig is not reset when minInt_ set to 1.
// TODO: Reset maxSig_ = 1 + minFrac_ to follow the spec.
macros.precision = Precision::constructSignificant(minSig_, maxSig_).withMode(roundingMode);
}
}
}

View file

@ -227,18 +227,26 @@ LocalizedNumberRangeFormatter::LocalizedNumberRangeFormatter(LocalizedNumberRang
LocalizedNumberRangeFormatter::LocalizedNumberRangeFormatter(NFS<LNF>&& src) U_NOEXCEPT
: NFS<LNF>(std::move(src)) {
// No additional fields to assign
// Steal the compiled formatter
LNF&& _src = static_cast<LNF&&>(src);
fImpl = _src.fImpl;
_src.fImpl = nullptr;
}
LocalizedNumberRangeFormatter& LocalizedNumberRangeFormatter::operator=(const LNF& other) {
NFS<LNF>::operator=(static_cast<const NFS<LNF>&>(other));
// No additional fields to assign
// Do not steal; just clear
delete fImpl;
fImpl = nullptr;
return *this;
}
LocalizedNumberRangeFormatter& LocalizedNumberRangeFormatter::operator=(LNF&& src) U_NOEXCEPT {
NFS<LNF>::operator=(static_cast<NFS<LNF>&&>(src));
// No additional fields to assign
// Steal the compiled formatter
delete fImpl;
fImpl = src.fImpl;
src.fImpl = nullptr;
return *this;
}

View file

@ -2358,6 +2358,8 @@ class U_I18N_API LocalizedNumberFormatter
LocalizedNumberFormatter(impl::MacroProps &&macros, const Locale &locale);
void clear();
void lnfMoveHelper(LocalizedNumberFormatter&& src);
/**

View file

@ -625,6 +625,8 @@ class U_I18N_API LocalizedNumberRangeFormatter
LocalizedNumberRangeFormatter(impl::RangeMacroProps &&macros, const Locale &locale);
void clear();
// To give the fluent setters access to this class's constructor:
friend class NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>;
friend class NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>;

View file

@ -48,8 +48,8 @@ int main(int argc, char **argv)
/* Protos */
static void usage(void);
static void version(void);
static void date(UDate when, const UChar *tz, UDateFormatStyle style, const char *format, UErrorCode *status);
static UDate getWhen(const char *millis, const char *seconds, const char *format, UDateFormatStyle style, const char *parse, const UChar *tz, UErrorCode *status);
static void date(UDate when, const UChar *tz, UDateFormatStyle style, const char *format, const char *locale, UErrorCode *status);
static UDate getWhen(const char *millis, const char *seconds, const char *format, const char *locale, UDateFormatStyle style, const char *parse, const UChar *tz, UErrorCode *status);
UConverter *cnv = NULL;
@ -74,6 +74,7 @@ main(int argc,
UDateFormatStyle style = UDAT_DEFAULT;
UErrorCode status = U_ZERO_ERROR;
const char *format = NULL;
const char *locale = NULL;
char *parse = NULL;
char *seconds = NULL;
char *millis = NULL;
@ -132,6 +133,12 @@ main(int argc,
parse = argv[optInd];
}
}
else if (strcmp(arg, "-L") == 0) {
if (optInd + 1 < argc) {
optInd++;
locale = argv[optInd];
}
}
/* POSIX.1 says all arguments after -- are not options */
else if(strcmp(arg, "--") == 0) {
/* skip the -- */
@ -162,13 +169,13 @@ main(int argc,
}
/* get the 'when' (or now) */
when = getWhen(millis, seconds, format, style, parse, tz, &status);
when = getWhen(millis, seconds, format, locale, style, parse, tz, &status);
if(parse != NULL) {
format = FORMAT_MILLIS; /* output in millis */
}
/* print the date */
date(when, tz, style, format, &status);
date(when, tz, style, format, locale, &status);
ucnv_close(cnv);
@ -194,6 +201,7 @@ usage()
puts(" -r <seconds> Use <seconds> as the time (Epoch 1970) rather than now.");
puts(" -R <millis> Use <millis> as the time (Epoch 1970) rather than now.");
puts(" -P <string> Parse <string> as the time, output in millis format.");
puts(" -L <string> Use the locale <string> instead of the default ICU locale.");
}
/* Version information */
@ -245,6 +253,7 @@ date(UDate when,
const UChar *tz,
UDateFormatStyle style,
const char *format,
const char *locale,
UErrorCode *status )
{
UChar *s = 0;
@ -264,7 +273,7 @@ date(UDate when,
}
}
fmt = udat_open(style, style, 0, tz, -1,NULL,0, status);
fmt = udat_open(style, style, locale, tz, -1,NULL,0, status);
if ( format != NULL ) {
charsToUCharsDefault(uFormat,sizeof(uFormat)/sizeof(uFormat[0]),format,-1,status);
udat_applyPattern(fmt,FALSE,uFormat,-1);
@ -292,7 +301,7 @@ date(UDate when,
free(s);
}
static UDate getWhen(const char *millis, const char *seconds, const char *format,
static UDate getWhen(const char *millis, const char *seconds, const char *format, const char *locale,
UDateFormatStyle style, const char *parse, const UChar *tz, UErrorCode *status) {
UDateFormat *fmt = NULL;
UChar uFormat[100];
@ -319,7 +328,7 @@ static UDate getWhen(const char *millis, const char *seconds, const char *format
}
}
fmt = udat_open(style, style, 0, tz, -1,NULL,0, status);
fmt = udat_open(style, style, locale, tz, -1,NULL,0, status);
if ( format != NULL ) {
charsToUCharsDefault(uFormat,sizeof(uFormat)/sizeof(uFormat[0]), format,-1,status);
udat_applyPattern(fmt,FALSE,uFormat,-1);

View file

@ -251,6 +251,7 @@ void addLocaleTest(TestNode** root)
TESTCASE(TestLikelySubtags);
TESTCASE(TestToLanguageTag);
TESTCASE(TestForLanguageTag);
TESTCASE(TestInvalidLanguageTag);
TESTCASE(TestTrailingNull);
TESTCASE(TestUnicodeDefines);
TESTCASE(TestEnglishExemplarCharacters);
@ -6030,6 +6031,9 @@ static const struct {
{"ja-u-ijkl-efgh-abcd-ca-japanese-xx-yyy-zzz-kn", "ja@attribute=abcd-efgh-ijkl;calendar=japanese;colnumeric=yes;xx=yyy-zzz", FULL_LENGTH},
{"de-u-xc-xphonebk-co-phonebk-ca-buddhist-mo-very-lo-extensi-xd-that-de-should-vc-probably-xz-killthebuffer",
"de@calendar=buddhist;collation=phonebook;de=should;lo=extensi;mo=very;vc=probably;xc=xphonebk;xd=that;xz=yes", 91},
{"de-1901-1901", "de__1901", 7},
{"de-DE-1901-1901", "de_DE_1901", 10},
{"en-a-bbb-a-ccc", "en@a=bbb", 8},
/* #12761 */
{"en-a-bar-u-baz", "en@a=bar;attribute=baz", FULL_LENGTH},
{"en-a-bar-u-baz-x-u-foo", "en@a=bar;attribute=baz;x=u-foo", FULL_LENGTH},
@ -6047,6 +6051,11 @@ static const struct {
{"zh-cmn-TW", "cmn_TW", FULL_LENGTH},
{"zh-x_t-ab", "zh", 2},
{"zh-hans-cn-u-ca-x_t-u", "zh_Hans_CN@calendar=yes", 15},
/* #20140 dupe keys in U-extension */
{"zh-u-ca-chinese-ca-gregory", "zh@calendar=chinese", FULL_LENGTH},
{"zh-u-ca-gregory-co-pinyin-ca-chinese", "zh@calendar=gregorian;collation=pinyin", FULL_LENGTH},
{"de-latn-DE-1901-u-co-phonebk-co-pinyin-ca-gregory", "de_Latn_DE_1901@calendar=gregorian;collation=phonebook", FULL_LENGTH},
{"th-u-kf-nu-thai-kf-false", "th@colcasefirst=yes;numbers=thai", FULL_LENGTH},
{NULL, NULL, 0}
};
@ -6081,6 +6090,35 @@ static void TestForLanguageTag(void) {
}
}
/* See https://unicode-org.atlassian.net/browse/ICU-20149 .
* Depending on the resolution of that bug, this test may have
* to be revised.
*/
static void TestInvalidLanguageTag(void) {
static const char* invalid_lang_tags[] = {
"zh-u-foo-foo-co-pinyin", /* duplicate attribute in U extension */
"zh-cmn-hans-u-foo-foo-co-pinyin", /* duplicate attribute in U extension */
#if 0
/*
* These do not lead to an error. Instead, parsing stops at the 1st
* invalid subtag.
*/
"de-DE-1901-1901", /* duplicate variant */
"en-a-bbb-a-ccc", /* duplicate extension */
#endif
NULL
};
char locale[256];
for (const char** tag = invalid_lang_tags; *tag != NULL; tag++) {
UErrorCode status = U_ZERO_ERROR;
uloc_forLanguageTag(*tag, locale, sizeof(locale), NULL, &status);
if (status != U_ILLEGAL_ARGUMENT_ERROR) {
log_err("Error returned by uloc_forLanguageTag for input language tag [%s] : %s - expected error: %s\n",
*tag, u_errorName(status), u_errorName(U_ILLEGAL_ARGUMENT_ERROR));
}
}
}
static void TestToUnicodeLocaleKey(void)
{
/* $IN specifies the result should be the input pointer itself */

View file

@ -123,6 +123,7 @@ static void TestLikelySubtags(void);
* lanuage tag
*/
static void TestForLanguageTag(void);
static void TestInvalidLanguageTag(void);
static void TestToLanguageTag(void);
static void TestToUnicodeLocaleKey(void);

View file

@ -257,6 +257,7 @@ class NumberRangeFormatterTest : public IntlTest {
void testIdentity();
void testDifferentFormatters();
void testPlurals();
void testCopyMove();
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);

View file

@ -2372,8 +2372,15 @@ void NumberFormatterApiTest::copyMove() {
assertTrue("[constructor] Source should be reset after move", l1.getCompiled() == nullptr);
// Reset l1 and l2 to check for macro-props copying for behavior testing
// Make the test more interesting: also warm them up with a compiled formatter.
l1 = NumberFormatter::withLocale("en");
l1.formatInt(1, status);
l1.formatInt(1, status);
l1.formatInt(1, status);
l2 = NumberFormatter::withLocale("en");
l2.formatInt(1, status);
l2.formatInt(1, status);
l2.formatInt(1, status);
// Copy assignment
l1 = l3;

View file

@ -48,6 +48,7 @@ void NumberRangeFormatterTest::runIndexedTest(int32_t index, UBool exec, const c
TESTCASE_AUTO(testIdentity);
TESTCASE_AUTO(testDifferentFormatters);
TESTCASE_AUTO(testPlurals);
TESTCASE_AUTO(testCopyMove);
TESTCASE_AUTO_END;
}
@ -706,6 +707,48 @@ void NumberRangeFormatterTest::testPlurals() {
}
}
void NumberRangeFormatterTest::testCopyMove() {
IcuTestErrorCode status(*this, "testCopyMove");
// Default constructors
LocalizedNumberRangeFormatter l1;
assertEquals("Initial behavior", u"15", l1.formatFormattableRange(1, 5, status).toString(status));
if (status.errDataIfFailureAndReset()) { return; }
// Setup
l1 = NumberRangeFormatter::withLocale("fr-FR")
.numberFormatterBoth(NumberFormatter::with().unit(USD));
assertEquals("Currency behavior", u"1,005,00 $US", l1.formatFormattableRange(1, 5, status).toString(status));
// Copy constructor
LocalizedNumberRangeFormatter l2 = l1;
assertEquals("Copy constructor", u"1,005,00 $US", l2.formatFormattableRange(1, 5, status).toString(status));
// Move constructor
LocalizedNumberRangeFormatter l3 = std::move(l1);
assertEquals("Move constructor", u"1,005,00 $US", l3.formatFormattableRange(1, 5, status).toString(status));
// Reset objects for assignment tests
l1 = NumberRangeFormatter::withLocale("en-us");
l2 = NumberRangeFormatter::withLocale("en-us");
assertEquals("Rest behavior, l1", u"15", l1.formatFormattableRange(1, 5, status).toString(status));
assertEquals("Rest behavior, l2", u"15", l2.formatFormattableRange(1, 5, status).toString(status));
// Copy assignment
l1 = l3;
assertEquals("Copy constructor", u"1,005,00 $US", l1.formatFormattableRange(1, 5, status).toString(status));
// Move assignment
l2 = std::move(l3);
assertEquals("Copy constructor", u"1,005,00 $US", l2.formatFormattableRange(1, 5, status).toString(status));
// FormattedNumberRange
FormattedNumberRange result = l1.formatFormattableRange(1, 5, status);
assertEquals("FormattedNumberRange move constructor", u"1,005,00 $US", result.toString(status));
result = l1.formatFormattableRange(3, 6, status);
assertEquals("FormattedNumberRange move assignment", u"3,006,00 $US", result.toString(status));
}
void NumberRangeFormatterTest::assertFormatRange(
const char16_t* message,
const UnlocalizedNumberRangeFormatter& f,

View file

@ -7367,6 +7367,35 @@ void NumberFormatTest::TestSignificantDigits(void) {
}
result.remove();
}
// Test for ICU-20063
{
DecimalFormat df({"en-us", status}, status);
df.setSignificantDigitsUsed(TRUE);
expect(df, 9.87654321, u"9.87654");
df.setMaximumSignificantDigits(3);
expect(df, 9.87654321, u"9.88");
// setSignificantDigitsUsed with maxSig only
df.setSignificantDigitsUsed(TRUE);
expect(df, 9.87654321, u"9.88");
df.setMinimumSignificantDigits(2);
expect(df, 9, u"9.0");
// setSignificantDigitsUsed with both minSig and maxSig
df.setSignificantDigitsUsed(TRUE);
expect(df, 9, u"9.0");
// setSignificantDigitsUsed to false: should revert to fraction rounding
df.setSignificantDigitsUsed(FALSE);
expect(df, 9.87654321, u"9.876543");
expect(df, 9, u"9");
df.setSignificantDigitsUsed(TRUE);
df.setMinimumSignificantDigits(2);
expect(df, 9.87654321, u"9.87654");
expect(df, 9, u"9.0");
// setSignificantDigitsUsed with minSig only
df.setSignificantDigitsUsed(TRUE);
expect(df, 9.87654321, u"9.87654");
expect(df, 9, u"9.0");
}
}
void NumberFormatTest::TestShowZero() {

View file

@ -13,6 +13,7 @@
#include "umutex.h"
#include "cmemory.h"
#include "cstring.h"
#include "indiancal.h"
#include "uparse.h"
#include "unicode/localpointer.h"
#include "unicode/resbund.h"
@ -82,6 +83,7 @@ void MultithreadTest::runIndexedTest( int32_t index, UBool exec,
TESTCASE_AUTO(TestBreakTranslit);
TESTCASE_AUTO(TestIncDec);
#endif /* #if !UCONFIG_NO_TRANSLITERATION */
TESTCASE_AUTO(Test20104);
TESTCASE_AUTO_END
}
@ -1549,4 +1551,35 @@ void MultithreadTest::TestIncDec()
}
static Calendar *gSharedCalendar = {};
class Test20104Thread : public SimpleThread {
public:
Test20104Thread() { };
virtual void run();
};
void Test20104Thread::run() {
gSharedCalendar->defaultCenturyStartYear();
}
void MultithreadTest::Test20104() {
UErrorCode status = U_ZERO_ERROR;
Locale loc("hi_IN");
gSharedCalendar = new IndianCalendar(loc, status);
assertSuccess("Test20104", status);
static constexpr int NUM_THREADS = 4;
Test20104Thread threads[NUM_THREADS];
for (auto &thread:threads) {
thread.start();
}
for (auto &thread:threads) {
thread.join();
}
delete gSharedCalendar;
// Note: failure is reported by Thread Sanitizer. Test itself succeeds.
}
#endif /* !UCONFIG_NO_TRANSLITERATION */

View file

@ -53,6 +53,7 @@ public:
void TestUnifiedCache();
void TestBreakTranslit();
void TestIncDec();
void Test20104();
};
#endif

View file

@ -353,6 +353,15 @@ minIntegerDigits maxIntegerDigits minFractionDigits maxFractionDigits output bre
// JDK fails here because it tries to use 9 + 6 = 15 sig digits.
2 9 1 6 29.979246E7 K
test ticket 20058
set locale en
begin
pattern format output breaks
#00.0##E0 0 0.0E0 K
#00.0##E0 1.2 1.2E0 K
#00.0E0 0 0.0E0 K
#00.0E0 1.2 1.2E0 K
test significant digits scientific
set locale en
set pattern #E0

View file

@ -2,8 +2,11 @@ eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
@ -13,6 +16,7 @@ org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
org.eclipse.jdt.core.compiler.problem.APILeak=warning
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
@ -62,12 +66,14 @@ org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
org.eclipse.jdt.core.compiler.problem.nullReference=warning
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
@ -84,12 +90,16 @@ org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=info
org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
@ -97,6 +107,7 @@ org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning

View file

@ -37,11 +37,11 @@ public class Relation<K, V> implements Freezable<Relation<K,V>> { // TODO: add ,
Object[] setComparatorParam;
public static <K, V> Relation<K, V> of(Map<K, Set<V>> map, Class<?> setCreator) {
return new Relation<K, V>(map, setCreator);
return new Relation<>(map, setCreator);
}
public static <K,V> Relation<K, V> of(Map<K, Set<V>> map, Class<?> setCreator, Comparator<V> setComparator) {
return new Relation<K, V>(map, setCreator, setComparator);
return new Relation<>(map, setCreator, setComparator);
}
public Relation(Map<K, Set<V>> map, Class<?> setCreator) {
@ -91,10 +91,10 @@ public class Relation<K, V> implements Freezable<Relation<K,V>> { // TODO: add ,
}
public Set<Entry<K, V>> keyValueSet() {
Set<Entry<K, V>> result = new LinkedHashSet<Entry<K, V>>();
Set<Entry<K, V>> result = new LinkedHashSet<>();
for (K key : data.keySet()) {
for (V value : data.get(key)) {
result.add(new SimpleEntry<K, V>(key, value));
result.add(new SimpleEntry<>(key, value));
}
}
return result;
@ -320,7 +320,9 @@ public class Relation<K, V> implements Freezable<Relation<K,V>> { // TODO: add ,
return result;
}
public Set<V> removeAll(K... keys) {
@SafeVarargs
@SuppressWarnings("varargs") // Not supported by Eclipse, but we need this for javac
public final Set<V> removeAll(K... keys) {
return removeAll(Arrays.asList(keys));
}
@ -333,7 +335,7 @@ public class Relation<K, V> implements Freezable<Relation<K,V>> { // TODO: add ,
}
public Set<V> removeAll(Collection<K> toBeRemoved) {
Set<V> result = new LinkedHashSet<V>();
Set<V> result = new LinkedHashSet<>();
for (K key : toBeRemoved) {
try {
final Set<V> removals = data.remove(key);

View file

@ -44,7 +44,9 @@ public class XCldrStub {
? setClass
: HashSet.class);
}
public Multimap<K, V> putAll(K key, V... values) {
@SafeVarargs
@SuppressWarnings("varargs") // Not supported by Eclipse, but we need this for javac
public final Multimap<K, V> putAll(K key, V... values) {
if (values.length != 0) {
createSetIfMissing(key).addAll(Arrays.asList(values));
}
@ -107,7 +109,7 @@ public class XCldrStub {
return map.size();
}
public Iterable<Entry<K, V>> entries() {
return new MultimapIterator<K, V>(map);
return new MultimapIterator<>(map);
}
@Override
public boolean equals(Object obj) {
@ -147,7 +149,7 @@ public class XCldrStub {
private static class MultimapIterator<K,V> implements Iterator<Entry<K,V>>, Iterable<Entry<K,V>> {
private final Iterator<Entry<K, Set<V>>> it1;
private Iterator<V> it2 = null;
private final ReusableEntry<K,V> entry = new ReusableEntry<K,V>();
private final ReusableEntry<K,V> entry = new ReusableEntry<>();
private MultimapIterator(Map<K,Set<V>> map) {
it1 = map.entrySet().iterator();
@ -199,7 +201,7 @@ public class XCldrStub {
super(new HashMap<K, Set<V>>(), HashSet.class);
}
public static <K, V> HashMultimap<K, V> create() {
return new HashMultimap<K, V>();
return new HashMultimap<>();
}
}
@ -208,7 +210,7 @@ public class XCldrStub {
super(new TreeMap<K, Set<V>>(), TreeSet.class);
}
public static <K, V> TreeMultimap<K, V> create() {
return new TreeMultimap<K, V>();
return new TreeMultimap<>();
}
}
@ -217,7 +219,7 @@ public class XCldrStub {
super(new LinkedHashMap<K, Set<V>>(), LinkedHashSet.class);
}
public static <K, V> LinkedHashMultimap<K, V> create() {
return new LinkedHashMultimap<K, V>();
return new LinkedHashMultimap<>();
}
}
@ -315,24 +317,24 @@ public class XCldrStub {
public static class ImmutableSet {
public static <T> Set<T> copyOf(Set<T> values) {
return Collections.unmodifiableSet(new LinkedHashSet<T>(values)); // copy set for safety, preserve order
return Collections.unmodifiableSet(new LinkedHashSet<>(values)); // copy set for safety, preserve order
}
}
public static class ImmutableMap {
public static <K,V> Map<K,V> copyOf(Map<K,V> values) {
return Collections.unmodifiableMap(new LinkedHashMap<K,V>(values)); // copy set for safety, preserve order
return Collections.unmodifiableMap(new LinkedHashMap<>(values)); // copy set for safety, preserve order
}
}
public static class ImmutableMultimap {
public static <K,V> Multimap<K,V> copyOf(Multimap<K,V> values) {
LinkedHashMap<K, Set<V>> temp = new LinkedHashMap<K,Set<V>>(); // semi-deep copy, preserve order
LinkedHashMap<K, Set<V>> temp = new LinkedHashMap<>(); // semi-deep copy, preserve order
for (Entry<K, Set<V>> entry : values.asMap().entrySet()) {
Set<V> value = entry.getValue();
temp.put(entry.getKey(), value.size() == 1
? Collections.singleton(value.iterator().next())
: Collections.unmodifiableSet(new LinkedHashSet<V>(value)));
: Collections.unmodifiableSet(new LinkedHashSet<>(value)));
}
return new Multimap<K,V>(Collections.unmodifiableMap(temp), null);
return new Multimap<>(Collections.unmodifiableMap(temp), null);
}
}

View file

@ -263,8 +263,8 @@ final class NumberPropertyMapper {
// TODO: Overriding here is a bit of a hack. Should this logic go earlier?
if (macros.precision instanceof FractionPrecision) {
// For the purposes of rounding, get the original min/max int/frac, since the local
// variables
// have been manipulated for display purposes.
// variables have been manipulated for display purposes.
int maxInt_ = properties.getMaximumIntegerDigits();
int minInt_ = properties.getMinimumIntegerDigits();
int minFrac_ = properties.getMinimumFractionDigits();
int maxFrac_ = properties.getMaximumFractionDigits();
@ -275,8 +275,15 @@ final class NumberPropertyMapper {
// Patterns like "#.##E0" (no zeros in the mantissa), which mean round to maxFrac+1
macros.precision = Precision.constructSignificant(1, maxFrac_ + 1).withMode(mathContext);
} else {
// All other scientific patterns, which mean round to minInt+maxFrac
macros.precision = Precision.constructSignificant(minInt_ + minFrac_, minInt_ + maxFrac_)
int maxSig_ = minInt_ + maxFrac_;
// Bug #20058: if maxInt_ > minInt_ > 1, then minInt_ should be 1.
if (maxInt_ > minInt_ && minInt_ > 1) {
minInt_ = 1;
}
int minSig_ = minInt_ + minFrac_;
// To avoid regression, maxSig is not reset when minInt_ set to 1.
// TODO: Reset maxSig_ = 1 + minFrac_ to follow the spec.
macros.precision = Precision.constructSignificant(minSig_, maxSig_)
.withMode(mathContext);
}
}

View file

@ -1560,14 +1560,22 @@ public class DecimalFormat extends NumberFormat {
* @stable ICU 3.0
*/
public synchronized void setSignificantDigitsUsed(boolean useSignificantDigits) {
int oldMinSig = properties.getMinimumSignificantDigits();
int oldMaxSig = properties.getMaximumSignificantDigits();
// These are the default values from the old implementation.
if (useSignificantDigits) {
// These are the default values from the old implementation.
properties.setMinimumSignificantDigits(1);
properties.setMaximumSignificantDigits(6);
if (oldMinSig != -1 || oldMaxSig != -1) {
return;
}
} else {
properties.setMinimumSignificantDigits(-1);
properties.setMaximumSignificantDigits(-1);
if (oldMinSig == -1 && oldMaxSig == -1) {
return;
}
}
int minSig = useSignificantDigits ? 1 : -1;
int maxSig = useSignificantDigits ? 6 : -1;
properties.setMinimumSignificantDigits(minSig);
properties.setMaximumSignificantDigits(maxSig);
refreshFormatter();
}

View file

@ -380,8 +380,8 @@ public abstract class CodePointMap implements Iterable<CodePointMap.Range> {
*
* @param start range start
* @param option defines whether surrogates are treated normally,
* or as having the surrogateValue; usually {@value RangeOption#NORMAL}
* @param surrogateValue value for surrogates; ignored if option=={@value RangeOption#NORMAL}
* or as having the surrogateValue; usually {@link RangeOption#NORMAL}
* @param surrogateValue value for surrogates; ignored if option=={@link RangeOption#NORMAL}
* @param filter an object that may modify the map data value,
* or null if the values from the map are to be used unmodified
* @param range the range object that will be set to the code point range and value

View file

@ -33,7 +33,7 @@ public abstract class CodePointTrie extends CodePointMap {
* <p>Use null for {@link #fromBinary} to accept any type;
* {@link #getType} will return the actual type.
*
* @see MutableCodePointTrie#buildImmutable(Type, ValueWidth)
* @see MutableCodePointTrie#buildImmutable(CodePointTrie.Type, CodePointTrie.ValueWidth)
* @see #fromBinary
* @see #getType
* @draft ICU 63
@ -133,7 +133,7 @@ public abstract class CodePointTrie extends CodePointMap {
* @param bytes a buffer containing the binary data of a CodePointTrie
* @return the trie
* @see MutableCodePointTrie#MutableCodePointTrie(int, int)
* @see MutableCodePointTrie#buildImmutable(Type, ValueWidth)
* @see MutableCodePointTrie#buildImmutable(CodePointTrie.Type, CodePointTrie.ValueWidth)
* @see #toBinary(OutputStream)
* @draft ICU 63
* @provisional This API might change or be removed in a future release.
@ -740,7 +740,7 @@ public abstract class CodePointTrie extends CodePointMap {
protected abstract int cpIndex(int c);
/**
* A CodePointTrie with {@value Type#FAST}.
* A CodePointTrie with {@link Type#FAST}.
*
* @draft ICU 63
* @provisional This API might change or be removed in a future release.
@ -754,7 +754,7 @@ public abstract class CodePointTrie extends CodePointMap {
/**
* Creates a trie from its binary form.
* Same as {@link CodePointTrie#fromBinary(Type, ValueWidth, ByteBuffer)}
* with {@value Type#FAST}.
* with {@link Type#FAST}.
*
* @param valueWidth selects the number of bits in a data value; this method throws an exception
* if the valueWidth does not match the binary data;
@ -769,7 +769,7 @@ public abstract class CodePointTrie extends CodePointMap {
}
/**
* @return {@value Type#FAST}
* @return {@link Type#FAST}
* @draft ICU 63
* @provisional This API might change or be removed in a future release.
*/
@ -884,7 +884,7 @@ public abstract class CodePointTrie extends CodePointMap {
}
/**
* A CodePointTrie with {@value Type#SMALL}.
* A CodePointTrie with {@link Type#SMALL}.
*
* @draft ICU 63
* @provisional This API might change or be removed in a future release.
@ -898,7 +898,7 @@ public abstract class CodePointTrie extends CodePointMap {
/**
* Creates a trie from its binary form.
* Same as {@link CodePointTrie#fromBinary(Type, ValueWidth, ByteBuffer)}
* with {@value Type#SMALL}.
* with {@link Type#SMALL}.
*
* @param valueWidth selects the number of bits in a data value; this method throws an exception
* if the valueWidth does not match the binary data;
@ -913,7 +913,7 @@ public abstract class CodePointTrie extends CodePointMap {
}
/**
* @return {@value Type#SMALL}
* @return {@link Type#SMALL}
* @draft ICU 63
* @provisional This API might change or be removed in a future release.
*/
@ -1005,7 +1005,7 @@ public abstract class CodePointTrie extends CodePointMap {
}
/**
* A CodePointTrie with {@value Type#FAST} and {@value ValueWidth#BITS_16}.
* A CodePointTrie with {@link Type#FAST} and {@link ValueWidth#BITS_16}.
*
* @draft ICU 63
* @provisional This API might change or be removed in a future release.
@ -1022,7 +1022,7 @@ public abstract class CodePointTrie extends CodePointMap {
/**
* Creates a trie from its binary form.
* Same as {@link CodePointTrie#fromBinary(Type, ValueWidth, ByteBuffer)}
* with {@value Type#FAST} and {@value ValueWidth#BITS_16}.
* with {@link Type#FAST} and {@link ValueWidth#BITS_16}.
*
* @param bytes a buffer containing the binary data of a CodePointTrie
* @return the trie
@ -1067,7 +1067,7 @@ public abstract class CodePointTrie extends CodePointMap {
}
/**
* A CodePointTrie with {@value Type#FAST} and {@value ValueWidth#BITS_32}.
* A CodePointTrie with {@link Type#FAST} and {@link ValueWidth#BITS_32}.
*
* @draft ICU 63
* @provisional This API might change or be removed in a future release.
@ -1084,7 +1084,7 @@ public abstract class CodePointTrie extends CodePointMap {
/**
* Creates a trie from its binary form.
* Same as {@link CodePointTrie#fromBinary(Type, ValueWidth, ByteBuffer)}
* with {@value Type#FAST} and {@value ValueWidth#BITS_32}.
* with {@link Type#FAST} and {@link ValueWidth#BITS_32}.
*
* @param bytes a buffer containing the binary data of a CodePointTrie
* @return the trie
@ -1129,7 +1129,7 @@ public abstract class CodePointTrie extends CodePointMap {
}
/**
* A CodePointTrie with {@value Type#FAST} and {@value ValueWidth#BITS_8}.
* A CodePointTrie with {@link Type#FAST} and {@link ValueWidth#BITS_8}.
*
* @draft ICU 63
* @provisional This API might change or be removed in a future release.
@ -1146,7 +1146,7 @@ public abstract class CodePointTrie extends CodePointMap {
/**
* Creates a trie from its binary form.
* Same as {@link CodePointTrie#fromBinary(Type, ValueWidth, ByteBuffer)}
* with {@value Type#FAST} and {@value ValueWidth#BITS_8}.
* with {@link Type#FAST} and {@link ValueWidth#BITS_8}.
*
* @param bytes a buffer containing the binary data of a CodePointTrie
* @return the trie
@ -1191,7 +1191,7 @@ public abstract class CodePointTrie extends CodePointMap {
}
/**
* A CodePointTrie with {@value Type#SMALL} and {@value ValueWidth#BITS_16}.
* A CodePointTrie with {@link Type#SMALL} and {@link ValueWidth#BITS_16}.
*
* @draft ICU 63
* @provisional This API might change or be removed in a future release.
@ -1205,7 +1205,7 @@ public abstract class CodePointTrie extends CodePointMap {
/**
* Creates a trie from its binary form.
* Same as {@link CodePointTrie#fromBinary(Type, ValueWidth, ByteBuffer)}
* with {@value Type#SMALL} and {@value ValueWidth#BITS_16}.
* with {@link Type#SMALL} and {@link ValueWidth#BITS_16}.
*
* @param bytes a buffer containing the binary data of a CodePointTrie
* @return the trie
@ -1218,7 +1218,7 @@ public abstract class CodePointTrie extends CodePointMap {
}
/**
* A CodePointTrie with {@value Type#SMALL} and {@value ValueWidth#BITS_32}.
* A CodePointTrie with {@link Type#SMALL} and {@link ValueWidth#BITS_32}.
*
* @draft ICU 63
* @provisional This API might change or be removed in a future release.
@ -1232,7 +1232,7 @@ public abstract class CodePointTrie extends CodePointMap {
/**
* Creates a trie from its binary form.
* Same as {@link CodePointTrie#fromBinary(Type, ValueWidth, ByteBuffer)}
* with {@value Type#SMALL} and {@value ValueWidth#BITS_32}.
* with {@link Type#SMALL} and {@link ValueWidth#BITS_32}.
*
* @param bytes a buffer containing the binary data of a CodePointTrie
* @return the trie
@ -1245,7 +1245,7 @@ public abstract class CodePointTrie extends CodePointMap {
}
/**
* A CodePointTrie with {@value Type#SMALL} and {@value ValueWidth#BITS_8}.
* A CodePointTrie with {@link Type#SMALL} and {@link ValueWidth#BITS_8}.
*
* @draft ICU 63
* @provisional This API might change or be removed in a future release.
@ -1259,7 +1259,7 @@ public abstract class CodePointTrie extends CodePointMap {
/**
* Creates a trie from its binary form.
* Same as {@link CodePointTrie#fromBinary(Type, ValueWidth, ByteBuffer)}
* with {@value Type#SMALL} and {@value ValueWidth#BITS_8}.
* with {@link Type#SMALL} and {@link ValueWidth#BITS_8}.
*
* @param bytes a buffer containing the binary data of a CodePointTrie
* @return the trie

View file

@ -50,7 +50,7 @@ import com.ibm.icu.impl.EraRules;
* names in OpenJDK. ICU4J implementation enables the CLDR tentative era when
* this property is defined, but it does not use the start date and names specified
* by the property value.)</li>
* </nl>
* </ol>
* <p>
* This class should not be subclassed.</p>
* <p>

View file

@ -17,6 +17,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Objects;
import com.ibm.icu.impl.ICUData;
import com.ibm.icu.impl.ICUResourceBundle;
@ -372,16 +373,11 @@ public abstract class Transliterator implements StringTransform {
}
/**
* Mock implementation of hashCode(). This implementation always returns a constant
* value. When Java assertion is enabled, this method triggers an assertion failure.
* @internal
* @deprecated This API is ICU internal only.
* @draft ICU 63
*/
@Override
@Deprecated
public int hashCode() {
assert false : "hashCode not designed";
return 42;
return Objects.hash(contextStart, contextLimit, start, limit);
}
/**

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6dadae4ae83d956325f4e089327e824bb32dbf75c98e9c2815ffa7521f3505ca
size 12512661
oid sha256:476f003e2b423c5c00481d86396a10d251c578c3118101ef493f70312836e257
size 12488984

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b5ffb95eb91501a9f61ee31333e392ff183e0f7dddefb592f04b90fe2ac3490c
oid sha256:d77cbfad1c6a13fa1d65303303e975c25baaca85901d63361485c221c00cead7
size 92857

View file

@ -353,6 +353,15 @@ minIntegerDigits maxIntegerDigits minFractionDigits maxFractionDigits output bre
// JDK fails here because it tries to use 9 + 6 = 15 sig digits.
2 9 1 6 29.979246E7 K
test ticket 20058
set locale en
begin
pattern format output breaks
#00.0##E0 0 0.0E0 K
#00.0##E0 1.2 1.2E0 K
#00.0E0 0 0.0E0 K
#00.0E0 1.2 1.2E0 K
test significant digits scientific
set locale en
set pattern #E0

View file

@ -3975,6 +3975,35 @@ public class NumberFormatTest extends TestFmwk {
for (int i = 0; i < input.length; i++) {
assertEquals("TestSignificantDigits", expected[i], numberFormat.format(input[i]));
}
// Test for ICU-20063
{
DecimalFormat df = new DecimalFormat("0.######", DecimalFormatSymbols.getInstance(ULocale.US));
df.setSignificantDigitsUsed(true);
expect(df, 9.87654321, "9.87654");
df.setMaximumSignificantDigits(3);
expect(df, 9.87654321, "9.88");
// setSignificantDigitsUsed with maxSig only
df.setSignificantDigitsUsed(true);
expect(df, 9.87654321, "9.88");
df.setMinimumSignificantDigits(2);
expect(df, 9, "9.0");
// setSignificantDigitsUsed with both minSig and maxSig
df.setSignificantDigitsUsed(true);
expect(df, 9, "9.0");
// setSignificantDigitsUsed to false: should revert to fraction rounding
df.setSignificantDigitsUsed(false);
expect(df, 9.87654321, "9.876543");
expect(df, 9, "9");
df.setSignificantDigitsUsed(true);
df.setMinimumSignificantDigits(2);
expect(df, 9.87654321, "9.87654");
expect(df, 9, "9.0");
// setSignificantDigitsUsed with minSig only
df.setSignificantDigitsUsed(true);
expect(df, 9.87654321, "9.87654");
expect(df, 9, "9.0");
}
}
@Test
@ -4501,7 +4530,7 @@ public class NumberFormatTest extends TestFmwk {
private void CompareAttributedCharacterFormatOutput(AttributedCharacterIterator iterator,
List<FieldContainer> expected, String formattedOutput) {
List<FieldContainer> result = new ArrayList<FieldContainer>();
List<FieldContainer> result = new ArrayList<>();
while (iterator.getIndex() != iterator.getEndIndex()) {
int start = iterator.getRunStart();
int end = iterator.getRunLimit();
@ -4540,7 +4569,7 @@ public class NumberFormatTest extends TestFmwk {
@Test
public void TestNPEIssue11914() {
// First test: Double value with grouping separators.
List<FieldContainer> v1 = new ArrayList<FieldContainer>(7);
List<FieldContainer> v1 = new ArrayList<>(7);
v1.add(new FieldContainer(0, 3, NumberFormat.Field.INTEGER));
v1.add(new FieldContainer(3, 4, NumberFormat.Field.GROUPING_SEPARATOR));
v1.add(new FieldContainer(4, 7, NumberFormat.Field.INTEGER));
@ -4560,7 +4589,7 @@ public class NumberFormatTest extends TestFmwk {
CompareAttributedCharacterFormatOutput(iterator, v1, numFmtted);
// Second test: Double with scientific notation formatting.
List<FieldContainer> v2 = new ArrayList<FieldContainer>(7);
List<FieldContainer> v2 = new ArrayList<>(7);
v2.add(new FieldContainer(0, 1, NumberFormat.Field.INTEGER));
v2.add(new FieldContainer(1, 2, NumberFormat.Field.DECIMAL_SEPARATOR));
v2.add(new FieldContainer(2, 5, NumberFormat.Field.FRACTION));
@ -4574,7 +4603,7 @@ public class NumberFormatTest extends TestFmwk {
CompareAttributedCharacterFormatOutput(iterator, v2, numFmtted);
// Third test. BigInteger with grouping separators.
List<FieldContainer> v3 = new ArrayList<FieldContainer>(7);
List<FieldContainer> v3 = new ArrayList<>(7);
v3.add(new FieldContainer(0, 1, NumberFormat.Field.SIGN));
v3.add(new FieldContainer(1, 2, NumberFormat.Field.INTEGER));
v3.add(new FieldContainer(2, 3, NumberFormat.Field.GROUPING_SEPARATOR));
@ -4596,7 +4625,7 @@ public class NumberFormatTest extends TestFmwk {
CompareAttributedCharacterFormatOutput(iterator, v3, fmtNumberBigInt);
// Fourth test: BigDecimal with exponential formatting.
List<FieldContainer> v4 = new ArrayList<FieldContainer>(7);
List<FieldContainer> v4 = new ArrayList<>(7);
v4.add(new FieldContainer(0, 1, NumberFormat.Field.SIGN));
v4.add(new FieldContainer(1, 2, NumberFormat.Field.INTEGER));
v4.add(new FieldContainer(2, 3, NumberFormat.Field.DECIMAL_SEPARATOR));

View file

@ -332,6 +332,7 @@ public class RBBIMonkeyTest extends TestFmwk {
fBreakRules.add(thisRule);
};
@SuppressWarnings("unused")
private static String hexToCodePoint(String hex) {
int cp = Integer.parseInt(hex, 16);
return new StringBuilder().appendCodePoint(cp).toString();

View file

@ -4156,6 +4156,11 @@ public class ULocaleTest extends TestFmwk {
{"zh-cmn-TW", "cmn_TW", NOERROR},
{"zh-x_t-ab", "zh", Integer.valueOf(3)},
{"zh-hans-cn-u-ca-x_t-u", "zh_Hans_CN@calendar=yes", Integer.valueOf(16)},
/* #20140 dupe keys in U-extension */
{"zh-u-ca-chinese-ca-gregory", "zh@calendar=chinese", NOERROR},
{"zh-u-ca-gregory-co-pinyin-ca-chinese", "zh@calendar=gregorian;collation=pinyin", NOERROR},
{"de-latn-DE-1901-u-co-phonebk-co-pinyin-ca-gregory", "de_Latn_DE_1901@calendar=gregorian;collation=phonebook", NOERROR},
{"th-u-kf-nu-thai-kf-false", "th@colcasefirst=yes;numbers=thai", NOERROR},
};
for (int i = 0; i < langtag_to_locale.length; i++) {

View file

@ -3949,4 +3949,18 @@ the ::BEGIN/::END stuff)
"exception for a rule of '\\'");
}
}
/**
* Tests equals and hashCode implementation of Transliterator.Position
*/
@Test
public void TestPositionEquals() {
Transliterator.Position position1 = new Transliterator.Position(1, 0, 0, 0);
Transliterator.Position position2 = new Transliterator.Position(0, 0, 0, 0);
assertNotEquals("2 different positions are not equal", position1, position2);
assertNotEquals("2 different positions have different hash codes", position1.hashCode(), position2.hashCode());
Transliterator.Position position3 = new Transliterator.Position(1, 0, 0, 0);
assertEquals("2 positions are equal", position1, position3);
assertEquals("2 positions have the same hash codes", position1.hashCode(), position3.hashCode());
}
}

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="output" path="out/bin"/>
</classpath>

View file

@ -1,9 +1,9 @@
#Thu Jan 19 10:20:40 EST 2012
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@ -71,7 +71,8 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disa
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
@ -153,7 +154,6 @@ org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
org.eclipse.jdt.core.formatter.indentation.size=4
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert

View file

@ -372,9 +372,11 @@ public class NumericCodeData {
{"UYN", "858"},
{"UYP", "858"},
{"UYU", "858"},
{"UYW", "927"},
{"UZS", "860"},
{"VEB", "862"},
{"VEF", "937"},
{"VES", "928"},
{"VNC", "704"},
{"VND", "704"},
{"VUV", "548"},