summaryrefslogtreecommitdiff
path: root/Build/source/libs/icu/icu-src/source
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/icu/icu-src/source')
-rw-r--r--Build/source/libs/icu/icu-src/source/common/BUILD.bazel (renamed from Build/source/libs/icu/icu-src/source/common/BUILD)0
-rw-r--r--Build/source/libs/icu/icu-src/source/common/brkeng.cpp1
-rw-r--r--Build/source/libs/icu/icu-src/source/common/brkeng.h2
-rw-r--r--Build/source/libs/icu/icu-src/source/common/brkiter.cpp31
-rw-r--r--Build/source/libs/icu/icu-src/source/common/common.vcxproj4
-rw-r--r--Build/source/libs/icu/icu-src/source/common/common_uwp.vcxproj4
-rw-r--r--Build/source/libs/icu/icu-src/source/common/dictbe.cpp165
-rw-r--r--Build/source/libs/icu/icu-src/source/common/dictbe.h27
-rw-r--r--Build/source/libs/icu/icu-src/source/common/localematcher.cpp42
-rw-r--r--Build/source/libs/icu/icu-src/source/common/locid.cpp18
-rw-r--r--Build/source/libs/icu/icu-src/source/common/lstmbe.cpp3
-rw-r--r--Build/source/libs/icu/icu-src/source/common/lstmbe.h1
-rw-r--r--Build/source/libs/icu/icu-src/source/common/normalizer2impl.cpp11
-rw-r--r--Build/source/libs/icu/icu-src/source/common/rbbi.cpp14
-rw-r--r--Build/source/libs/icu/icu-src/source/common/rbbi_cache.cpp2
-rw-r--r--Build/source/libs/icu/icu-src/source/common/serv.cpp5
-rw-r--r--Build/source/libs/icu/icu-src/source/common/servls.cpp3
-rw-r--r--Build/source/libs/icu/icu-src/source/common/servnotf.cpp18
-rw-r--r--Build/source/libs/icu/icu-src/source/common/ubrk.cpp12
-rw-r--r--Build/source/libs/icu/icu-src/source/common/ucase.cpp40
-rw-r--r--Build/source/libs/icu/icu-src/source/common/ucase.h15
-rw-r--r--Build/source/libs/icu/icu-src/source/common/ucasemap.cpp115
-rw-r--r--Build/source/libs/icu/icu-src/source/common/ucnv.cpp11
-rw-r--r--Build/source/libs/icu/icu-src/source/common/ucurr.cpp2
-rw-r--r--Build/source/libs/icu/icu-src/source/common/uloc.cpp6
-rw-r--r--Build/source/libs/icu/icu-src/source/common/unicode/localematcher.h6
-rw-r--r--Build/source/libs/icu/icu-src/source/common/unicode/rbbi.h20
-rw-r--r--Build/source/libs/icu/icu-src/source/common/unicode/ubrk.h11
-rw-r--r--Build/source/libs/icu/icu-src/source/common/unicode/ucnv.h26
-rw-r--r--Build/source/libs/icu/icu-src/source/common/unicode/uniset.h4
-rw-r--r--Build/source/libs/icu/icu-src/source/common/unicode/urename.h5
-rw-r--r--Build/source/libs/icu/icu-src/source/common/unicode/uset.h18
-rw-r--r--Build/source/libs/icu/icu-src/source/common/unicode/uvernum.h10
-rw-r--r--Build/source/libs/icu/icu-src/source/common/unistr.cpp8
-rw-r--r--Build/source/libs/icu/icu-src/source/common/uposixdefs.h5
-rw-r--r--Build/source/libs/icu/icu-src/source/common/ustrcase.cpp130
-rw-r--r--Build/source/libs/icu/icu-src/source/common/uvector.cpp43
-rw-r--r--Build/source/libs/icu/icu-src/source/common/uvector.h12
-rw-r--r--Build/source/libs/icu/icu-src/source/common/uvectr32.cpp2
-rw-r--r--Build/source/libs/icu/icu-src/source/common/uvectr32.h6
-rwxr-xr-xBuild/source/libs/icu/icu-src/source/configure24
-rw-r--r--Build/source/libs/icu/icu-src/source/configure.ac5
-rw-r--r--Build/source/libs/icu/icu-src/source/data/cldr-icu-readme.txt102
-rw-r--r--Build/source/libs/icu/icu-src/source/data/dtd/cldr/common/dtd/ldml.dtd3208
-rw-r--r--Build/source/libs/icu/icu-src/source/data/dtd/cldr/common/dtd/ldmlICU.dtd125
-rw-r--r--Build/source/libs/icu/icu-src/source/data/in/icudt71l.dat (renamed from Build/source/libs/icu/icu-src/source/data/in/icudt70l.dat)bin19910752 -> 20632800 bytes
-rw-r--r--Build/source/libs/icu/icu-src/source/data/makedata.mak25
-rw-r--r--Build/source/libs/icu/icu-src/source/data/unidata/norm2/BUILD.bazel (renamed from Build/source/libs/icu/icu-src/source/data/unidata/norm2/BUILD)0
-rw-r--r--Build/source/libs/icu/icu-src/source/data/unidata/ucdterms.txt47
-rw-r--r--Build/source/libs/icu/icu-src/source/extra/uconv/makedata.mak17
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/BUILD.bazel (renamed from Build/source/libs/icu/icu-src/source/i18n/BUILD)0
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/alphaindex.cpp88
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/collationdatabuilder.cpp7
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/csdetect.cpp5
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/double-conversion-ieee.h25
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/double-conversion-utils.h42
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/dtfmtsym.cpp30
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/dtitvfmt.cpp11
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/dtptngen.cpp93
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/formattedval_sbimpl.cpp5
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/i18n.vcxproj4
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/i18n_uwp.vcxproj16
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/measunit_extra.cpp4
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/msgfmt.cpp21
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/msgfmt_impl.h4
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/number_affixutils.cpp3
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/number_compact.cpp4
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/number_decimalquantity.cpp123
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/number_decimalquantity.h26
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/number_longnames.cpp28
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/number_mapper.cpp10
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/number_output.cpp43
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/number_patternstring.cpp14
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/number_rounding.cpp155
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/number_roundingutils.h9
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/number_skeletons.cpp43
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/number_skeletons.h2
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/numsys.cpp7
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/plurrule.cpp18
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/rbt_set.cpp47
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/region.cpp152
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/region_impl.h6
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/smpdtfmt.cpp3
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/tmutfmt.cpp4
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/tzfmt.cpp12
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/tzgnames.cpp41
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/tznames.cpp22
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/tznames_impl.cpp57
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/ucol.cpp8
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/udatpg.cpp41
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/unicode/basictz.h4
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/unicode/dtptngen.h68
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/unicode/measunit.h79
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/unicode/numberformatter.h95
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/unicode/rbtz.h4
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/unicode/simpletz.h4
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/unicode/ucal.h29
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/unicode/ucol.h30
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/unicode/udatpg.h75
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/unicode/unounclass.h43
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/unicode/unum.h21
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/unicode/unumberformatter.h22
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/unicode/vtzone.h4
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/units_complexconverter.cpp9
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/units_complexconverter.h4
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/units_converter.cpp11
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/units_router.h2
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/uspoof_conf.cpp43
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/uspoof_conf.h11
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/uspoof_impl.cpp2
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/vtzone.cpp333
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/zonemeta.cpp64
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/zonemeta.h4
-rw-r--r--Build/source/libs/icu/icu-src/source/io/io.vcxproj4
-rw-r--r--Build/source/libs/icu/icu-src/source/io/sprintf.cpp12
-rw-r--r--Build/source/libs/icu/icu-src/source/io/ustdio.cpp2
-rw-r--r--Build/source/libs/icu/icu-src/source/layoutex/layoutex.vcxproj8
-rw-r--r--Build/source/libs/icu/icu-src/source/samples/Makefile.in2
-rw-r--r--Build/source/libs/icu/icu-src/source/samples/case/ucase.c3
-rw-r--r--Build/source/libs/icu/icu-src/source/samples/citer/citer.cpp8
-rw-r--r--Build/source/libs/icu/icu-src/source/samples/coll/coll.cpp8
-rw-r--r--Build/source/libs/icu/icu-src/source/samples/datecal/cal.cpp2
-rw-r--r--Build/source/libs/icu/icu-src/source/samples/dtitvfmtsample/Makefile27
-rw-r--r--Build/source/libs/icu/icu-src/source/samples/dtitvfmtsample/dtitvfmtsample.cpp176
-rw-r--r--Build/source/libs/icu/icu-src/source/samples/dtptngsample/Makefile27
-rw-r--r--Build/source/libs/icu/icu-src/source/samples/dtptngsample/dtptngsample.cpp220
-rw-r--r--Build/source/libs/icu/icu-src/source/samples/plurfmtsample/Makefile27
-rw-r--r--Build/source/libs/icu/icu-src/source/samples/plurfmtsample/plurfmtsample.cpp60
-rw-r--r--Build/source/libs/icu/icu-src/source/samples/readme.txt45
-rw-r--r--Build/source/libs/icu/icu-src/source/samples/strsrch/strsrch.cpp6
-rw-r--r--Build/source/libs/icu/icu-src/source/stubdata/BUILD.bazel (renamed from Build/source/libs/icu/icu-src/source/stubdata/BUILD)0
-rw-r--r--Build/source/libs/icu/icu-src/source/stubdata/stubdata.vcxproj2
-rw-r--r--Build/source/libs/icu/icu-src/source/test/cintltst/capitst.c119
-rw-r--r--Build/source/libs/icu/icu-src/source/test/cintltst/capitst.h5
-rw-r--r--Build/source/libs/icu/icu-src/source/test/cintltst/cbiditst.c9
-rw-r--r--Build/source/libs/icu/icu-src/source/test/cintltst/ccapitst.c134
-rw-r--r--Build/source/libs/icu/icu-src/source/test/cintltst/cdateintervalformattest.c80
-rw-r--r--Build/source/libs/icu/icu-src/source/test/cintltst/cdattst.c22
-rw-r--r--Build/source/libs/icu/icu-src/source/test/cintltst/cldrtest.c8
-rw-r--r--Build/source/libs/icu/icu-src/source/test/cintltst/cloctst.c34
-rw-r--r--Build/source/libs/icu/icu-src/source/test/cintltst/cnormtst.c53
-rw-r--r--Build/source/libs/icu/icu-src/source/test/cintltst/creststn.c2
-rw-r--r--Build/source/libs/icu/icu-src/source/test/cintltst/ucsdetst.c1
-rw-r--r--Build/source/libs/icu/icu-src/source/test/cintltst/udatpg_test.c176
-rw-r--r--Build/source/libs/icu/icu-src/source/test/cintltst/ulistfmttest.c102
-rw-r--r--Build/source/libs/icu/icu-src/source/test/cintltst/utexttst.c20
-rw-r--r--Build/source/libs/icu/icu-src/source/test/depstest/dependencies.txt1
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/csdetest.cpp23
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/csdetest.h1
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/dtfmttst.cpp2
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/dtifmtts.cpp41
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/dtptngts.cpp149
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/dtptngts.h10
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/icusvtst.cpp2
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/incaltst.cpp2
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/intltest.cpp12
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/listformattertest.cpp59
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/listformattertest.h1
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/lstmbetst.cpp4
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/measfmttest.cpp5
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/numbertest.h6
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/numbertest_api.cpp519
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/numbertest_decimalquantity.cpp58
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/numbertest_range.cpp22
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/numfmtst.cpp13
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/plurults.cpp6
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/rbbitst.cpp48
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/rbbitst.h4
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/strcase.cpp103
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/tmsgfmt.cpp4
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/transtst.cpp31
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/tztest.cpp64
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/units_test.cpp56
-rw-r--r--Build/source/libs/icu/icu-src/source/test/intltest/ustrtest.cpp12
-rw-r--r--Build/source/libs/icu/icu-src/source/test/iotest/strtst.c7
-rw-r--r--Build/source/libs/icu/icu-src/source/test/perf/Makefile.in7
-rw-r--r--Build/source/libs/icu/icu-src/source/test/perf/charperf/charperf.cpp1
-rw-r--r--Build/source/libs/icu/icu-src/source/test/perf/ustrperf/Makefile.in2
-rw-r--r--Build/source/libs/icu/icu-src/source/test/perf/ustrperf/stringperf.h2
-rw-r--r--Build/source/libs/icu/icu-src/source/test/testdata/break_rules/line_loose_cj.txt14
-rw-r--r--Build/source/libs/icu/icu-src/source/test/testdata/break_rules/line_normal_cj.txt14
-rw-r--r--Build/source/libs/icu/icu-src/source/test/testdata/rbbitst.txt54
-rw-r--r--Build/source/libs/icu/icu-src/source/test/testdata/root.txt4
-rw-r--r--Build/source/libs/icu/icu-src/source/tools/ctestfw/ctestfw.vcxproj4
-rw-r--r--Build/source/libs/icu/icu-src/source/tools/ctestfw/uperf.cpp18
-rw-r--r--Build/source/libs/icu/icu-src/source/tools/gennorm2/BUILD.bazel (renamed from Build/source/libs/icu/icu-src/source/tools/gennorm2/BUILD)0
-rw-r--r--Build/source/libs/icu/icu-src/source/tools/icuexportdata/icuexportdata.cpp407
-rw-r--r--Build/source/libs/icu/icu-src/source/tools/toolutil/BUILD.bazel (renamed from Build/source/libs/icu/icu-src/source/tools/toolutil/BUILD)0
-rw-r--r--Build/source/libs/icu/icu-src/source/tools/toolutil/toolutil.cpp13
-rw-r--r--Build/source/libs/icu/icu-src/source/tools/toolutil/toolutil.vcxproj16
-rw-r--r--Build/source/libs/icu/icu-src/source/tools/tzcode/icuregions1
191 files changed, 8016 insertions, 1815 deletions
diff --git a/Build/source/libs/icu/icu-src/source/common/BUILD b/Build/source/libs/icu/icu-src/source/common/BUILD.bazel
index e385d3b243f..e385d3b243f 100644
--- a/Build/source/libs/icu/icu-src/source/common/BUILD
+++ b/Build/source/libs/icu/icu-src/source/common/BUILD.bazel
diff --git a/Build/source/libs/icu/icu-src/source/common/brkeng.cpp b/Build/source/libs/icu/icu-src/source/common/brkeng.cpp
index 52e9c53621d..dc9fb99bf19 100644
--- a/Build/source/libs/icu/icu-src/source/common/brkeng.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/brkeng.cpp
@@ -79,6 +79,7 @@ UnhandledEngine::findBreaks( UText *text,
int32_t /* startPos */,
int32_t endPos,
UVector32 &/*foundBreaks*/,
+ UBool /* isPhraseBreaking */,
UErrorCode &status) const {
if (U_FAILURE(status)) return 0;
UChar32 c = utext_current32(text);
diff --git a/Build/source/libs/icu/icu-src/source/common/brkeng.h b/Build/source/libs/icu/icu-src/source/common/brkeng.h
index 6843f1cc953..127ba59e186 100644
--- a/Build/source/libs/icu/icu-src/source/common/brkeng.h
+++ b/Build/source/libs/icu/icu-src/source/common/brkeng.h
@@ -75,6 +75,7 @@ class LanguageBreakEngine : public UMemory {
int32_t startPos,
int32_t endPos,
UVector32 &foundBreaks,
+ UBool isPhraseBreaking,
UErrorCode &status) const = 0;
};
@@ -194,6 +195,7 @@ class UnhandledEngine : public LanguageBreakEngine {
int32_t startPos,
int32_t endPos,
UVector32 &foundBreaks,
+ UBool isPhraseBreaking,
UErrorCode &status) const override;
/**
diff --git a/Build/source/libs/icu/icu-src/source/common/brkiter.cpp b/Build/source/libs/icu/icu-src/source/common/brkiter.cpp
index 8b228acf2c3..8a1915880ee 100644
--- a/Build/source/libs/icu/icu-src/source/common/brkiter.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/brkiter.cpp
@@ -30,6 +30,7 @@
#include "unicode/ures.h"
#include "unicode/ustring.h"
#include "unicode/filteredbrk.h"
+#include "bytesinkutil.h"
#include "ucln_cmn.h"
#include "cstring.h"
#include "umutex.h"
@@ -115,7 +116,7 @@ BreakIterator::buildInstance(const Locale& loc, const char *type, UErrorCode &st
}
// Create a RuleBasedBreakIterator
- result = new RuleBasedBreakIterator(file, status);
+ result = new RuleBasedBreakIterator(file, uprv_strstr(type, "phrase") != NULL, status);
// If there is a result, set the valid locale and actual locale, and the kind
if (U_SUCCESS(status) && result != NULL) {
@@ -408,7 +409,6 @@ BreakIterator::makeInstance(const Locale& loc, int32_t kind, UErrorCode& status)
if (U_FAILURE(status)) {
return NULL;
}
- char lbType[kKeyValueLenMax];
BreakIterator *result = NULL;
switch (kind) {
@@ -428,18 +428,29 @@ BreakIterator::makeInstance(const Locale& loc, int32_t kind, UErrorCode& status)
break;
case UBRK_LINE:
{
+ char lb_lw[kKeyValueLenMax];
UTRACE_ENTRY(UTRACE_UBRK_CREATE_LINE);
- uprv_strcpy(lbType, "line");
- char lbKeyValue[kKeyValueLenMax] = {0};
+ uprv_strcpy(lb_lw, "line");
UErrorCode kvStatus = U_ZERO_ERROR;
- int32_t kLen = loc.getKeywordValue("lb", lbKeyValue, kKeyValueLenMax, kvStatus);
- if (U_SUCCESS(kvStatus) && kLen > 0 && (uprv_strcmp(lbKeyValue,"strict")==0 || uprv_strcmp(lbKeyValue,"normal")==0 || uprv_strcmp(lbKeyValue,"loose")==0)) {
- uprv_strcat(lbType, "_");
- uprv_strcat(lbType, lbKeyValue);
+ CharString value;
+ CharStringByteSink valueSink(&value);
+ loc.getKeywordValue("lb", valueSink, kvStatus);
+ if (U_SUCCESS(kvStatus) && (value == "strict" || value == "normal" || value == "loose")) {
+ uprv_strcat(lb_lw, "_");
+ uprv_strcat(lb_lw, value.data());
}
- result = BreakIterator::buildInstance(loc, lbType, status);
+ // lw=phrase is only supported in Japanese.
+ if (uprv_strcmp(loc.getLanguage(), "ja") == 0) {
+ value.clear();
+ loc.getKeywordValue("lw", valueSink, kvStatus);
+ if (U_SUCCESS(kvStatus) && value == "phrase") {
+ uprv_strcat(lb_lw, "_");
+ uprv_strcat(lb_lw, value.data());
+ }
+ }
+ result = BreakIterator::buildInstance(loc, lb_lw, status);
- UTRACE_DATA1(UTRACE_INFO, "lb=%s", lbKeyValue);
+ UTRACE_DATA1(UTRACE_INFO, "lb_lw=%s", lb_lw);
UTRACE_EXIT_STATUS(status);
}
break;
diff --git a/Build/source/libs/icu/icu-src/source/common/common.vcxproj b/Build/source/libs/icu/icu-src/source/common/common.vcxproj
index fdc0e8d71fd..6b0a60e46c1 100644
--- a/Build/source/libs/icu/icu-src/source/common/common.vcxproj
+++ b/Build/source/libs/icu/icu-src/source/common/common.vcxproj
@@ -58,7 +58,7 @@
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Link>
- <OutputFile>..\..\$(IcuBinOutputDir)\icuuc70d.dll</OutputFile>
+ <OutputFile>..\..\$(IcuBinOutputDir)\icuuc71d.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\$(IcuLibOutputDir)\icuucd.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\$(IcuLibOutputDir)\icuucd.lib</ImportLibrary>
</Link>
@@ -70,7 +70,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
</ClCompile>
<Link>
- <OutputFile>..\..\$(IcuBinOutputDir)\icuuc70.dll</OutputFile>
+ <OutputFile>..\..\$(IcuBinOutputDir)\icuuc71.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\$(IcuLibOutputDir)\icuuc.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\$(IcuLibOutputDir)\icuuc.lib</ImportLibrary>
</Link>
diff --git a/Build/source/libs/icu/icu-src/source/common/common_uwp.vcxproj b/Build/source/libs/icu/icu-src/source/common/common_uwp.vcxproj
index 09743e6babc..dcd95b8c318 100644
--- a/Build/source/libs/icu/icu-src/source/common/common_uwp.vcxproj
+++ b/Build/source/libs/icu/icu-src/source/common/common_uwp.vcxproj
@@ -125,7 +125,7 @@
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<AdditionalDependencies>vccorlib.lib;msvcrt.lib;vcruntime.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <OutputFile>..\..\$(IcuBinOutputDir)\icuuc70.dll</OutputFile>
+ <OutputFile>..\..\$(IcuBinOutputDir)\icuuc71.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\$(IcuLibOutputDir)\icuuc.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\$(IcuLibOutputDir)\icuuc.lib</ImportLibrary>
</Link>
@@ -148,7 +148,7 @@
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>vccorlibd.lib;msvcrtd.lib;vcruntimed.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <OutputFile>..\..\$(IcuBinOutputDir)\icuuc70d.dll</OutputFile>
+ <OutputFile>..\..\$(IcuBinOutputDir)\icuuc71d.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\$(IcuLibOutputDir)\icuucd.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\$(IcuLibOutputDir)\icuucd.lib</ImportLibrary>
</Link>
diff --git a/Build/source/libs/icu/icu-src/source/common/dictbe.cpp b/Build/source/libs/icu/icu-src/source/common/dictbe.cpp
index 4d158e3226d..4fdbdf2760f 100644
--- a/Build/source/libs/icu/icu-src/source/common/dictbe.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/dictbe.cpp
@@ -17,7 +17,10 @@
#include "dictbe.h"
#include "unicode/uniset.h"
#include "unicode/chariter.h"
+#include "unicode/resbund.h"
#include "unicode/ubrk.h"
+#include "unicode/usetiter.h"
+#include "ubrkimpl.h"
#include "utracimp.h"
#include "uvectr32.h"
#include "uvector.h"
@@ -48,6 +51,7 @@ DictionaryBreakEngine::findBreaks( UText *text,
int32_t startPos,
int32_t endPos,
UVector32 &foundBreaks,
+ UBool isPhraseBreaking,
UErrorCode& status) const {
if (U_FAILURE(status)) return 0;
(void)startPos; // TODO: remove this param?
@@ -68,7 +72,7 @@ DictionaryBreakEngine::findBreaks( UText *text,
}
rangeStart = start;
rangeEnd = current;
- result = divideUpDictionaryRange(text, rangeStart, rangeEnd, foundBreaks, status);
+ result = divideUpDictionaryRange(text, rangeStart, rangeEnd, foundBreaks, isPhraseBreaking, status);
utext_setNativeIndex(text, current);
return result;
@@ -199,13 +203,13 @@ ThaiBreakEngine::ThaiBreakEngine(DictionaryMatcher *adoptDictionary, UErrorCode
{
UTRACE_ENTRY(UTRACE_UBRK_CREATE_BREAK_ENGINE);
UTRACE_DATA1(UTRACE_INFO, "dictbe=%s", "Thai");
- fThaiWordSet.applyPattern(UNICODE_STRING_SIMPLE("[[:Thai:]&[:LineBreak=SA:]]"), status);
+ UnicodeSet thaiWordSet(UnicodeString(u"[[:Thai:]&[:LineBreak=SA:]]"), status);
if (U_SUCCESS(status)) {
- setCharacters(fThaiWordSet);
+ setCharacters(thaiWordSet);
}
- fMarkSet.applyPattern(UNICODE_STRING_SIMPLE("[[:Thai:]&[:LineBreak=SA:]&[:M:]]"), status);
+ fMarkSet.applyPattern(UnicodeString(u"[[:Thai:]&[:LineBreak=SA:]&[:M:]]"), status);
fMarkSet.add(0x0020);
- fEndWordSet = fThaiWordSet;
+ fEndWordSet = thaiWordSet;
fEndWordSet.remove(0x0E31); // MAI HAN-AKAT
fEndWordSet.remove(0x0E40, 0x0E44); // SARA E through SARA AI MAIMALAI
fBeginWordSet.add(0x0E01, 0x0E2E); // KO KAI through HO NOKHUK
@@ -230,6 +234,7 @@ ThaiBreakEngine::divideUpDictionaryRange( UText *text,
int32_t rangeStart,
int32_t rangeEnd,
UVector32 &foundBreaks,
+ UBool /* isPhraseBreaking */,
UErrorCode& status) const {
if (U_FAILURE(status)) return 0;
utext_setNativeIndex(text, rangeStart);
@@ -441,13 +446,13 @@ LaoBreakEngine::LaoBreakEngine(DictionaryMatcher *adoptDictionary, UErrorCode &s
{
UTRACE_ENTRY(UTRACE_UBRK_CREATE_BREAK_ENGINE);
UTRACE_DATA1(UTRACE_INFO, "dictbe=%s", "Laoo");
- fLaoWordSet.applyPattern(UNICODE_STRING_SIMPLE("[[:Laoo:]&[:LineBreak=SA:]]"), status);
+ UnicodeSet laoWordSet(UnicodeString(u"[[:Laoo:]&[:LineBreak=SA:]]"), status);
if (U_SUCCESS(status)) {
- setCharacters(fLaoWordSet);
+ setCharacters(laoWordSet);
}
- fMarkSet.applyPattern(UNICODE_STRING_SIMPLE("[[:Laoo:]&[:LineBreak=SA:]&[:M:]]"), status);
+ fMarkSet.applyPattern(UnicodeString(u"[[:Laoo:]&[:LineBreak=SA:]&[:M:]]"), status);
fMarkSet.add(0x0020);
- fEndWordSet = fLaoWordSet;
+ fEndWordSet = laoWordSet;
fEndWordSet.remove(0x0EC0, 0x0EC4); // prefix vowels
fBeginWordSet.add(0x0E81, 0x0EAE); // basic consonants (including holes for corresponding Thai characters)
fBeginWordSet.add(0x0EDC, 0x0EDD); // digraph consonants (no Thai equivalent)
@@ -469,6 +474,7 @@ LaoBreakEngine::divideUpDictionaryRange( UText *text,
int32_t rangeStart,
int32_t rangeEnd,
UVector32 &foundBreaks,
+ UBool /* isPhraseBreaking */,
UErrorCode& status) const {
if (U_FAILURE(status)) return 0;
if ((rangeEnd - rangeStart) < LAO_MIN_WORD_SPAN) {
@@ -637,14 +643,13 @@ BurmeseBreakEngine::BurmeseBreakEngine(DictionaryMatcher *adoptDictionary, UErro
{
UTRACE_ENTRY(UTRACE_UBRK_CREATE_BREAK_ENGINE);
UTRACE_DATA1(UTRACE_INFO, "dictbe=%s", "Mymr");
- fBurmeseWordSet.applyPattern(UNICODE_STRING_SIMPLE("[[:Mymr:]&[:LineBreak=SA:]]"), status);
+ fBeginWordSet.add(0x1000, 0x102A); // basic consonants and independent vowels
+ fEndWordSet.applyPattern(UnicodeString(u"[[:Mymr:]&[:LineBreak=SA:]]"), status);
+ fMarkSet.applyPattern(UnicodeString(u"[[:Mymr:]&[:LineBreak=SA:]&[:M:]]"), status);
+ fMarkSet.add(0x0020);
if (U_SUCCESS(status)) {
- setCharacters(fBurmeseWordSet);
+ setCharacters(fEndWordSet);
}
- fMarkSet.applyPattern(UNICODE_STRING_SIMPLE("[[:Mymr:]&[:LineBreak=SA:]&[:M:]]"), status);
- fMarkSet.add(0x0020);
- fEndWordSet = fBurmeseWordSet;
- fBeginWordSet.add(0x1000, 0x102A); // basic consonants and independent vowels
// Compact for caching.
fMarkSet.compact();
@@ -662,6 +667,7 @@ BurmeseBreakEngine::divideUpDictionaryRange( UText *text,
int32_t rangeStart,
int32_t rangeEnd,
UVector32 &foundBreaks,
+ UBool /* isPhraseBreaking */,
UErrorCode& status ) const {
if (U_FAILURE(status)) return 0;
if ((rangeEnd - rangeStart) < BURMESE_MIN_WORD_SPAN) {
@@ -830,13 +836,13 @@ KhmerBreakEngine::KhmerBreakEngine(DictionaryMatcher *adoptDictionary, UErrorCod
{
UTRACE_ENTRY(UTRACE_UBRK_CREATE_BREAK_ENGINE);
UTRACE_DATA1(UTRACE_INFO, "dictbe=%s", "Khmr");
- fKhmerWordSet.applyPattern(UNICODE_STRING_SIMPLE("[[:Khmr:]&[:LineBreak=SA:]]"), status);
+ UnicodeSet khmerWordSet(UnicodeString(u"[[:Khmr:]&[:LineBreak=SA:]]"), status);
if (U_SUCCESS(status)) {
- setCharacters(fKhmerWordSet);
+ setCharacters(khmerWordSet);
}
- fMarkSet.applyPattern(UNICODE_STRING_SIMPLE("[[:Khmr:]&[:LineBreak=SA:]&[:M:]]"), status);
+ fMarkSet.applyPattern(UnicodeString(u"[[:Khmr:]&[:LineBreak=SA:]&[:M:]]"), status);
fMarkSet.add(0x0020);
- fEndWordSet = fKhmerWordSet;
+ fEndWordSet = khmerWordSet;
fBeginWordSet.add(0x1780, 0x17B3);
//fBeginWordSet.add(0x17A3, 0x17A4); // deprecated vowels
//fEndWordSet.remove(0x17A5, 0x17A9); // Khmer independent vowels that can't end a word
@@ -867,6 +873,7 @@ KhmerBreakEngine::divideUpDictionaryRange( UText *text,
int32_t rangeStart,
int32_t rangeEnd,
UVector32 &foundBreaks,
+ UBool /* isPhraseBreaking */,
UErrorCode& status ) const {
if (U_FAILURE(status)) return 0;
if ((rangeEnd - rangeStart) < KHMER_MIN_WORD_SPAN) {
@@ -1050,25 +1057,27 @@ CjkBreakEngine::CjkBreakEngine(DictionaryMatcher *adoptDictionary, LanguageType
: DictionaryBreakEngine(), fDictionary(adoptDictionary) {
UTRACE_ENTRY(UTRACE_UBRK_CREATE_BREAK_ENGINE);
UTRACE_DATA1(UTRACE_INFO, "dictbe=%s", "Hani");
- // Korean dictionary only includes Hangul syllables
- fHangulWordSet.applyPattern(UNICODE_STRING_SIMPLE("[\\uac00-\\ud7a3]"), status);
- fHanWordSet.applyPattern(UNICODE_STRING_SIMPLE("[:Han:]"), status);
- fKatakanaWordSet.applyPattern(UNICODE_STRING_SIMPLE("[[:Katakana:]\\uff9e\\uff9f]"), status);
- fHiraganaWordSet.applyPattern(UNICODE_STRING_SIMPLE("[:Hiragana:]"), status);
nfkcNorm2 = Normalizer2::getNFKCInstance(status);
-
- if (U_SUCCESS(status)) {
- // handle Korean and Japanese/Chinese using different dictionaries
- if (type == kKorean) {
+ // Korean dictionary only includes Hangul syllables
+ fHangulWordSet.applyPattern(UnicodeString(u"[\\uac00-\\ud7a3]"), status);
+ fHangulWordSet.compact();
+ // Digits, open puncutation and Alphabetic characters.
+ fDigitOrOpenPunctuationOrAlphabetSet.applyPattern(
+ UnicodeString(u"[[:Nd:][:Pi:][:Ps:][:Alphabetic:]]"), status);
+ fDigitOrOpenPunctuationOrAlphabetSet.compact();
+ fClosePunctuationSet.applyPattern(UnicodeString(u"[[:Pc:][:Pd:][:Pe:][:Pf:][:Po:]]"), status);
+ fClosePunctuationSet.compact();
+
+ // handle Korean and Japanese/Chinese using different dictionaries
+ if (type == kKorean) {
+ if (U_SUCCESS(status)) {
setCharacters(fHangulWordSet);
- } else { //Chinese and Japanese
- UnicodeSet cjSet;
- cjSet.addAll(fHanWordSet);
- cjSet.addAll(fKatakanaWordSet);
- cjSet.addAll(fHiraganaWordSet);
- cjSet.add(0xFF70); // HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
- cjSet.add(0x30FC); // KATAKANA-HIRAGANA PROLONGED SOUND MARK
+ }
+ } else { //Chinese and Japanese
+ UnicodeSet cjSet(UnicodeString(u"[[:Han:][:Hiragana:][:Katakana:]\\u30fc\\uff70\\uff9e\\uff9f]"), status);
+ if (U_SUCCESS(status)) {
setCharacters(cjSet);
+ initJapanesePhraseParameter(status);
}
}
UTRACE_EXIT_STATUS(status);
@@ -1096,14 +1105,12 @@ static inline bool isKatakana(UChar32 value) {
(value >= 0xFF66 && value <= 0xFF9f);
}
-
// Function for accessing internal utext flags.
// Replicates an internal UText function.
static inline int32_t utext_i32_flag(int32_t bitIndex) {
return (int32_t)1 << bitIndex;
}
-
/*
* @param text A UText representing the text
@@ -1117,6 +1124,7 @@ CjkBreakEngine::divideUpDictionaryRange( UText *inText,
int32_t rangeStart,
int32_t rangeEnd,
UVector32 &foundBreaks,
+ UBool isPhraseBreaking,
UErrorCode& status) const {
if (U_FAILURE(status)) return 0;
if (rangeStart >= rangeEnd) {
@@ -1347,6 +1355,31 @@ CjkBreakEngine::divideUpDictionaryRange( UText *inText,
if ((uint32_t)bestSnlp.elementAti(numCodePts) == kuint32max) {
t_boundary.addElement(numCodePts, status);
numBreaks++;
+ } else if (isPhraseBreaking) {
+ t_boundary.addElement(numCodePts, status);
+ if(U_SUCCESS(status)) {
+ numBreaks++;
+ int32_t prevIdx = numCodePts;
+
+ int32_t codeUnitIdx = -1;
+ int32_t prevCodeUnitIdx = -1;
+ int32_t length = -1;
+ for (int32_t i = prev.elementAti(numCodePts); i > 0; i = prev.elementAti(i)) {
+ codeUnitIdx = inString.moveIndex32(0, i);
+ prevCodeUnitIdx = inString.moveIndex32(0, prevIdx);
+ // Calculate the length by using the code unit.
+ length = prevCodeUnitIdx - codeUnitIdx;
+ prevIdx = i;
+ // Keep the breakpoint if the pattern is not in the fSkipSet and continuous Katakana
+ // characters don't occur.
+ if (!fSkipSet.containsKey(inString.tempSubString(codeUnitIdx, length))
+ && (!isKatakana(inString.char32At(inString.moveIndex32(codeUnitIdx, -1)))
+ || !isKatakana(inString.char32At(codeUnitIdx)))) {
+ t_boundary.addElement(i, status);
+ numBreaks++;
+ }
+ }
+ }
} else {
for (int32_t i = numCodePts; i > 0; i = prev.elementAti(i)) {
t_boundary.addElement(i, status);
@@ -1367,7 +1400,8 @@ CjkBreakEngine::divideUpDictionaryRange( UText *inText,
// while reversing t_boundary and pushing values to foundBreaks.
int32_t prevCPPos = -1;
int32_t prevUTextPos = -1;
- for (int32_t i = numBreaks-1; i >= 0; i--) {
+ int32_t correctedNumBreaks = 0;
+ for (int32_t i = numBreaks - 1; i >= 0; i--) {
int32_t cpPos = t_boundary.elementAti(i);
U_ASSERT(cpPos > prevCPPos);
int32_t utextPos = inputMap.isValid() ? inputMap->elementAti(cpPos) : cpPos + rangeStart;
@@ -1375,7 +1409,15 @@ CjkBreakEngine::divideUpDictionaryRange( UText *inText,
if (utextPos > prevUTextPos) {
// Boundaries are added to foundBreaks output in ascending order.
U_ASSERT(foundBreaks.size() == 0 || foundBreaks.peeki() < utextPos);
- foundBreaks.push(utextPos, status);
+ // In phrase breaking, there has to be a breakpoint between Cj character and close
+ // punctuation.
+ // E.g.[携帯電話]正しい選択 -> [携帯▁電話]▁正しい▁選択 -> breakpoint between ] and 正
+ if (utextPos != rangeStart
+ || (isPhraseBreaking && utextPos > 0
+ && fClosePunctuationSet.contains(utext_char32At(inText, utextPos - 1)))) {
+ foundBreaks.push(utextPos, status);
+ correctedNumBreaks++;
+ }
} else {
// Normalization expanded the input text, the dictionary found a boundary
// within the expansion, giving two boundaries with the same index in the
@@ -1387,9 +1429,52 @@ CjkBreakEngine::divideUpDictionaryRange( UText *inText,
}
(void)prevCPPos; // suppress compiler warnings about unused variable
+ UChar32 nextChar = utext_char32At(inText, rangeEnd);
+ if (!foundBreaks.isEmpty() && foundBreaks.peeki() == rangeEnd) {
+ // In phrase breaking, there has to be a breakpoint between Cj character and
+ // the number/open punctuation.
+ // E.g. る文字「そうだ、京都」->る▁文字▁「そうだ、▁京都」-> breakpoint between 字 and「
+ // E.g. 乗車率90%程度だろうか -> 乗車▁率▁90%▁程度だろうか -> breakpoint between 率 and 9
+ // E.g. しかもロゴがUnicode! -> しかも▁ロゴが▁Unicode!-> breakpoint between が and U
+ if (isPhraseBreaking) {
+ if (!fDigitOrOpenPunctuationOrAlphabetSet.contains(nextChar)) {
+ foundBreaks.popi();
+ correctedNumBreaks--;
+ }
+ } else {
+ foundBreaks.popi();
+ correctedNumBreaks--;
+ }
+ }
+
// inString goes out of scope
// inputMap goes out of scope
- return numBreaks;
+ return correctedNumBreaks;
+}
+
+void CjkBreakEngine::initJapanesePhraseParameter(UErrorCode& error) {
+ loadJapaneseExtensions(error);
+ loadHiragana(error);
+}
+
+void CjkBreakEngine::loadJapaneseExtensions(UErrorCode& error) {
+ const char* tag = "extensions";
+ ResourceBundle ja(U_ICUDATA_BRKITR, "ja", error);
+ if (U_SUCCESS(error)) {
+ ResourceBundle bundle = ja.get(tag, error);
+ while (U_SUCCESS(error) && bundle.hasNext()) {
+ fSkipSet.puti(bundle.getNextString(error), 1, error);
+ }
+ }
+}
+
+void CjkBreakEngine::loadHiragana(UErrorCode& error) {
+ UnicodeSet hiraganaWordSet(UnicodeString(u"[:Hiragana:]"), error);
+ hiraganaWordSet.compact();
+ UnicodeSetIterator iterator(hiraganaWordSet);
+ while (iterator.next()) {
+ fSkipSet.puti(UnicodeString(iterator.getCodepoint()), 1, error);
+ }
}
#endif
diff --git a/Build/source/libs/icu/icu-src/source/common/dictbe.h b/Build/source/libs/icu/icu-src/source/common/dictbe.h
index 4e70ed38171..ca1a3c28b7b 100644
--- a/Build/source/libs/icu/icu-src/source/common/dictbe.h
+++ b/Build/source/libs/icu/icu-src/source/common/dictbe.h
@@ -15,6 +15,7 @@
#include "unicode/utext.h"
#include "brkeng.h"
+#include "hash.h"
#include "uvectr32.h"
U_NAMESPACE_BEGIN
@@ -80,6 +81,7 @@ class DictionaryBreakEngine : public LanguageBreakEngine {
int32_t startPos,
int32_t endPos,
UVector32 &foundBreaks,
+ UBool isPhraseBreaking,
UErrorCode& status ) const override;
protected:
@@ -105,6 +107,7 @@ class DictionaryBreakEngine : public LanguageBreakEngine {
int32_t rangeStart,
int32_t rangeEnd,
UVector32 &foundBreaks,
+ UBool isPhraseBreaking,
UErrorCode& status) const = 0;
};
@@ -127,7 +130,6 @@ class ThaiBreakEngine : public DictionaryBreakEngine {
* @internal
*/
- UnicodeSet fThaiWordSet;
UnicodeSet fEndWordSet;
UnicodeSet fBeginWordSet;
UnicodeSet fSuffixSet;
@@ -164,6 +166,7 @@ class ThaiBreakEngine : public DictionaryBreakEngine {
int32_t rangeStart,
int32_t rangeEnd,
UVector32 &foundBreaks,
+ UBool isPhraseBreaking,
UErrorCode& status) const override;
};
@@ -186,7 +189,6 @@ class LaoBreakEngine : public DictionaryBreakEngine {
* @internal
*/
- UnicodeSet fLaoWordSet;
UnicodeSet fEndWordSet;
UnicodeSet fBeginWordSet;
UnicodeSet fMarkSet;
@@ -222,6 +224,7 @@ class LaoBreakEngine : public DictionaryBreakEngine {
int32_t rangeStart,
int32_t rangeEnd,
UVector32 &foundBreaks,
+ UBool isPhraseBreaking,
UErrorCode& status) const override;
};
@@ -244,7 +247,6 @@ class BurmeseBreakEngine : public DictionaryBreakEngine {
* @internal
*/
- UnicodeSet fBurmeseWordSet;
UnicodeSet fEndWordSet;
UnicodeSet fBeginWordSet;
UnicodeSet fMarkSet;
@@ -280,6 +282,7 @@ class BurmeseBreakEngine : public DictionaryBreakEngine {
int32_t rangeStart,
int32_t rangeEnd,
UVector32 &foundBreaks,
+ UBool isPhraseBreaking,
UErrorCode& status) const override;
};
@@ -302,7 +305,6 @@ class KhmerBreakEngine : public DictionaryBreakEngine {
* @internal
*/
- UnicodeSet fKhmerWordSet;
UnicodeSet fEndWordSet;
UnicodeSet fBeginWordSet;
UnicodeSet fMarkSet;
@@ -338,6 +340,7 @@ class KhmerBreakEngine : public DictionaryBreakEngine {
int32_t rangeStart,
int32_t rangeEnd,
UVector32 &foundBreaks,
+ UBool isPhraseBreaking,
UErrorCode& status) const override;
};
@@ -366,13 +369,22 @@ class CjkBreakEngine : public DictionaryBreakEngine {
* @internal
*/
UnicodeSet fHangulWordSet;
- UnicodeSet fHanWordSet;
- UnicodeSet fKatakanaWordSet;
- UnicodeSet fHiraganaWordSet;
+ UnicodeSet fDigitOrOpenPunctuationOrAlphabetSet;
+ UnicodeSet fClosePunctuationSet;
DictionaryMatcher *fDictionary;
const Normalizer2 *nfkcNorm2;
+ private:
+ // Load Japanese extensions.
+ void loadJapaneseExtensions(UErrorCode& error);
+ // Load Japanese Hiragana.
+ void loadHiragana(UErrorCode& error);
+ // Initialize fSkipSet by loading Japanese Hiragana and extensions.
+ void initJapanesePhraseParameter(UErrorCode& error);
+
+ Hashtable fSkipSet;
+
public:
/**
@@ -404,6 +416,7 @@ class CjkBreakEngine : public DictionaryBreakEngine {
int32_t rangeStart,
int32_t rangeEnd,
UVector32 &foundBreaks,
+ UBool isPhraseBreaking,
UErrorCode& status) const override;
};
diff --git a/Build/source/libs/icu/icu-src/source/common/localematcher.cpp b/Build/source/libs/icu/icu-src/source/common/localematcher.cpp
index 3d178dfbaf1..2cad708d99f 100644
--- a/Build/source/libs/icu/icu-src/source/common/localematcher.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/localematcher.cpp
@@ -168,12 +168,9 @@ void LocaleMatcher::Builder::clearSupportedLocales() {
bool LocaleMatcher::Builder::ensureSupportedLocaleVector() {
if (U_FAILURE(errorCode_)) { return false; }
if (supportedLocales_ != nullptr) { return true; }
- supportedLocales_ = new UVector(uprv_deleteUObject, nullptr, errorCode_);
+ LocalPointer<UVector> lpSupportedLocales(new UVector(uprv_deleteUObject, nullptr, errorCode_), errorCode_);
if (U_FAILURE(errorCode_)) { return false; }
- if (supportedLocales_ == nullptr) {
- errorCode_ = U_MEMORY_ALLOCATION_ERROR;
- return false;
- }
+ supportedLocales_ = lpSupportedLocales.orphan();
return true;
}
@@ -187,9 +184,8 @@ LocaleMatcher::Builder &LocaleMatcher::Builder::setSupportedLocalesFromListStrin
for (int32_t i = 0; i < length; ++i) {
Locale *locale = list.orphanLocaleAt(i);
if (locale == nullptr) { continue; }
- supportedLocales_->addElementX(locale, errorCode_);
+ supportedLocales_->adoptElement(locale, errorCode_);
if (U_FAILURE(errorCode_)) {
- delete locale;
break;
}
}
@@ -197,35 +193,21 @@ LocaleMatcher::Builder &LocaleMatcher::Builder::setSupportedLocalesFromListStrin
}
LocaleMatcher::Builder &LocaleMatcher::Builder::setSupportedLocales(Locale::Iterator &locales) {
- if (U_FAILURE(errorCode_)) { return *this; }
- clearSupportedLocales();
- if (!ensureSupportedLocaleVector()) { return *this; }
- while (locales.hasNext()) {
- const Locale &locale = locales.next();
- Locale *clone = locale.clone();
- if (clone == nullptr) {
- errorCode_ = U_MEMORY_ALLOCATION_ERROR;
- break;
- }
- supportedLocales_->addElementX(clone, errorCode_);
- if (U_FAILURE(errorCode_)) {
- delete clone;
- break;
+ if (ensureSupportedLocaleVector()) {
+ clearSupportedLocales();
+ while (locales.hasNext() && U_SUCCESS(errorCode_)) {
+ const Locale &locale = locales.next();
+ LocalPointer<Locale> clone (locale.clone(), errorCode_);
+ supportedLocales_->adoptElement(clone.orphan(), errorCode_);
}
}
return *this;
}
LocaleMatcher::Builder &LocaleMatcher::Builder::addSupportedLocale(const Locale &locale) {
- if (!ensureSupportedLocaleVector()) { return *this; }
- Locale *clone = locale.clone();
- if (clone == nullptr) {
- errorCode_ = U_MEMORY_ALLOCATION_ERROR;
- return *this;
- }
- supportedLocales_->addElementX(clone, errorCode_);
- if (U_FAILURE(errorCode_)) {
- delete clone;
+ if (ensureSupportedLocaleVector()) {
+ LocalPointer<Locale> clone(locale.clone(), errorCode_);
+ supportedLocales_->adoptElement(clone.orphan(), errorCode_);
}
return *this;
}
diff --git a/Build/source/libs/icu/icu-src/source/common/locid.cpp b/Build/source/libs/icu/icu-src/source/common/locid.cpp
index e8859c7048b..73bb8d8aec1 100644
--- a/Build/source/libs/icu/icu-src/source/common/locid.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/locid.cpp
@@ -1204,14 +1204,11 @@ AliasReplacer::parseLanguageReplacement(
// We have multiple field so we have to allocate and parse
CharString* str = new CharString(
replacement, (int32_t)uprv_strlen(replacement), status);
+ LocalPointer<CharString> lpStr(str, status);
+ toBeFreed.adoptElement(lpStr.orphan(), status);
if (U_FAILURE(status)) {
return;
}
- if (str == nullptr) {
- status = U_MEMORY_ALLOCATION_ERROR;
- return;
- }
- toBeFreed.addElementX(str, status);
char* data = str->data();
replacedLanguage = (const char*) data;
char* endOfField = uprv_strchr(data, '_');
@@ -1420,12 +1417,9 @@ AliasReplacer::replaceTerritory(UVector& toBeFreed, UErrorCode& status)
(int32_t)(firstSpace - replacement), status), status);
}
if (U_FAILURE(status)) { return false; }
- if (item.isNull()) {
- status = U_MEMORY_ALLOCATION_ERROR;
- return false;
- }
replacedRegion = item->data();
- toBeFreed.addElementX(item.orphan(), status);
+ toBeFreed.adoptElement(item.orphan(), status);
+ if (U_FAILURE(status)) { return false; }
}
U_ASSERT(!same(region, replacedRegion));
region = replacedRegion;
@@ -1659,10 +1653,10 @@ AliasReplacer::replace(const Locale& locale, CharString& out, UErrorCode& status
while ((end = uprv_strchr(start, SEP_CHAR)) != nullptr &&
U_SUCCESS(status)) {
*end = NULL_CHAR; // null terminate inside variantsBuff
- variants.addElementX(start, status);
+ variants.addElement(start, status);
start = end + 1;
}
- variants.addElementX(start, status);
+ variants.addElement(start, status);
}
if (U_FAILURE(status)) { return false; }
diff --git a/Build/source/libs/icu/icu-src/source/common/lstmbe.cpp b/Build/source/libs/icu/icu-src/source/common/lstmbe.cpp
index 3793abceb3f..f6114cdfe25 100644
--- a/Build/source/libs/icu/icu-src/source/common/lstmbe.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/lstmbe.cpp
@@ -1,8 +1,8 @@
// © 2021 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
+#include <complex>
#include <utility>
-#include <ctgmath>
#include "unicode/utypes.h"
@@ -639,6 +639,7 @@ LSTMBreakEngine::divideUpDictionaryRange( UText *text,
int32_t startPos,
int32_t endPos,
UVector32 &foundBreaks,
+ UBool /* isPhraseBreaking */,
UErrorCode& status) const {
if (U_FAILURE(status)) return 0;
int32_t beginFoundBreakSize = foundBreaks.size();
diff --git a/Build/source/libs/icu/icu-src/source/common/lstmbe.h b/Build/source/libs/icu/icu-src/source/common/lstmbe.h
index c3f7ecf8154..ffdf805eca2 100644
--- a/Build/source/libs/icu/icu-src/source/common/lstmbe.h
+++ b/Build/source/libs/icu/icu-src/source/common/lstmbe.h
@@ -62,6 +62,7 @@ protected:
int32_t rangeStart,
int32_t rangeEnd,
UVector32 &foundBreaks,
+ UBool isPhraseBreaking,
UErrorCode& status) const override;
private:
const LSTMData* fData;
diff --git a/Build/source/libs/icu/icu-src/source/common/normalizer2impl.cpp b/Build/source/libs/icu/icu-src/source/common/normalizer2impl.cpp
index 5bfd49e8cb9..e6bd75e7173 100644
--- a/Build/source/libs/icu/icu-src/source/common/normalizer2impl.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/normalizer2impl.cpp
@@ -2496,15 +2496,18 @@ void CanonIterData::addToStartSet(UChar32 origin, UChar32 decompLead, UErrorCode
// origin is not the first character, or it is U+0000.
UnicodeSet *set;
if((canonValue&CANON_HAS_SET)==0) {
- set=new UnicodeSet;
- if(set==NULL) {
- errorCode=U_MEMORY_ALLOCATION_ERROR;
+ LocalPointer<UnicodeSet> lpSet(new UnicodeSet, errorCode);
+ set=lpSet.getAlias();
+ if(U_FAILURE(errorCode)) {
return;
}
UChar32 firstOrigin=(UChar32)(canonValue&CANON_VALUE_MASK);
canonValue=(canonValue&~CANON_VALUE_MASK)|CANON_HAS_SET|(uint32_t)canonStartSets.size();
umutablecptrie_set(mutableTrie, decompLead, canonValue, &errorCode);
- canonStartSets.addElementX(set, errorCode);
+ canonStartSets.adoptElement(lpSet.orphan(), errorCode);
+ if (U_FAILURE(errorCode)) {
+ return;
+ }
if(firstOrigin!=0) {
set->add(firstOrigin);
}
diff --git a/Build/source/libs/icu/icu-src/source/common/rbbi.cpp b/Build/source/libs/icu/icu-src/source/common/rbbi.cpp
index f65177f2323..cae8d154b30 100644
--- a/Build/source/libs/icu/icu-src/source/common/rbbi.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/rbbi.cpp
@@ -82,6 +82,19 @@ RuleBasedBreakIterator::RuleBasedBreakIterator(RBBIDataHeader* data, UErrorCode
}
}
+//-------------------------------------------------------------------------------
+//
+// Constructor from a UDataMemory handle to precompiled break rules
+// stored in an ICU data file. This construcotr is private API,
+// only for internal use.
+//
+//-------------------------------------------------------------------------------
+RuleBasedBreakIterator::RuleBasedBreakIterator(UDataMemory* udm, UBool isPhraseBreaking,
+ UErrorCode &status) : RuleBasedBreakIterator(udm, status)
+{
+ fIsPhraseBreaking = isPhraseBreaking;
+}
+
//
// Construct from precompiled binary rules (tables). This constructor is public API,
// taking the rules as a (const uint8_t *) to match the type produced by getBinaryRules().
@@ -322,6 +335,7 @@ void RuleBasedBreakIterator::init(UErrorCode &status) {
fBreakCache = nullptr;
fDictionaryCache = nullptr;
fLookAheadMatches = nullptr;
+ fIsPhraseBreaking = false;
// Note: IBM xlC is unable to assign or initialize member fText from UTEXT_INITIALIZER.
// fText = UTEXT_INITIALIZER;
diff --git a/Build/source/libs/icu/icu-src/source/common/rbbi_cache.cpp b/Build/source/libs/icu/icu-src/source/common/rbbi_cache.cpp
index 6bfe3feca49..26d82df7811 100644
--- a/Build/source/libs/icu/icu-src/source/common/rbbi_cache.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/rbbi_cache.cpp
@@ -163,7 +163,7 @@ void RuleBasedBreakIterator::DictionaryCache::populateDictionary(int32_t startPo
// Ask the language object if there are any breaks. It will add them to the cache and
// leave the text pointer on the other side of its range, ready to search for the next one.
if (lbe != NULL) {
- foundBreakCount += lbe->findBreaks(text, rangeStart, rangeEnd, fBreaks, status);
+ foundBreakCount += lbe->findBreaks(text, rangeStart, rangeEnd, fBreaks, fBI->fIsPhraseBreaking, status);
}
// Reload the loop variables for the next go-round
diff --git a/Build/source/libs/icu/icu-src/source/common/serv.cpp b/Build/source/libs/icu/icu-src/source/common/serv.cpp
index 0c54a4dce99..c26dbca1a9c 100644
--- a/Build/source/libs/icu/icu-src/source/common/serv.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/serv.cpp
@@ -625,10 +625,7 @@ ICUService::getVisibleIDs(UVector& result, const UnicodeString* matchID, UErrorC
}
}
- LocalPointer<UnicodeString> idClone(new UnicodeString(*id), status);
- if (U_SUCCESS(status) && idClone->isBogus()) {
- status = U_MEMORY_ALLOCATION_ERROR;
- }
+ LocalPointer<UnicodeString> idClone(id->clone(), status);
result.adoptElement(idClone.orphan(), status);
}
delete fallbackKey;
diff --git a/Build/source/libs/icu/icu-src/source/common/servls.cpp b/Build/source/libs/icu/icu-src/source/common/servls.cpp
index 7108afd4a52..98f0a8a12b0 100644
--- a/Build/source/libs/icu/icu-src/source/common/servls.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/servls.cpp
@@ -179,7 +179,8 @@ private:
length = other._ids.size();
for(i = 0; i < length; ++i) {
- _ids.addElementX(((UnicodeString *)other._ids.elementAt(i))->clone(), status);
+ LocalPointer<UnicodeString> clonedId(((UnicodeString *)other._ids.elementAt(i))->clone(), status);
+ _ids.adoptElement(clonedId.orphan(), status);
}
if(U_SUCCESS(status)) {
diff --git a/Build/source/libs/icu/icu-src/source/common/servnotf.cpp b/Build/source/libs/icu/icu-src/source/common/servnotf.cpp
index 342e0d9f24d..d9fb3887520 100644
--- a/Build/source/libs/icu/icu-src/source/common/servnotf.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/servnotf.cpp
@@ -49,7 +49,11 @@ ICUNotifier::addListener(const EventListener* l, UErrorCode& status)
if (acceptsListener(*l)) {
Mutex lmx(&notifyLock);
if (listeners == NULL) {
- listeners = new UVector(5, status);
+ LocalPointer<UVector> lpListeners(new UVector(5, status), status);
+ if (U_FAILURE(status)) {
+ return;
+ }
+ listeners = lpListeners.orphan();
} else {
for (int i = 0, e = listeners->size(); i < e; ++i) {
const EventListener* el = (const EventListener*)(listeners->elementAt(i));
@@ -59,7 +63,7 @@ ICUNotifier::addListener(const EventListener* l, UErrorCode& status)
}
}
- listeners->addElementX((void*)l, status); // cast away const
+ listeners->addElement((void*)l, status); // cast away const
}
#ifdef NOTIFIER_DEBUG
else {
@@ -102,13 +106,11 @@ ICUNotifier::removeListener(const EventListener *l, UErrorCode& status)
void
ICUNotifier::notifyChanged(void)
{
+ Mutex lmx(&notifyLock);
if (listeners != NULL) {
- Mutex lmx(&notifyLock);
- if (listeners != NULL) {
- for (int i = 0, e = listeners->size(); i < e; ++i) {
- EventListener* el = (EventListener*)listeners->elementAt(i);
- notifyListener(*el);
- }
+ for (int i = 0, e = listeners->size(); i < e; ++i) {
+ EventListener* el = (EventListener*)listeners->elementAt(i);
+ notifyListener(*el);
}
}
}
diff --git a/Build/source/libs/icu/icu-src/source/common/ubrk.cpp b/Build/source/libs/icu/icu-src/source/common/ubrk.cpp
index bb5bdd1b501..f4e064961f3 100644
--- a/Build/source/libs/icu/icu-src/source/common/ubrk.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/ubrk.cpp
@@ -168,7 +168,7 @@ ubrk_safeClone(
BreakIterator *newBI = ((BreakIterator *)bi)->clone();
if (newBI == NULL) {
*status = U_MEMORY_ALLOCATION_ERROR;
- } else {
+ } else if (pBufferSize != NULL) {
*status = U_SAFECLONE_ALLOCATED_WARNING;
}
return (UBreakIterator *)newBI;
@@ -176,15 +176,7 @@ ubrk_safeClone(
U_CAPI UBreakIterator * U_EXPORT2
ubrk_clone(const UBreakIterator *bi, UErrorCode *status) {
- if (U_FAILURE(*status)) {
- return nullptr;
- }
- BreakIterator *newBI = ((BreakIterator *)bi)->clone();
- if (newBI == nullptr) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- return nullptr;
- }
- return (UBreakIterator *)newBI;
+ return ubrk_safeClone(bi, nullptr, nullptr, status);
}
diff --git a/Build/source/libs/icu/icu-src/source/common/ucase.cpp b/Build/source/libs/icu/icu-src/source/common/ucase.cpp
index 4aa856507aa..388c86b1bba 100644
--- a/Build/source/libs/icu/icu-src/source/common/ucase.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/ucase.cpp
@@ -22,27 +22,14 @@
#include "unicode/utypes.h"
#include "unicode/unistr.h"
#include "unicode/uset.h"
-#include "unicode/udata.h" /* UDataInfo */
#include "unicode/utf16.h"
-#include "ucmndata.h" /* DataHeader */
-#include "udatamem.h"
-#include "umutex.h"
-#include "uassert.h"
#include "cmemory.h"
-#include "utrie2.h"
+#include "uassert.h"
#include "ucase.h"
+#include "umutex.h"
+#include "utrie2.h"
-struct UCaseProps {
- UDataMemory *mem;
- const int32_t *indexes;
- const uint16_t *exceptions;
- const uint16_t *unfold;
-
- UTrie2 trie;
- uint8_t formatVersion[4];
-};
-
-/* ucase_props_data.h is machine-generated by gencase --csource */
+/* ucase_props_data.h is machine-generated by genprops/casepropsbuilder.cpp */
#define INCLUDED_FROM_UCASE_CPP
#include "ucase_props_data.h"
@@ -77,6 +64,13 @@ ucase_addPropertyStarts(const USetAdder *sa, UErrorCode *pErrorCode) {
/* data access primitives --------------------------------------------------- */
+U_CAPI const struct UCaseProps * U_EXPORT2
+ucase_getSingleton(int32_t *pExceptionsLength, int32_t *pUnfoldLength) {
+ *pExceptionsLength = UPRV_LENGTHOF(ucase_props_exceptions);
+ *pUnfoldLength = UPRV_LENGTHOF(ucase_props_unfold);
+ return &ucase_props_singleton;
+}
+
U_CFUNC const UTrie2 * U_EXPORT2
ucase_getTrie() {
return &ucase_props_singleton.trie;
@@ -690,7 +684,7 @@ ucase_isCaseSensitive(UChar32 c) {
* - The general category of C is
* Nonspacing Mark (Mn), or Enclosing Mark (Me), or Format Control (Cf), or
* Letter Modifier (Lm), or Symbol Modifier (Sk)
- * - C is one of the following characters
+ * - C is one of the following characters
* U+0027 APOSTROPHE
* U+00AD SOFT HYPHEN (SHY)
* U+2019 RIGHT SINGLE QUOTATION MARK
@@ -1064,6 +1058,8 @@ ucase_toFullLower(UChar32 c,
// The sign of the result has meaning, input must be non-negative so that it can be returned as is.
U_ASSERT(c >= 0);
UChar32 result=c;
+ // Reset the output pointer in case it was uninitialized.
+ *pString=nullptr;
uint16_t props=UTRIE2_GET16(&ucase_props_singleton.trie, c);
if(!UCASE_HAS_EXCEPTION(props)) {
if(UCASE_IS_UPPER_OR_TITLE(props)) {
@@ -1148,7 +1144,6 @@ ucase_toFullLower(UChar32 c,
0307; ; 0307; 0307; tr After_I; # COMBINING DOT ABOVE
0307; ; 0307; 0307; az After_I; # COMBINING DOT ABOVE
*/
- *pString=nullptr;
return 0; /* remove the dot (continue without output) */
} else if(loc==UCASE_LOC_TURKISH && c==0x49 && !isFollowedByDotAbove(iter, context)) {
/*
@@ -1215,6 +1210,8 @@ toUpperOrTitle(UChar32 c,
// The sign of the result has meaning, input must be non-negative so that it can be returned as is.
U_ASSERT(c >= 0);
UChar32 result=c;
+ // Reset the output pointer in case it was uninitialized.
+ *pString=nullptr;
uint16_t props=UTRIE2_GET16(&ucase_props_singleton.trie, c);
if(!UCASE_HAS_EXCEPTION(props)) {
if(UCASE_GET_TYPE(props)==UCASE_LOWER) {
@@ -1252,7 +1249,6 @@ toUpperOrTitle(UChar32 c,
0307; 0307; ; ; lt After_Soft_Dotted; # COMBINING DOT ABOVE
*/
- *pString=nullptr;
return 0; /* remove the dot (continue without output) */
} else if(c==0x0587) {
// See ICU-13416:
@@ -1449,6 +1445,8 @@ ucase_toFullFolding(UChar32 c,
// The sign of the result has meaning, input must be non-negative so that it can be returned as is.
U_ASSERT(c >= 0);
UChar32 result=c;
+ // Reset the output pointer in case it was uninitialized.
+ *pString=nullptr;
uint16_t props=UTRIE2_GET16(&ucase_props_singleton.trie, c);
if(!UCASE_HAS_EXCEPTION(props)) {
if(UCASE_IS_UPPER_OR_TITLE(props)) {
@@ -1542,7 +1540,7 @@ U_CAPI UChar32 U_EXPORT2
u_tolower(UChar32 c) {
return ucase_tolower(c);
}
-
+
/* Transforms the Unicode character to its upper case equivalent.*/
U_CAPI UChar32 U_EXPORT2
u_toupper(UChar32 c) {
diff --git a/Build/source/libs/icu/icu-src/source/common/ucase.h b/Build/source/libs/icu/icu-src/source/common/ucase.h
index a018f82b81b..7bf57fd3706 100644
--- a/Build/source/libs/icu/icu-src/source/common/ucase.h
+++ b/Build/source/libs/icu/icu-src/source/common/ucase.h
@@ -312,6 +312,21 @@ UCaseMapFull(UChar32 c,
U_CDECL_END
+/* for icuexportdata -------------------------------------------------------- */
+
+struct UCaseProps {
+ void *mem; // TODO: was unused, and type UDataMemory -- remove
+ const int32_t *indexes;
+ const uint16_t *exceptions;
+ const uint16_t *unfold;
+
+ UTrie2 trie;
+ uint8_t formatVersion[4];
+};
+
+U_CAPI const struct UCaseProps * U_EXPORT2
+ucase_getSingleton(int32_t *pExceptionsLength, int32_t *pUnfoldLength);
+
/* file definitions --------------------------------------------------------- */
#define UCASE_DATA_NAME "ucase"
diff --git a/Build/source/libs/icu/icu-src/source/common/ucasemap.cpp b/Build/source/libs/icu/icu-src/source/common/ucasemap.cpp
index ed72bda828f..95b55d56a02 100644
--- a/Build/source/libs/icu/icu-src/source/common/ucasemap.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/ucasemap.cpp
@@ -112,8 +112,7 @@ ucasemap_setLocale(UCaseMap *csm, const char *locale, UErrorCode *pErrorCode) {
if(length==sizeof(csm->locale)) {
*pErrorCode=U_BUFFER_OVERFLOW_ERROR;
}
- if(U_SUCCESS(*pErrorCode)) {
- csm->caseLocale=UCASE_LOC_UNKNOWN;
+ if(U_SUCCESS(*pErrorCode)) {
csm->caseLocale = ucase_getCaseLocale(csm->locale);
} else {
csm->locale[0]=0;
@@ -420,6 +419,97 @@ void toUpper(int32_t caseLocale, uint32_t options,
#if !UCONFIG_NO_BREAK_ITERATION
+namespace {
+
+constexpr uint8_t ACUTE_BYTE0 = u8"\u0301"[0];
+
+constexpr uint8_t ACUTE_BYTE1 = u8"\u0301"[1];
+
+/**
+ * Input: c is a letter I with or without acute accent.
+ * start is the index in src after c, and is less than segmentLimit.
+ * If a plain i/I is followed by a plain j/J,
+ * or an i/I with acute (precomposed or decomposed) is followed by a j/J with acute,
+ * then we output accordingly.
+ *
+ * @return the src index after the titlecased sequence, or the start index if no Dutch IJ
+ */
+int32_t maybeTitleDutchIJ(const uint8_t *src, UChar32 c, int32_t start, int32_t segmentLimit,
+ ByteSink &sink, uint32_t options, icu::Edits *edits, UErrorCode &errorCode) {
+ U_ASSERT(start < segmentLimit);
+
+ int32_t index = start;
+ bool withAcute = false;
+
+ // If the conditions are met, then the following variables tell us what to output.
+ int32_t unchanged1 = 0; // code units before the j, or the whole sequence (0..3)
+ bool doTitleJ = false; // true if the j needs to be titlecased
+ int32_t unchanged2 = 0; // after the j (0 or 1)
+
+ // next character after the first letter
+ UChar32 c2;
+ c2 = src[index++];
+
+ // Is the first letter an i/I with accent?
+ if (c == u'I') {
+ if (c2 == ACUTE_BYTE0 && index < segmentLimit && src[index++] == ACUTE_BYTE1) {
+ withAcute = true;
+ unchanged1 = 2; // ACUTE is 2 code units in UTF-8
+ if (index == segmentLimit) { return start; }
+ c2 = src[index++];
+ }
+ } else { // Í
+ withAcute = true;
+ }
+
+ // Is the next character a j/J?
+ if (c2 == u'j') {
+ doTitleJ = true;
+ } else if (c2 == u'J') {
+ ++unchanged1;
+ } else {
+ return start;
+ }
+
+ // A plain i/I must be followed by a plain j/J.
+ // An i/I with acute must be followed by a j/J with acute.
+ if (withAcute) {
+ if ((index + 1) >= segmentLimit || src[index++] != ACUTE_BYTE0 || src[index++] != ACUTE_BYTE1) {
+ return start;
+ }
+ if (doTitleJ) {
+ unchanged2 = 2; // ACUTE is 2 code units in UTF-8
+ } else {
+ unchanged1 = unchanged1 + 2; // ACUTE is 2 code units in UTF-8
+ }
+ }
+
+ // There must not be another combining mark.
+ if (index < segmentLimit) {
+ int32_t cp;
+ int32_t i = index;
+ U8_NEXT(src, i, segmentLimit, cp);
+ uint32_t typeMask = U_GET_GC_MASK(cp);
+ if ((typeMask & U_GC_M_MASK) != 0) {
+ return start;
+ }
+ }
+
+ // Output the rest of the Dutch IJ.
+ ByteSinkUtil::appendUnchanged(src + start, unchanged1, sink, options, edits, errorCode);
+ start += unchanged1;
+ if (doTitleJ) {
+ ByteSinkUtil::appendCodePoint(1, u'J', sink, edits);
+ ++start;
+ }
+ ByteSinkUtil::appendUnchanged(src + start, unchanged2, sink, options, edits, errorCode);
+
+ U_ASSERT(start + unchanged2 == index);
+ return index;
+}
+
+} // namespace
+
U_CFUNC void U_CALLCONV
ucasemap_internalUTF8ToTitle(
int32_t caseLocale, uint32_t options, BreakIterator *iter,
@@ -504,19 +594,14 @@ ucasemap_internalUTF8ToTitle(
}
/* Special case Dutch IJ titlecasing */
- if (titleStart+1 < index &&
- caseLocale == UCASE_LOC_DUTCH &&
- (src[titleStart] == 0x0049 || src[titleStart] == 0x0069)) {
- if (src[titleStart+1] == 0x006A) {
- ByteSinkUtil::appendCodePoint(1, 0x004A, sink, edits);
- titleLimit++;
- } else if (src[titleStart+1] == 0x004A) {
- // Keep the capital J from getting lowercased.
- if (!ByteSinkUtil::appendUnchanged(src+titleStart+1, 1,
- sink, options, edits, errorCode)) {
- return;
- }
- titleLimit++;
+ if (titleLimit < index &&
+ caseLocale == UCASE_LOC_DUTCH) {
+ if (c < 0) {
+ c = ~c;
+ }
+
+ if (c == u'I' || c == u'Í') {
+ titleLimit = maybeTitleDutchIJ(src, c, titleLimit, index, sink, options, edits, errorCode);
}
}
diff --git a/Build/source/libs/icu/icu-src/source/common/ucnv.cpp b/Build/source/libs/icu/icu-src/source/common/ucnv.cpp
index 5dcf35e0438..019bcb6a79c 100644
--- a/Build/source/libs/icu/icu-src/source/common/ucnv.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/ucnv.cpp
@@ -252,7 +252,10 @@ ucnv_safeClone(const UConverter* cnv, void *stackBuffer, int32_t *pBufferSize, U
UTRACE_EXIT_STATUS(*status);
return NULL;
}
- *status = U_SAFECLONE_ALLOCATED_WARNING;
+ // If pBufferSize was NULL as the input, pBufferSize is set to &stackBufferSize in this function.
+ if (pBufferSize != &stackBufferSize) {
+ *status = U_SAFECLONE_ALLOCATED_WARNING;
+ }
/* record the fact that memory was allocated */
*pBufferSize = bufferSizeNeeded;
@@ -317,7 +320,11 @@ ucnv_safeClone(const UConverter* cnv, void *stackBuffer, int32_t *pBufferSize, U
return localConverter;
}
-
+U_CAPI UConverter* U_EXPORT2
+ucnv_clone(const UConverter* cnv, UErrorCode *status)
+{
+ return ucnv_safeClone(cnv, nullptr, nullptr, status);
+}
/*Decreases the reference counter in the shared immutable section of the object
*and frees the mutable part*/
diff --git a/Build/source/libs/icu/icu-src/source/common/ucurr.cpp b/Build/source/libs/icu/icu-src/source/common/ucurr.cpp
index 67aab4e8ffe..6e489e0563d 100644
--- a/Build/source/libs/icu/icu-src/source/common/ucurr.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/ucurr.cpp
@@ -254,7 +254,7 @@ currSymbolsEquiv_cleanup(void)
}
/**
- * Deleter for OlsonToMetaMappingEntry
+ * Deleter for IsoCodeEntry
*/
static void U_CALLCONV
deleteIsoCodeEntry(void *obj) {
diff --git a/Build/source/libs/icu/icu-src/source/common/uloc.cpp b/Build/source/libs/icu/icu-src/source/common/uloc.cpp
index c8a3f1ff731..99c6a0af39d 100644
--- a/Build/source/libs/icu/icu-src/source/common/uloc.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/uloc.cpp
@@ -186,10 +186,10 @@ NULL
};
static const char* const DEPRECATED_LANGUAGES[]={
- "in", "iw", "ji", "jw", NULL, NULL
+ "in", "iw", "ji", "jw", "mo", NULL, NULL
};
static const char* const REPLACEMENT_LANGUAGES[]={
- "id", "he", "yi", "jv", NULL, NULL
+ "id", "he", "yi", "jv", "ro", NULL, NULL
};
/**
@@ -444,7 +444,7 @@ static const char * const COUNTRIES_3[] = {
/* "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", */
"VAT", "VCT", "VEN", "VGB", "VIR", "VNM", "VUT", "WLF",
/* "WS", "XK", "YE", "YT", "ZA", "ZM", "ZW", */
- "WSM", "XXK", "YEM", "MYT", "ZAF", "ZMB", "ZWE",
+ "WSM", "XKK", "YEM", "MYT", "ZAF", "ZMB", "ZWE",
NULL,
/* "AN", "BU", "CS", "FX", "RO", "SU", "TP", "YD", "YU", "ZR" */
"ANT", "BUR", "SCG", "FXX", "ROM", "SUN", "TMP", "YMD", "YUG", "ZAR",
diff --git a/Build/source/libs/icu/icu-src/source/common/unicode/localematcher.h b/Build/source/libs/icu/icu-src/source/common/unicode/localematcher.h
index 252bb7fdc20..0f7e04a3afd 100644
--- a/Build/source/libs/icu/icu-src/source/common/unicode/localematcher.h
+++ b/Build/source/libs/icu/icu-src/source/common/unicode/localematcher.h
@@ -461,13 +461,13 @@ public:
* Option for whether to include or ignore one-way (fallback) match data.
* By default, they are included.
*
- * @param direction the match direction to set.
+ * @param matchDirection the match direction to set.
* @return this Builder object
* @stable ICU 67
*/
- Builder &setDirection(ULocMatchDirection direction) {
+ Builder &setDirection(ULocMatchDirection matchDirection) {
if (U_SUCCESS(errorCode_)) {
- direction_ = direction;
+ direction_ = matchDirection;
}
return *this;
}
diff --git a/Build/source/libs/icu/icu-src/source/common/unicode/rbbi.h b/Build/source/libs/icu/icu-src/source/common/unicode/rbbi.h
index 0ce93819f54..0bad0d3897c 100644
--- a/Build/source/libs/icu/icu-src/source/common/unicode/rbbi.h
+++ b/Build/source/libs/icu/icu-src/source/common/unicode/rbbi.h
@@ -147,6 +147,11 @@ private:
*/
int32_t *fLookAheadMatches;
+ /**
+ * A flag to indicate if phrase based breaking is enabled.
+ */
+ UBool fIsPhraseBreaking;
+
//=======================================================================
// constructors
//=======================================================================
@@ -163,6 +168,21 @@ private:
*/
RuleBasedBreakIterator(RBBIDataHeader* data, UErrorCode &status);
+ /**
+ * This constructor uses the udata interface to create a BreakIterator
+ * whose internal tables live in a memory-mapped file. "image" is an
+ * ICU UDataMemory handle for the pre-compiled break iterator tables.
+ * @param image handle to the memory image for the break iterator data.
+ * Ownership of the UDataMemory handle passes to the Break Iterator,
+ * which will be responsible for closing it when it is no longer needed.
+ * @param status Information on any errors encountered.
+ * @param isPhraseBreaking true if phrase based breaking is required, otherwise false.
+ * @see udata_open
+ * @see #getBinaryRules
+ * @internal (private)
+ */
+ RuleBasedBreakIterator(UDataMemory* image, UBool isPhraseBreaking, UErrorCode &status);
+
/** @internal */
friend class RBBIRuleBuilder;
/** @internal */
diff --git a/Build/source/libs/icu/icu-src/source/common/unicode/ubrk.h b/Build/source/libs/icu/icu-src/source/common/unicode/ubrk.h
index c603f7c13f3..2b3dc7aa576 100644
--- a/Build/source/libs/icu/icu-src/source/common/unicode/ubrk.h
+++ b/Build/source/libs/icu/icu-src/source/common/unicode/ubrk.h
@@ -312,11 +312,12 @@ ubrk_openBinaryRules(const uint8_t *binaryRules, int32_t rulesLength,
* If *pBufferSize is not enough for a stack-based safe clone,
* new memory will be allocated.
* @param status to indicate whether the operation went on smoothly or there were errors
- * An informational status value, U_SAFECLONE_ALLOCATED_ERROR, is used if any allocations were necessary.
+ * An informational status value, U_SAFECLONE_ALLOCATED_ERROR, is used
+ * if pBufferSize != NULL and any allocations were necessary
* @return pointer to the new clone
* @deprecated ICU 69 Use ubrk_clone() instead.
*/
-U_CAPI UBreakIterator * U_EXPORT2
+U_DEPRECATED UBreakIterator * U_EXPORT2
ubrk_safeClone(
const UBreakIterator *bi,
void *stackBuffer,
@@ -325,21 +326,17 @@ ubrk_safeClone(
#endif /* U_HIDE_DEPRECATED_API */
-#ifndef U_HIDE_DRAFT_API
-
/**
* Thread safe cloning operation.
* @param bi iterator to be cloned
* @param status to indicate whether the operation went on smoothly or there were errors
* @return pointer to the new clone
- * @draft ICU 69
+ * @stable ICU 69
*/
U_CAPI UBreakIterator * U_EXPORT2
ubrk_clone(const UBreakIterator *bi,
UErrorCode *status);
-#endif // U_HIDE_DRAFT_API
-
#ifndef U_HIDE_DEPRECATED_API
/**
diff --git a/Build/source/libs/icu/icu-src/source/common/unicode/ucnv.h b/Build/source/libs/icu/icu-src/source/common/unicode/ucnv.h
index 2687c984d43..20c173b6628 100644
--- a/Build/source/libs/icu/icu-src/source/common/unicode/ucnv.h
+++ b/Build/source/libs/icu/icu-src/source/common/unicode/ucnv.h
@@ -477,7 +477,7 @@ ucnv_openCCSID(int32_t codepage,
*
* <p>The name will NOT be looked up in the alias mechanism, nor will the converter be
* stored in the converter cache or the alias table. The only way to open further converters
- * is call this function multiple times, or use the ucnv_safeClone() function to clone a
+ * is call this function multiple times, or use the ucnv_clone() function to clone a
* 'primary' converter.</p>
*
* <p>A future version of ICU may add alias table lookups and/or caching
@@ -493,7 +493,7 @@ ucnv_openCCSID(int32_t codepage,
* @return the created Unicode converter object, or <TT>NULL</TT> if an error occurred
* @see udata_open
* @see ucnv_open
- * @see ucnv_safeClone
+ * @see ucnv_clone
* @see ucnv_close
* @stable ICU 2.2
*/
@@ -502,6 +502,20 @@ ucnv_openPackage(const char *packageName, const char *converterName, UErrorCode
/**
* Thread safe converter cloning operation.
+ *
+ * You must ucnv_close() the clone.
+ *
+ * @param cnv converter to be cloned
+ * @param status to indicate whether the operation went on smoothly or there were errors
+ * @return pointer to the new clone
+ * @stable ICU 71
+ */
+U_CAPI UConverter* U_EXPORT2 ucnv_clone(const UConverter *cnv, UErrorCode *status);
+
+#ifndef U_HIDE_DEPRECATED_API
+
+/**
+ * Thread safe converter cloning operation.
* For most efficient operation, pass in a stackBuffer (and a *pBufferSize)
* with at least U_CNV_SAFECLONE_BUFFERSIZE bytes of space.
* If the buffer size is sufficient, then the clone will use the stack buffer;
@@ -532,21 +546,19 @@ ucnv_openPackage(const char *packageName, const char *converterName, UErrorCode
* pointer to size of allocated space.
* @param status to indicate whether the operation went on smoothly or there were errors
* An informational status value, U_SAFECLONE_ALLOCATED_WARNING,
- * is used if any allocations were necessary.
+ * is used if pBufferSize != NULL and any allocations were necessary
* However, it is better to check if *pBufferSize grew for checking for
* allocations because warning codes can be overridden by subsequent
* function calls.
* @return pointer to the new clone
- * @stable ICU 2.0
+ * @deprecated ICU 71 Use ucnv_clone() instead.
*/
-U_CAPI UConverter * U_EXPORT2
+U_DEPRECATED UConverter * U_EXPORT2
ucnv_safeClone(const UConverter *cnv,
void *stackBuffer,
int32_t *pBufferSize,
UErrorCode *status);
-#ifndef U_HIDE_DEPRECATED_API
-
/**
* \def U_CNV_SAFECLONE_BUFFERSIZE
* Definition of a buffer size that is designed to be large enough for
diff --git a/Build/source/libs/icu/icu-src/source/common/unicode/uniset.h b/Build/source/libs/icu/icu-src/source/common/unicode/uniset.h
index 730337a3535..310c7c8d201 100644
--- a/Build/source/libs/icu/icu-src/source/common/unicode/uniset.h
+++ b/Build/source/libs/icu/icu-src/source/common/unicode/uniset.h
@@ -1229,7 +1229,6 @@ public:
*/
UnicodeSet& retain(UChar32 c);
-#ifndef U_HIDE_DRAFT_API
/**
* Retains only the specified string from this set if it is present.
* Upon return this set will be empty if it did not contain s, or
@@ -1238,10 +1237,9 @@ public:
*
* @param s the source string
* @return this object, for chaining
- * @draft ICU 69
+ * @stable ICU 69
*/
UnicodeSet& retain(const UnicodeString &s);
-#endif // U_HIDE_DRAFT_API
/**
* Removes the specified range from this set if it is present.
diff --git a/Build/source/libs/icu/icu-src/source/common/unicode/urename.h b/Build/source/libs/icu/icu-src/source/common/unicode/urename.h
index 4605f632ea8..d9f9b8f336c 100644
--- a/Build/source/libs/icu/icu-src/source/common/unicode/urename.h
+++ b/Build/source/libs/icu/icu-src/source/common/unicode/urename.h
@@ -567,6 +567,7 @@
#define ucase_addStringCaseClosure U_ICU_ENTRY_POINT_RENAME(ucase_addStringCaseClosure)
#define ucase_fold U_ICU_ENTRY_POINT_RENAME(ucase_fold)
#define ucase_getCaseLocale U_ICU_ENTRY_POINT_RENAME(ucase_getCaseLocale)
+#define ucase_getSingleton U_ICU_ENTRY_POINT_RENAME(ucase_getSingleton)
#define ucase_getTrie U_ICU_ENTRY_POINT_RENAME(ucase_getTrie)
#define ucase_getType U_ICU_ENTRY_POINT_RENAME(ucase_getType)
#define ucase_getTypeOrIgnorable U_ICU_ENTRY_POINT_RENAME(ucase_getTypeOrIgnorable)
@@ -630,6 +631,7 @@
#define ucnv_cbFromUWriteUChars U_ICU_ENTRY_POINT_RENAME(ucnv_cbFromUWriteUChars)
#define ucnv_cbToUWriteSub U_ICU_ENTRY_POINT_RENAME(ucnv_cbToUWriteSub)
#define ucnv_cbToUWriteUChars U_ICU_ENTRY_POINT_RENAME(ucnv_cbToUWriteUChars)
+#define ucnv_clone U_ICU_ENTRY_POINT_RENAME(ucnv_clone)
#define ucnv_close U_ICU_ENTRY_POINT_RENAME(ucnv_close)
#define ucnv_compareNames U_ICU_ENTRY_POINT_RENAME(ucnv_compareNames)
#define ucnv_convert U_ICU_ENTRY_POINT_RENAME(ucnv_convert)
@@ -725,6 +727,7 @@
#define ucnvsel_selectForString U_ICU_ENTRY_POINT_RENAME(ucnvsel_selectForString)
#define ucnvsel_selectForUTF8 U_ICU_ENTRY_POINT_RENAME(ucnvsel_selectForUTF8)
#define ucnvsel_serialize U_ICU_ENTRY_POINT_RENAME(ucnvsel_serialize)
+#define ucol_clone U_ICU_ENTRY_POINT_RENAME(ucol_clone)
#define ucol_cloneBinary U_ICU_ENTRY_POINT_RENAME(ucol_cloneBinary)
#define ucol_close U_ICU_ENTRY_POINT_RENAME(ucol_close)
#define ucol_closeElements U_ICU_ENTRY_POINT_RENAME(ucol_closeElements)
@@ -904,6 +907,7 @@
#define udatpg_getBestPattern U_ICU_ENTRY_POINT_RENAME(udatpg_getBestPattern)
#define udatpg_getBestPatternWithOptions U_ICU_ENTRY_POINT_RENAME(udatpg_getBestPatternWithOptions)
#define udatpg_getDateTimeFormat U_ICU_ENTRY_POINT_RENAME(udatpg_getDateTimeFormat)
+#define udatpg_getDateTimeFormatForStyle U_ICU_ENTRY_POINT_RENAME(udatpg_getDateTimeFormatForStyle)
#define udatpg_getDecimal U_ICU_ENTRY_POINT_RENAME(udatpg_getDecimal)
#define udatpg_getDefaultHourCycle U_ICU_ENTRY_POINT_RENAME(udatpg_getDefaultHourCycle)
#define udatpg_getFieldDisplayName U_ICU_ENTRY_POINT_RENAME(udatpg_getFieldDisplayName)
@@ -918,6 +922,7 @@
#define udatpg_setAppendItemFormat U_ICU_ENTRY_POINT_RENAME(udatpg_setAppendItemFormat)
#define udatpg_setAppendItemName U_ICU_ENTRY_POINT_RENAME(udatpg_setAppendItemName)
#define udatpg_setDateTimeFormat U_ICU_ENTRY_POINT_RENAME(udatpg_setDateTimeFormat)
+#define udatpg_setDateTimeFormatForStyle U_ICU_ENTRY_POINT_RENAME(udatpg_setDateTimeFormatForStyle)
#define udatpg_setDecimal U_ICU_ENTRY_POINT_RENAME(udatpg_setDecimal)
#define udict_swap U_ICU_ENTRY_POINT_RENAME(udict_swap)
#define udtitvfmt_close U_ICU_ENTRY_POINT_RENAME(udtitvfmt_close)
diff --git a/Build/source/libs/icu/icu-src/source/common/unicode/uset.h b/Build/source/libs/icu/icu-src/source/common/unicode/uset.h
index 2ef352ef563..33332f2d362 100644
--- a/Build/source/libs/icu/icu-src/source/common/unicode/uset.h
+++ b/Build/source/libs/icu/icu-src/source/common/unicode/uset.h
@@ -628,7 +628,6 @@ uset_removeRange(USet* set, UChar32 start, UChar32 end);
U_CAPI void U_EXPORT2
uset_removeString(USet* set, const UChar* str, int32_t strLen);
-#ifndef U_HIDE_DRAFT_API
/**
* Removes EACH of the characters in this string. Note: "ch" == {"c", "h"}
* A frozen set will not be modified.
@@ -636,11 +635,10 @@ uset_removeString(USet* set, const UChar* str, int32_t strLen);
* @param set the object to be modified
* @param str the string
* @param length the length of the string, or -1 if NUL-terminated
- * @draft ICU 69
+ * @stable ICU 69
*/
U_CAPI void U_EXPORT2
uset_removeAllCodePoints(USet *set, const UChar *str, int32_t length);
-#endif // U_HIDE_DRAFT_API
/**
* Removes from this set all of its elements that are contained in the
@@ -671,7 +669,6 @@ uset_removeAll(USet* set, const USet* removeSet);
U_CAPI void U_EXPORT2
uset_retain(USet* set, UChar32 start, UChar32 end);
-#ifndef U_HIDE_DRAFT_API
/**
* Retains only the specified string from this set if it is present.
* Upon return this set will be empty if it did not contain s, or
@@ -681,7 +678,7 @@ uset_retain(USet* set, UChar32 start, UChar32 end);
* @param set the object to be modified
* @param str the string
* @param length the length of the string, or -1 if NUL-terminated
- * @draft ICU 69
+ * @stable ICU 69
*/
U_CAPI void U_EXPORT2
uset_retainString(USet *set, const UChar *str, int32_t length);
@@ -693,11 +690,10 @@ uset_retainString(USet *set, const UChar *str, int32_t length);
* @param set the object to be modified
* @param str the string
* @param length the length of the string, or -1 if NUL-terminated
- * @draft ICU 69
+ * @stable ICU 69
*/
U_CAPI void U_EXPORT2
uset_retainAllCodePoints(USet *set, const UChar *str, int32_t length);
-#endif // U_HIDE_DRAFT_API
/**
* Retains only the elements in this set that are contained in the
@@ -741,7 +737,6 @@ uset_compact(USet* set);
U_CAPI void U_EXPORT2
uset_complement(USet* set);
-#ifndef U_HIDE_DRAFT_API
/**
* Complements the specified range in this set. Any character in
* the range will be removed if it is in this set, or will be
@@ -753,7 +748,7 @@ uset_complement(USet* set);
* @param set the object to be modified
* @param start first character, inclusive, of range
* @param end last character, inclusive, of range
- * @draft ICU 69
+ * @stable ICU 69
*/
U_CAPI void U_EXPORT2
uset_complementRange(USet *set, UChar32 start, UChar32 end);
@@ -766,7 +761,7 @@ uset_complementRange(USet *set, UChar32 start, UChar32 end);
* @param set the object to be modified
* @param str the string
* @param length the length of the string, or -1 if NUL-terminated
- * @draft ICU 69
+ * @stable ICU 69
*/
U_CAPI void U_EXPORT2
uset_complementString(USet *set, const UChar *str, int32_t length);
@@ -778,11 +773,10 @@ uset_complementString(USet *set, const UChar *str, int32_t length);
* @param set the object to be modified
* @param str the string
* @param length the length of the string, or -1 if NUL-terminated
- * @draft ICU 69
+ * @stable ICU 69
*/
U_CAPI void U_EXPORT2
uset_complementAllCodePoints(USet *set, const UChar *str, int32_t length);
-#endif // U_HIDE_DRAFT_API
/**
* Complements in this set all elements contained in the specified
diff --git a/Build/source/libs/icu/icu-src/source/common/unicode/uvernum.h b/Build/source/libs/icu/icu-src/source/common/unicode/uvernum.h
index 42e8865d7e3..2706e0b0606 100644
--- a/Build/source/libs/icu/icu-src/source/common/unicode/uvernum.h
+++ b/Build/source/libs/icu/icu-src/source/common/unicode/uvernum.h
@@ -60,7 +60,7 @@
* This value will change in the subsequent releases of ICU
* @stable ICU 2.4
*/
-#define U_ICU_VERSION_MAJOR_NUM 70
+#define U_ICU_VERSION_MAJOR_NUM 71
/** The current ICU minor version as an integer.
* This value will change in the subsequent releases of ICU
@@ -86,7 +86,7 @@
* This value will change in the subsequent releases of ICU
* @stable ICU 2.6
*/
-#define U_ICU_VERSION_SUFFIX _70
+#define U_ICU_VERSION_SUFFIX _71
/**
* \def U_DEF2_ICU_ENTRY_POINT_RENAME
@@ -139,7 +139,7 @@
* This value will change in the subsequent releases of ICU
* @stable ICU 2.4
*/
-#define U_ICU_VERSION "70.1"
+#define U_ICU_VERSION "71.1"
/**
* The current ICU library major version number as a string, for library name suffixes.
@@ -152,13 +152,13 @@
*
* @stable ICU 2.6
*/
-#define U_ICU_VERSION_SHORT "70"
+#define U_ICU_VERSION_SHORT "71"
#ifndef U_HIDE_INTERNAL_API
/** Data version in ICU4C.
* @internal ICU 4.4 Internal Use Only
**/
-#define U_ICU_DATA_VERSION "70.1"
+#define U_ICU_DATA_VERSION "71.1"
#endif /* U_HIDE_INTERNAL_API */
/*===========================================================================
diff --git a/Build/source/libs/icu/icu-src/source/common/unistr.cpp b/Build/source/libs/icu/icu-src/source/common/unistr.cpp
index 077b4d6ef20..c18665928d8 100644
--- a/Build/source/libs/icu/icu-src/source/common/unistr.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/unistr.cpp
@@ -334,7 +334,8 @@ Replaceable::clone() const {
// UnicodeString overrides clone() with a real implementation
UnicodeString *
UnicodeString::clone() const {
- return new UnicodeString(*this);
+ LocalPointer<UnicodeString> clonedString(new UnicodeString(*this));
+ return clonedString.isValid() && !clonedString->isBogus() ? clonedString.orphan() : nullptr;
}
//========================================
@@ -1976,7 +1977,12 @@ The vector deleting destructor is already a part of UObject,
but defining it here makes sure that it is included with this object file.
This makes sure that static library dependencies are kept to a minimum.
*/
+#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 1100
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-function"
static void uprv_UnicodeStringDummy(void) {
delete [] (new UnicodeString[2]);
}
+#pragma GCC diagnostic pop
+#endif
#endif
diff --git a/Build/source/libs/icu/icu-src/source/common/uposixdefs.h b/Build/source/libs/icu/icu-src/source/common/uposixdefs.h
index 2ac6ac48cf4..6af520bf9f1 100644
--- a/Build/source/libs/icu/icu-src/source/common/uposixdefs.h
+++ b/Build/source/libs/icu/icu-src/source/common/uposixdefs.h
@@ -1,4 +1,4 @@
-// © 2016 and later: Unicode, Inc. and others
+// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
@@ -51,9 +51,6 @@
* Make sure things like readlink and such functions work.
* Poorly upgraded Solaris machines can't have this defined.
* Cleanly installed Solaris can use this #define.
- * [Experience with TeX Live is that it always causes failure.
- * http://tug.org/pipermail/tlbuild/2013q1/002493.html
- * http://tug.org/pipermail/tlbuild/2013q1/002536.html ]
*
* z/OS needs this definition for timeval and to get usleep.
*/
diff --git a/Build/source/libs/icu/icu-src/source/common/ustrcase.cpp b/Build/source/libs/icu/icu-src/source/common/ustrcase.cpp
index 36b19e75f2d..43910ea5209 100644
--- a/Build/source/libs/icu/icu-src/source/common/ustrcase.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/ustrcase.cpp
@@ -36,6 +36,12 @@
#include "ustr_imp.h"
#include "uassert.h"
+/**
+ * Code point for COMBINING ACUTE ACCENT
+ * @internal
+ */
+#define ACUTE u'\u0301'
+
U_NAMESPACE_BEGIN
namespace {
@@ -396,6 +402,94 @@ U_NAMESPACE_USE
#if !UCONFIG_NO_BREAK_ITERATION
+namespace {
+
+/**
+ * Input: c is a letter I with or without acute accent.
+ * start is the index in src after c, and is less than segmentLimit.
+ * If a plain i/I is followed by a plain j/J,
+ * or an i/I with acute (precomposed or decomposed) is followed by a j/J with acute,
+ * then we output accordingly.
+ *
+ * @return the src index after the titlecased sequence, or the start index if no Dutch IJ
+ */
+int32_t maybeTitleDutchIJ(const UChar *src, UChar32 c, int32_t start, int32_t segmentLimit,
+ UChar *dest, int32_t &destIndex, int32_t destCapacity, uint32_t options,
+ icu::Edits *edits) {
+ U_ASSERT(start < segmentLimit);
+
+ int32_t index = start;
+ bool withAcute = false;
+
+ // If the conditions are met, then the following variables tell us what to output.
+ int32_t unchanged1 = 0; // code units before the j, or the whole sequence (0..3)
+ bool doTitleJ = false; // true if the j needs to be titlecased
+ int32_t unchanged2 = 0; // after the j (0 or 1)
+
+ // next character after the first letter
+ UChar c2 = src[index++];
+
+ // Is the first letter an i/I with accent?
+ if (c == u'I') {
+ if (c2 == ACUTE) {
+ withAcute = true;
+ unchanged1 = 1;
+ if (index == segmentLimit) { return start; }
+ c2 = src[index++];
+ }
+ } else { // Í
+ withAcute = true;
+ }
+
+ // Is the next character a j/J?
+ if (c2 == u'j') {
+ doTitleJ = true;
+ } else if (c2 == u'J') {
+ ++unchanged1;
+ } else {
+ return start;
+ }
+
+ // A plain i/I must be followed by a plain j/J.
+ // An i/I with acute must be followed by a j/J with acute.
+ if (withAcute) {
+ if (index == segmentLimit || src[index++] != ACUTE) { return start; }
+ if (doTitleJ) {
+ unchanged2 = 1;
+ } else {
+ ++unchanged1;
+ }
+ }
+
+ // There must not be another combining mark.
+ if (index < segmentLimit) {
+ int32_t cp;
+ int32_t i = index;
+ U16_NEXT(src, i, segmentLimit, cp);
+ uint32_t typeMask = U_GET_GC_MASK(cp);
+ if ((typeMask & U_GC_M_MASK) != 0) {
+ return start;
+ }
+ }
+
+ // Output the rest of the Dutch IJ.
+ destIndex = appendUnchanged(dest, destIndex, destCapacity, src + start, unchanged1, options, edits);
+ start += unchanged1;
+ if (doTitleJ) {
+ destIndex = appendUChar(dest, destIndex, destCapacity, u'J');
+ if (edits != nullptr) {
+ edits->addReplace(1, 1);
+ }
+ ++start;
+ }
+ destIndex = appendUnchanged(dest, destIndex, destCapacity, src + start, unchanged2, options, edits);
+
+ U_ASSERT(start + unchanged2 == index);
+ return index;
+}
+
+} // namespace
+
U_CFUNC int32_t U_CALLCONV
ustrcase_internalToTitle(int32_t caseLocale, uint32_t options, BreakIterator *iter,
UChar *dest, int32_t destCapacity,
@@ -412,14 +506,14 @@ ustrcase_internalToTitle(int32_t caseLocale, uint32_t options, BreakIterator *it
csc.limit=srcLength;
int32_t destIndex=0;
int32_t prev=0;
- UBool isFirstIndex=TRUE;
+ bool isFirstIndex=true;
/* titlecasing loop */
while(prev<srcLength) {
/* find next index where to titlecase */
int32_t index;
if(isFirstIndex) {
- isFirstIndex=FALSE;
+ isFirstIndex=false;
index=iter->first();
} else {
index=iter->next();
@@ -446,7 +540,7 @@ ustrcase_internalToTitle(int32_t caseLocale, uint32_t options, BreakIterator *it
// Stop with titleStart<titleLimit<=index
// if there is a character to be titlecased,
// or else stop with titleStart==titleLimit==index.
- UBool toCased = (options&U_TITLECASE_ADJUST_TO_CASED) != 0;
+ bool toCased = (options&U_TITLECASE_ADJUST_TO_CASED) != 0;
while (toCased ? UCASE_NONE==ucase_getType(c) : !ustrcase_isLNS(c)) {
titleStart=titleLimit;
if(titleLimit==index) {
@@ -479,27 +573,15 @@ ustrcase_internalToTitle(int32_t caseLocale, uint32_t options, BreakIterator *it
/* Special case Dutch IJ titlecasing */
if (titleStart+1 < index &&
- caseLocale == UCASE_LOC_DUTCH &&
- (src[titleStart] == 0x0049 || src[titleStart] == 0x0069)) {
- if (src[titleStart+1] == 0x006A) {
- destIndex=appendUChar(dest, destIndex, destCapacity, 0x004A);
- if(destIndex<0) {
- errorCode=U_INDEX_OUTOFBOUNDS_ERROR;
- return 0;
- }
- if(edits!=NULL) {
- edits->addReplace(1, 1);
- }
- titleLimit++;
- } else if (src[titleStart+1] == 0x004A) {
- // Keep the capital J from getting lowercased.
- destIndex=appendUnchanged(dest, destIndex, destCapacity,
- src+titleStart+1, 1, options, edits);
- if(destIndex<0) {
- errorCode=U_INDEX_OUTOFBOUNDS_ERROR;
- return 0;
- }
- titleLimit++;
+ caseLocale == UCASE_LOC_DUTCH) {
+ if (c < 0) {
+ c = ~c;
+ }
+
+ if (c == u'I' || c == u'Í') {
+ titleLimit = maybeTitleDutchIJ(src, c, titleStart + 1, index,
+ dest, destIndex, destCapacity, options,
+ edits);
}
}
diff --git a/Build/source/libs/icu/icu-src/source/common/uvector.cpp b/Build/source/libs/icu/icu-src/source/common/uvector.cpp
index 4da8b864e1b..844463921ef 100644
--- a/Build/source/libs/icu/icu-src/source/common/uvector.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/uvector.cpp
@@ -99,14 +99,6 @@ bool UVector::operator==(const UVector& other) const {
return true;
}
-// TODO: delete this function once all call sites have been migrated to the
-// new addElement().
-void UVector::addElementX(void* obj, UErrorCode &status) {
- if (ensureCapacityX(count + 1, status)) {
- elements[count++].pointer = obj;
- }
-}
-
void UVector::addElement(void* obj, UErrorCode &status) {
U_ASSERT(deleter == nullptr);
if (ensureCapacity(count + 1, status)) {
@@ -331,38 +323,6 @@ int32_t UVector::indexOf(UElement key, int32_t startIndex, int8_t hint) const {
return -1;
}
-UBool UVector::ensureCapacityX(int32_t minimumCapacity, UErrorCode &status) {
- if (minimumCapacity < 0) {
- status = U_ILLEGAL_ARGUMENT_ERROR;
- return FALSE;
- }
- if (capacity < minimumCapacity) {
- if (capacity > (INT32_MAX - 1) / 2) { // integer overflow check
- status = U_ILLEGAL_ARGUMENT_ERROR;
- return FALSE;
- }
- int32_t newCap = capacity * 2;
- if (newCap < minimumCapacity) {
- newCap = minimumCapacity;
- }
- if (newCap > (int32_t)(INT32_MAX / sizeof(UElement))) { // integer overflow check
- // We keep the original memory contents on bad minimumCapacity.
- status = U_ILLEGAL_ARGUMENT_ERROR;
- return FALSE;
- }
- UElement* newElems = (UElement *)uprv_realloc(elements, sizeof(UElement)*newCap);
- if (newElems == nullptr) {
- // We keep the original contents on the memory failure on realloc or bad minimumCapacity.
- status = U_MEMORY_ALLOCATION_ERROR;
- return FALSE;
- }
- elements = newElems;
- capacity = newCap;
- }
- return TRUE;
-}
-
-
UBool UVector::ensureCapacity(int32_t minimumCapacity, UErrorCode &status) {
if (U_FAILURE(status)) {
return false;
@@ -370,7 +330,7 @@ UBool UVector::ensureCapacity(int32_t minimumCapacity, UErrorCode &status) {
if (minimumCapacity < 0) {
status = U_ILLEGAL_ARGUMENT_ERROR;
return false;
- }
+ }
if (capacity < minimumCapacity) {
if (capacity > (INT32_MAX - 1) / 2) { // integer overflow check
status = U_ILLEGAL_ARGUMENT_ERROR;
@@ -396,6 +356,7 @@ UBool UVector::ensureCapacity(int32_t minimumCapacity, UErrorCode &status) {
}
return true;
}
+
/**
* Change the size of this vector as follows: If newSize is smaller,
* then truncate the array, possibly deleting held elements for i >=
diff --git a/Build/source/libs/icu/icu-src/source/common/uvector.h b/Build/source/libs/icu/icu-src/source/common/uvector.h
index f61fcc2be60..1eb7d136e7a 100644
--- a/Build/source/libs/icu/icu-src/source/common/uvector.h
+++ b/Build/source/libs/icu/icu-src/source/common/uvector.h
@@ -123,12 +123,6 @@ public:
// java.util.Vector API
//------------------------------------------------------------
- /*
- * Old version of addElement, with non-standard error handling.
- * Will be removed once all uses have been switched to the new addElement().
- */
- void addElementX(void* obj, UErrorCode &status);
-
/**
* Add an element at the end of the vector.
* For use only with vectors that do not adopt their elements, which is to say,
@@ -197,12 +191,6 @@ public:
inline UBool isEmpty(void) const {return count == 0;}
- /*
- * Old version of ensureCapacity, with non-standard error handling.
- * Will be removed once all uses have been switched to the new ensureCapacity().
- */
- UBool ensureCapacityX(int32_t minimumCapacity, UErrorCode &status);
-
UBool ensureCapacity(int32_t minimumCapacity, UErrorCode &status);
/**
diff --git a/Build/source/libs/icu/icu-src/source/common/uvectr32.cpp b/Build/source/libs/icu/icu-src/source/common/uvectr32.cpp
index a77ecb689fd..2b4d0b8a75a 100644
--- a/Build/source/libs/icu/icu-src/source/common/uvectr32.cpp
+++ b/Build/source/libs/icu/icu-src/source/common/uvectr32.cpp
@@ -83,7 +83,7 @@ void UVector32::assign(const UVector32& other, UErrorCode &ec) {
}
-bool UVector32::operator==(const UVector32& other) {
+bool UVector32::operator==(const UVector32& other) const {
int32_t i;
if (count != other.count) return false;
for (i=0; i<count; ++i) {
diff --git a/Build/source/libs/icu/icu-src/source/common/uvectr32.h b/Build/source/libs/icu/icu-src/source/common/uvectr32.h
index f08c2ade765..ecefb7af3ea 100644
--- a/Build/source/libs/icu/icu-src/source/common/uvectr32.h
+++ b/Build/source/libs/icu/icu-src/source/common/uvectr32.h
@@ -86,12 +86,12 @@ public:
* equal if they are of the same size and all elements are equal,
* as compared using this object's comparer.
*/
- bool operator==(const UVector32& other);
+ bool operator==(const UVector32& other) const;
/**
* Equivalent to !operator==()
*/
- inline bool operator!=(const UVector32& other);
+ inline bool operator!=(const UVector32& other) const;
//------------------------------------------------------------
// java.util.Vector API
@@ -268,7 +268,7 @@ inline int32_t UVector32::lastElementi(void) const {
return elementAti(count-1);
}
-inline bool UVector32::operator!=(const UVector32& other) {
+inline bool UVector32::operator!=(const UVector32& other) const {
return !operator==(other);
}
diff --git a/Build/source/libs/icu/icu-src/source/configure b/Build/source/libs/icu/icu-src/source/configure
index b7709d56556..421ef87c249 100755
--- a/Build/source/libs/icu/icu-src/source/configure
+++ b/Build/source/libs/icu/icu-src/source/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for ICU 70.1.
+# Generated by GNU Autoconf 2.69 for ICU 71.1.
#
# Report bugs to <http://icu-project.org/bugs>.
#
@@ -582,8 +582,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='ICU'
PACKAGE_TARNAME='International Components for Unicode'
-PACKAGE_VERSION='70.1'
-PACKAGE_STRING='ICU 70.1'
+PACKAGE_VERSION='71.1'
+PACKAGE_STRING='ICU 71.1'
PACKAGE_BUGREPORT='http://icu-project.org/bugs'
PACKAGE_URL='http://icu-project.org'
@@ -1375,7 +1375,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures ICU 70.1 to adapt to many kinds of systems.
+\`configure' configures ICU 71.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1442,7 +1442,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of ICU 70.1:";;
+ short | recursive ) echo "Configuration of ICU 71.1:";;
esac
cat <<\_ACEOF
@@ -1580,7 +1580,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-ICU configure 70.1
+ICU configure 71.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2326,7 +2326,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by ICU $as_me 70.1, which was
+It was created by ICU $as_me 71.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -6160,12 +6160,6 @@ $as_echo "$as_me: Adding CXXFLAGS option -std=c++11" >&6;}
else
CXXFLAGS="$OLD_CXXFLAGS"
fi
-# TL: why? http://bugs.icu-project.org/trac/ticket/13543
-# case "${host}" in
-# *-*-solaris*)
-# CXXFLAGS="$OLD_CXXFLAGS"
-# ;;
-# esac
fi
fi
@@ -8607,7 +8601,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by ICU $as_me 70.1, which was
+This file was extended by ICU $as_me 71.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -8661,7 +8655,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-ICU config.status 70.1
+ICU config.status 71.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/Build/source/libs/icu/icu-src/source/configure.ac b/Build/source/libs/icu/icu-src/source/configure.ac
index 22c11af06a3..ba97cbc286a 100644
--- a/Build/source/libs/icu/icu-src/source/configure.ac
+++ b/Build/source/libs/icu/icu-src/source/configure.ac
@@ -527,11 +527,6 @@ if [[ "$GXX" = yes ]]; then
else
CXXFLAGS="$OLD_CXXFLAGS"
fi
- case "${host}" in
- *-*-solaris*)
- CXXFLAGS="$OLD_CXXFLAGS"
- ;;
- esac
fi
fi
diff --git a/Build/source/libs/icu/icu-src/source/data/cldr-icu-readme.txt b/Build/source/libs/icu/icu-src/source/data/cldr-icu-readme.txt
index 93ba253d715..72821872e1c 100644
--- a/Build/source/libs/icu/icu-src/source/data/cldr-icu-readme.txt
+++ b/Build/source/libs/icu/icu-src/source/data/cldr-icu-readme.txt
@@ -138,24 +138,52 @@ export ICU4C_DIR=$HOME/icu-myfork/icu4c
export ICU4J_ROOT=$HOME/icu-myfork/icu4j
export TOOLS_ROOT=$HOME/icu-myfork/tools
-# 2. Build and install the CLDR jar
+# 1d. Directory for logs/notes (create if does not exist)
-cd $TOOLS_ROOT/cldr
-ant install-cldr-libs
+export NOTES=...(some directory)...
+mkdir -p $NOTES
-See the $TOOLS_ROOT/cldr/lib/README.txt file for more information on the CLDR
-jar and the install-cldr-jars.sh script.
-
-# 3. Configure ICU4C, build and test without new data first, to verify that
+# 2a. Configure ICU4C, build and test without new data first, to verify that
# there are no pre-existing errors. Here <platform> is the runConfigureICU
# code for the platform you are building, e.g. Linux, MacOSX, Cygwin.
+# (optionally build with debug enabled)
cd $ICU4C_DIR/source
-./runConfigureICU <platform>
+./runConfigureICU [--enable-debug] <platform>
make clean
-make check 2>&1 | tee /tmp/icu4c-oldData-makeCheck.txt
+make check 2>&1 | tee $NOTES/icu4c-oldData-makeCheck.txt
+
+# 2b. Now with ICU4J, build and test without new data first, to verify that
+# there are no pre-existing errors (or at least to have the pre-existing errors
+# as a base for comparison):
+
+cd $ICU4J_ROOT
+ant clean
+ant check 2>&1 | tee $NOTES/icu4j-oldData-antCheck.txt
+
+# 3. Make pre-adjustments as necessary
+# 3a. Copy latest relevant CLDR dtds to ICU
+cp -p $CLDR_DIR/common/dtd/ldml.dtd $ICU4C_DIR/source/data/dtd/cldr/common/dtd/
+cp -p $CLDR_DIR/common/dtd/ldmlICU.dtd $ICU4C_DIR/source/data/dtd/cldr/common/dtd/
+
+# 3b. Update the cldr-icu tooling to use the latest tagged version of ICU
+open $TOOLS_ROOT/cldr/cldr-to-icu/pom.xml
+# search for icu4j-for-cldr and update to the latest tagged version per instructions
+
+# 3c. Update the build for any new icu version, added locales, etc.
+open $TOOLS_ROOT/cldr/cldr-to-icu/build-icu-data.xml
+# update icuVersion, icuDataVersion if necessary
+# update lists of locales to include if necessary
+
+# 4. Build and install the CLDR jar
-# 4a. Generate the CLDR production data. This process uses ant with ICU's
+cd $TOOLS_ROOT/cldr
+ant install-cldr-libs
+
+See the $TOOLS_ROOT/cldr/lib/README.txt file for more information on the CLDR
+jar and the install-cldr-jars.sh script.
+
+# 5a. Generate the CLDR production data. This process uses ant with ICU's
# data/build.xml
#
# Running "ant cleanprod" is necessary to clean out the production data directory
@@ -167,9 +195,9 @@ make check 2>&1 | tee /tmp/icu4c-oldData-makeCheck.txt
cd $ICU4C_DIR/source/data
ant cleanprod
ant setup
-ant proddata 2>&1 | tee /tmp/cldr-newData-proddataLog.txt
+ant proddata 2>&1 | tee $NOTES/cldr-newData-proddataLog.txt
-# 4b. Build the new ICU4C data files; these include .txt files and .py files.
+# 5b. Build the new ICU4C data files; these include .txt files and .py files.
# These new files will replace whatever was already present in the ICU4C sources.
# This process uses the LdmlConverter in $TOOLS_ROOT/cldr/cldr-to-icu/;
# see $TOOLS_ROOT/cldr/cldr-to-icu/README.txt
@@ -187,59 +215,58 @@ ant proddata 2>&1 | tee /tmp/cldr-newData-proddataLog.txt
# build-icu-data.xml file, such as adding new locales etc.
cd $TOOLS_ROOT/cldr/cldr-to-icu
-ant -f build-icu-data.xml -DcldrDataDir="$CLDR_TMP_DIR/production" | tee /tmp/cldr-newData-builddataLog.txt
+ant -f build-icu-data.xml -DcldrDataDir="$CLDR_TMP_DIR/production" | tee $NOTES/cldr-newData-builddataLog.txt
-# 4c. Update the CLDR testData files needed by ICU4C and ICU4J tests, ensuring
+# 5c. Update the CLDR testData files needed by ICU4C and ICU4J tests, ensuring
# they're representative of the newest CLDR data.
cd $TOOLS_ROOT/cldr
ant copy-cldr-testdata
-# 4d. Copy from CLDR common/testData/localeIdentifiers/localeCanonicalization.txt
+# 5d. Copy from CLDR common/testData/localeIdentifiers/localeCanonicalization.txt
# into icu4c/source/test/testdata/localeCanonicalization.txt
# and icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/localeCanonicalization.txt
# and add the following line to the beginning of these two files
# # File copied from cldr common/testData/localeIdentifiers/localeCanonicalization.txt
-# 4e. For the time being, manually re-add the lstm entries in data/brkitr/root.txt
-
+# 5e. For the time being, manually re-add the lstm entries in data/brkitr/root.txt
open $ICU4C_DIR/source/data/brkitr/root.txt
-# paste the following block at the end, after the dictionaries block>
+# paste the following block after the dictionaries block and before the final closing '}':
lstm{
Thai{"Thai_graphclust_model4_heavy.res"}
Mymr{"Burmese_graphclust_model5_heavy.res"}
}
-# 5. Check which data files have modifications, which have been added or removed
+# 6. Check which data files have modifications, which have been added or removed
# (if there are no changes, you may not need to proceed further). Make sure the
# list seems reasonable.
-cd $ICU4C_DIR/source/data
+cd $ICU4C_DIR/..
git status
-# 5a. You may also want to check which files were modified in CLDR production data:
+# 6a. You may also want to check which files were modified in CLDR production data:
cd $CLDR_TMP_DIR
git status
-# 6. Fix any errors, investigate any warnings.
+# 7. Fix any errors, investigate any warnings.
#
# Fixing may entail modifying CLDR source data or TOOLS_ROOT config files or
# tooling.
-# 7. Now rebuild ICU4C with the new data and run make check tests.
+# 8. Now rebuild ICU4C with the new data and run make check tests.
# Again, keep a log so you can investigate the errors.
cd $ICU4C_DIR/source
-# 7a. If any files were added or removed (likely), re-run configure:
-./runConfigureICU <platform>
+# 8a. If any files were added or removed (likely), re-run configure:
+./runConfigureICU [--enable-debug] <platform>
make clean
-# 7b. Now do the rebuild.
-make check 2>&1 | tee /tmp/icu4c-newData-makeCheck.txt
+# 8b. Now do the rebuild.
+make check 2>&1 | tee $NOTES/icu4c-newData-makeCheck.txt
-# 8. Investigate each test case failure. The first run processing new CLDR data
+# 9. Investigate each test case failure. The first run processing new CLDR data
# from the Survey Tool can result in thousands of failures (in many cases, one
# CLDR data fix can resolve hundreds of test failures). If the error is caused
# by bad CLDR data, then file a CLDR bug, fix the data, and regenerate from
@@ -249,9 +276,9 @@ make check 2>&1 | tee /tmp/icu4c-newData-makeCheck.txt
# Note that if the new data has any differences in structure, you will have to
# update test/testdata/structLocale.txt or /tsutil/cldrtest/TestLocaleStructure
# may fail.
-# Repeat steps 4-7 until there are no errors.
+# Repeat steps 4-8 until there are no errors.
-# 9. You can also run the make check tests in exhaustive mode. As an alternative
+# 10. You can also run the make check tests in exhaustive mode. As an alternative
# you can run them as part of the pre-merge tests by adding the following as a
# comment in the pull request: "/azp run CI-Exhaustive". You should do one or the
# other; the exhaustive tests are *not* run automatically on each pull request,
@@ -260,17 +287,10 @@ make check 2>&1 | tee /tmp/icu4c-newData-makeCheck.txt
cd $ICU4C_DIR/source
export INTLTEST_OPTS="-e"
export CINTLTST_OPTS="-e"
-make check 2>&1 | tee /tmp/icu4c-newData-makeCheckEx.txt
-
-# 10. Again, investigate each failure, fixing CLDR data or ICU test cases as
-# appropriate, and repeating steps 4-7 and 9 until there are no errors.
-
-# 11. Now with ICU4J, build and test without new data first, to verify that
-# there are no pre-existing errors (or at least to have the pre-existing errors
-# as a base for comparison):
+make check 2>&1 | tee $NOTES/icu4c-newData-makeCheckEx.txt
-cd $ICU4J_ROOT
-ant check 2>&1 | tee /tmp/icu4j-oldData-antCheck.txt
+# 11. Again, investigate each failure, fixing CLDR data or ICU test cases as
+# appropriate, and repeating steps 4-8 and 10 until there are no errors.
# 12. Transfer the data to ICU4J:
cd $ICU4C_DIR/source
@@ -291,7 +311,7 @@ make icu4j-data-install
# Keep a log so you can investigate the errors.
cd $ICU4J_ROOT
-ant check 2>&1 | tee /tmp/icu4j-newData-antCheck.txt
+ant check 2>&1 | tee $NOTES/icu4j-newData-antCheck.txt
# 14. Investigate test case failures; fix test cases and repeat from step 12,
# or fix CLDR data and repeat from step 4, as appropriate, until there are no
diff --git a/Build/source/libs/icu/icu-src/source/data/dtd/cldr/common/dtd/ldml.dtd b/Build/source/libs/icu/icu-src/source/data/dtd/cldr/common/dtd/ldml.dtd
new file mode 100644
index 00000000000..c59fead460b
--- /dev/null
+++ b/Build/source/libs/icu/icu-src/source/data/dtd/cldr/common/dtd/ldml.dtd
@@ -0,0 +1,3208 @@
+<!--
+Copyright © 1991-2022 Unicode, Inc.
+For terms of use, see http://www.unicode.org/copyright.html
+SPDX-License-Identifier: Unicode-DFS-2016
+CLDR data files are interpreted according to the LDML specification (http://unicode.org/reports/tr35/)
+-->
+
+<!ELEMENT ldml ( identity, ( alias | ( fallback*, localeDisplayNames?, layout?, contextTransforms?, characters?, delimiters?, measurement?, dates?, numbers?, units?, listPatterns?, collations?, posix?, characterLabels?, segmentations?, rbnf?, typographicNames?, annotations?, metadata?, references?, special* ) ) ) >
+<!ATTLIST ldml version CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST ldml draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!-- ######################################################### -->
+
+<!ELEMENT identity ( alias | ( version, generation?, language, script?, territory?, variant?, special* ) ) >
+<!ATTLIST identity draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!-- ######################################################### -->
+<!-- # These elements are common to almost all elements defined -->
+
+<!ELEMENT alias ( special* ) >
+<!ATTLIST alias source NMTOKEN #REQUIRED >
+ <!--@MATCH:literal/locale-->
+ <!--@VALUE-->
+<!ATTLIST alias path CDATA #IMPLIED >
+ <!--@MATCH:regex/\.\..*-->
+ <!--@VALUE-->
+<!ATTLIST alias alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST alias draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT special ANY >
+
+<!ELEMENT version EMPTY >
+<!ATTLIST version number CDATA #REQUIRED >
+ <!--@MATCH:regex/\$Revision.*\$-->
+ <!--@METADATA-->
+<!ATTLIST version cldrVersion CDATA #FIXED "41" >
+ <!--@MATCH:any-->
+ <!--@VALUE-->
+<!ATTLIST version draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT generation EMPTY >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST generation date CDATA #REQUIRED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST generation draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT language ( #PCDATA ) >
+<!ATTLIST language type NMTOKEN #REQUIRED >
+ <!--@MATCH:validity/locale-->
+<!ATTLIST language alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/long, secondary, short, variant, menu-->
+<!ATTLIST language draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST language references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT script ( #PCDATA ) >
+<!ATTLIST script type NMTOKEN #REQUIRED >
+ <!--@MATCH:validity/script-->
+<!ATTLIST script alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/secondary, short, stand-alone, variant-->
+<!ATTLIST script draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST script references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT territory ( #PCDATA ) >
+<!ATTLIST territory type NMTOKEN #REQUIRED >
+ <!--@MATCH:validity/region-->
+<!ATTLIST territory alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/short, variant-->
+<!ATTLIST territory draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST territory references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT variant ( #PCDATA ) >
+<!ATTLIST variant type NMTOKEN #REQUIRED >
+ <!--@MATCH:validity/variant-->
+<!ATTLIST variant alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/secondary, variant-->
+<!ATTLIST variant draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST variant references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!-- ######################################################### -->
+
+<!ELEMENT fallback ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST fallback alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST fallback draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST fallback references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT localeDisplayNames ( alias | ( localeDisplayPattern?, languages?, scripts?, territories?, subdivisions?, variants?, keys?, types?, transformNames?, measurementSystemNames?, codePatterns?, special* ) ) >
+<!ATTLIST localeDisplayNames draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT localeDisplayPattern ( alias | ( localePattern*, localeSeparator*, localeKeyTypePattern*, special* ) ) >
+<!ATTLIST localeDisplayPattern alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST localeDisplayPattern draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST localeDisplayPattern references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT localePattern ( #PCDATA ) >
+<!ATTLIST localePattern alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST localePattern draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST localePattern references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT localeSeparator ( #PCDATA ) >
+<!ATTLIST localeSeparator alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST localeSeparator draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST localeSeparator references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT localeKeyTypePattern ( #PCDATA ) >
+<!ATTLIST localeKeyTypePattern alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST localeKeyTypePattern draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST localeKeyTypePattern references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!-- # Either 1 alias OR any specials, any order, zero or more language -->
+
+<!ELEMENT languages ( alias | ( language | special )* ) >
+<!ATTLIST languages draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST languages standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST languages references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST languages validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!-- # Either 1 alias OR any specials, any order, zero or more script -->
+
+<!ELEMENT scripts ( alias | ( script | special )* ) >
+<!ATTLIST scripts draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST scripts standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST scripts references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST scripts validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!-- # Either 1 alias OR any specials, any order, zero or more territory -->
+
+<!ELEMENT territories ( alias | ( territory | special )* ) >
+<!ATTLIST territories draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST territories standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST territories references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST territories validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT subdivisions ( alias | ( subdivision | special )* ) >
+<!ATTLIST subdivisions draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST subdivisions references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT subdivision ( #PCDATA ) >
+<!ATTLIST subdivision type NMTOKEN #REQUIRED >
+ <!--@MATCH:or/validity/subdivision||literal/AS, AW, AX, BL, CP, CW, GF, GP, GU, HK, IC, MF, MO, MP, MQ, NC, PF, PM, PR, RE, SX, TA, TF, TW, UM, VI, WF, YT, itsd, no50-->
+<!ATTLIST subdivision alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST subdivision draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!-- # Either 1 alias OR any specials, any order, zero or more variant -->
+
+<!ELEMENT variants ( alias | ( variant | special )* ) >
+<!ATTLIST variants draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST variants standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST variants references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST variants validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!-- # Either 1 alias OR any specials, any order, zero or more key -->
+
+<!ELEMENT keys ( alias | ( key | special )* ) >
+<!ATTLIST keys draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST keys standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST keys references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST keys validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT key ( #PCDATA ) >
+<!ATTLIST key type NMTOKEN #REQUIRED >
+ <!--@MATCH:or/bcp47/anykey||literal/t-->
+<!ATTLIST key alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST key draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST key references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!-- # Either 1 alias OR any specials, any order, zero or more type -->
+
+<!ELEMENT types ( alias | ( type | special )* ) >
+<!ATTLIST types draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST types standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST types references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST types validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT type ( #PCDATA ) >
+<!ATTLIST type key NMTOKEN #REQUIRED >
+ <!--@MATCH:bcp47/anykey-->
+<!ATTLIST type type NMTOKEN #REQUIRED >
+ <!--@MATCH:bcp47/anyvalue-->
+<!ATTLIST type alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/short, variant-->
+<!ATTLIST type draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST type references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT transformNames ( alias | ( transformName | special )* ) >
+ <!--@DEPRECATED-->
+<!ATTLIST transformNames draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST transformNames references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT transformName ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST transformName type NMTOKEN #REQUIRED >
+ <!--@DEPRECATED-->
+<!ATTLIST transformName alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST transformName draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST transformName references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!-- # Either 1 alias OR any specials, any order, zero or more measurementSystemName -->
+
+<!ELEMENT measurementSystemNames ( alias | ( measurementSystemName | special )* ) >
+<!ATTLIST measurementSystemNames draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST measurementSystemNames references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST measurementSystemNames validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT measurementSystemName ( #PCDATA ) >
+<!ATTLIST measurementSystemName type (US | metric | UK) #REQUIRED >
+<!ATTLIST measurementSystemName alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST measurementSystemName draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST measurementSystemName references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT codePatterns ( alias | ( codePattern | special )* ) >
+
+<!ELEMENT codePattern ( #PCDATA ) >
+<!ATTLIST codePattern type NMTOKEN #REQUIRED >
+ <!--@MATCH:literal/language, script, territory-->
+<!ATTLIST codePattern alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST codePattern draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST codePattern references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!-- ######################################################### -->
+<!-- # layout and orientation are script specific, so validSublocales attribute is not required -->
+
+<!ELEMENT layout ( alias | ( orientation*, inList*, inText*, special* ) ) >
+<!ATTLIST layout draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST layout references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT orientation ( alias | ( characterOrder*, lineOrder*, special* ) ) >
+<!ATTLIST orientation characters (left-to-right | right-to-left | top-to-bottom | bottom-to-top) #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST orientation lines (left-to-right | right-to-left | top-to-bottom | bottom-to-top) #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST orientation alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST orientation draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST orientation standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST orientation references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT characterOrder ( #PCDATA ) >
+<!ATTLIST characterOrder alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST characterOrder draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT lineOrder ( #PCDATA ) >
+<!ATTLIST lineOrder alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST lineOrder draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT inList ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST inList casing (titlecase-words | titlecase-firstword | lowercase-words | mixed) #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST inList alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST inList draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST inList references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT inText ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST inText type (languages | scripts | territories | variants | keys | types | measurementSystemNames | monthWidth | dayWidth | quarterWidth | long | fields | currency) #IMPLIED >
+ <!--@DEPRECATED-->
+<!ATTLIST inText alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST inText draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST inText references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!-- ######################################################### -->
+
+<!ELEMENT contextTransforms ( alias | ( contextTransformUsage*, special* ) ) >
+<!ATTLIST contextTransforms alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST contextTransforms draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST contextTransforms references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST contextTransforms validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT contextTransformUsage ( alias | ( contextTransform*, special* ) ) >
+<!ATTLIST contextTransformUsage type CDATA #REQUIRED >
+ <!--@MATCH:literal/calendar-field, currencyName, day-format-except-narrow, day-standalone-except-narrow, era-abbr, era-name, keyValue, languages, month-format-except-narrow, month-standalone-except-narrow, number-spellout, relative, script, typographicNames-->
+<!ATTLIST contextTransformUsage alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST contextTransformUsage draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST contextTransformUsage references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST contextTransformUsage validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT contextTransform ( #PCDATA ) >
+<!ATTLIST contextTransform type (uiListOrMenu | stand-alone) #REQUIRED >
+<!ATTLIST contextTransform alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST contextTransform draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST contextTransform references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!-- ######################################################### -->
+
+<!ELEMENT characters ( alias | ( exemplarCharacters*, ellipsis*, moreInformation*, stopwords*, indexLabels*, mapping*, parseLenients*, special* ) ) >
+<!ATTLIST characters draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT exemplarCharacters ( #PCDATA | cp )* >
+<!ATTLIST exemplarCharacters type (auxiliary | standard | punctuation | currencySymbol | index | numbers) #IMPLIED >
+ <!--@DEPRECATED:currencySymbol-->
+<!ATTLIST exemplarCharacters alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST exemplarCharacters draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST exemplarCharacters standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST exemplarCharacters references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST exemplarCharacters validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!-- # This element can occur anywhere there may be localizable data -->
+
+<!ELEMENT cp ( special* ) >
+ <!--@DEPRECATED-->
+<!ATTLIST cp hex NMTOKEN #REQUIRED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT ellipsis ( #PCDATA ) >
+<!ATTLIST ellipsis type (initial | medial | final | word-initial | word-medial | word-final) #REQUIRED >
+<!ATTLIST ellipsis alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST ellipsis draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST ellipsis references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT moreInformation ( #PCDATA ) >
+<!ATTLIST moreInformation alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST moreInformation draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST moreInformation references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT stopwords ( stopwordList* ) >
+ <!--@DEPRECATED-->
+
+<!ELEMENT stopwordList ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST stopwordList type NMTOKEN #REQUIRED >
+ <!--@DEPRECATED-->
+<!ATTLIST stopwordList alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST stopwordList draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST stopwordList references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT indexLabels ( indexSeparator*, compressedIndexSeparator*, indexRangePattern*, indexLabelBefore*, indexLabelAfter*, indexLabel* ) >
+ <!--@DEPRECATED-->
+
+<!ELEMENT indexSeparator ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST indexSeparator alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST indexSeparator draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST indexSeparator references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT compressedIndexSeparator ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST compressedIndexSeparator alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST compressedIndexSeparator draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST compressedIndexSeparator references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT indexRangePattern ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST indexRangePattern alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST indexRangePattern draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST indexRangePattern references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT indexLabelBefore ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST indexLabelBefore alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST indexLabelBefore draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST indexLabelBefore references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT indexLabelAfter ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST indexLabelAfter alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST indexLabelAfter draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST indexLabelAfter references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT indexLabel ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST indexLabel indexSource CDATA #IMPLIED >
+ <!--@DEPRECATED-->
+<!ATTLIST indexLabel priority (1 | 2 | 3) #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST indexLabel alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST indexLabel draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST indexLabel references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT mapping ( special* ) >
+ <!--@DEPRECATED-->
+<!ATTLIST mapping registry NMTOKEN #REQUIRED >
+ <!--@DEPRECATED-->
+<!ATTLIST mapping type NMTOKEN #IMPLIED >
+ <!-- use choice instead -->
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST mapping choice NMTOKEN #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST mapping alt NMTOKENS #IMPLIED >
+ <!--@DEPRECATED-->
+<!ATTLIST mapping draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST mapping standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST mapping references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST mapping validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT parseLenients ( alias | ( parseLenient*, special* ) ) >
+<!ATTLIST parseLenients scope (general | number | date) #REQUIRED >
+<!ATTLIST parseLenients level (lenient | stricter) #REQUIRED >
+
+<!ELEMENT parseLenient ( #PCDATA ) >
+<!ATTLIST parseLenient sample CDATA #REQUIRED >
+ <!--@MATCH:any-->
+<!ATTLIST parseLenient alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST parseLenient draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!-- ######################################################### -->
+
+<!ELEMENT delimiters ( alias | ( quotationStart*, quotationEnd*, alternateQuotationStart*, alternateQuotationEnd*, special* ) ) >
+<!ATTLIST delimiters alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST delimiters draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST delimiters standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST delimiters references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST delimiters validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT quotationStart ( #PCDATA | cp )* >
+<!ATTLIST quotationStart alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST quotationStart draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST quotationStart references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT quotationEnd ( #PCDATA | cp )* >
+<!ATTLIST quotationEnd alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST quotationEnd draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST quotationEnd references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT alternateQuotationStart ( #PCDATA | cp )* >
+<!ATTLIST alternateQuotationStart alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST alternateQuotationStart draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST alternateQuotationStart references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT alternateQuotationEnd ( #PCDATA | cp )* >
+<!ATTLIST alternateQuotationEnd alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST alternateQuotationEnd draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST alternateQuotationEnd references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!-- ######################################################### -->
+
+<!ELEMENT measurement ( alias | ( measurementSystem*, paperSize*, special* ) ) >
+ <!-- use measurementData in supplemental instead -->
+ <!--@DEPRECATED-->
+<!ATTLIST measurement alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST measurement draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST measurement standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST measurement references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST measurement validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT measurementSystem ( special* ) >
+ <!-- use measurementSystem in supplemental instead -->
+ <!--@DEPRECATED-->
+<!ATTLIST measurementSystem type (metric | US | UK) #REQUIRED >
+ <!-- use choice instead -->
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST measurementSystem choice (metric | US | UK) #IMPLIED >
+ <!-- really required, but needs to be optional to support type also -->
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST measurementSystem alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST measurementSystem draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST measurementSystem standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST measurementSystem references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST measurementSystem validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT paperSize ( alias | ( height*, width*, special* ) ) >
+ <!-- use paperSize in supplemental instead -->
+ <!--@DEPRECATED-->
+<!ATTLIST paperSize alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST paperSize draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST paperSize standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST paperSize references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST paperSize validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT height ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST height alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST height draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST height references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT width ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST width alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST width draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST width references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!-- ######################################################### -->
+
+<!ELEMENT dates ( alias | ( localizedPatternChars*, dateRangePattern*, calendars?, fields?, timeZoneNames?, special* ) ) >
+<!ATTLIST dates alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST dates draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dates standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dates references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST dates validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT localizedPatternChars ( #PCDATA | cp )* >
+ <!--@DEPRECATED-->
+<!ATTLIST localizedPatternChars alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST localizedPatternChars draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST localizedPatternChars standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST localizedPatternChars references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST localizedPatternChars validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT dateRangePattern ( #PCDATA ) >
+ <!-- use intervalFormats. -->
+ <!--@DEPRECATED-->
+<!ATTLIST dateRangePattern alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST dateRangePattern draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dateRangePattern standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dateRangePattern references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dateRangePattern validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT calendars ( alias | ( default*, calendar*, special* ) ) >
+ <!-- use calendarPreferenceData instead of default element -->
+<!ATTLIST calendars draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST calendars validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT default ( special* ) >
+ <!--@DEPRECATED-->
+<!ATTLIST default type NMTOKEN #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST default choice NMTOKEN #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST default alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST default draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST default references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT calendar ( alias | ( months?, monthNames?, monthAbbr?, monthPatterns?, days?, dayNames?, dayAbbr?, quarters?, week?, am*, pm*, dayPeriods?, eras?, cyclicNameSets?, dateFormats?, timeFormats?, dateTimeFormats?, fields*, special* ) ) >
+ <!-- use of fields is deprecated here -->
+<!ATTLIST calendar type NMTOKEN #REQUIRED >
+ <!--@MATCH:bcp47/ca-->
+<!ATTLIST calendar alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST calendar draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST calendar standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST calendar references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST calendar validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT months ( alias | ( default*, monthContext*, special* ) ) >
+<!ATTLIST months alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST months draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST months standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST months references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST months validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT monthContext ( alias | ( default*, monthWidth*, special* ) ) >
+<!ATTLIST monthContext type (format | stand-alone) #REQUIRED >
+<!ATTLIST monthContext alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST monthContext draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST monthContext standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST monthContext references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST monthContext validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT monthWidth ( alias | ( month*, special* ) ) >
+<!ATTLIST monthWidth type (abbreviated | narrow | wide) #REQUIRED >
+<!ATTLIST monthWidth alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST monthWidth draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST monthWidth standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST monthWidth references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST monthWidth validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT month ( #PCDATA | cp )* >
+<!ATTLIST month type (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13) #REQUIRED >
+<!ATTLIST month yeartype (standard | leap) #IMPLIED >
+<!ATTLIST month alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST month draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST month references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT monthNames ( alias | ( month*, special* ) ) >
+ <!--@DEPRECATED-->
+<!ATTLIST monthNames draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT monthAbbr ( alias | ( month*, special* ) ) >
+ <!--@DEPRECATED-->
+<!ATTLIST monthAbbr draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT monthPatterns ( alias | ( monthPatternContext*, special* ) ) >
+<!ATTLIST monthPatterns alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST monthPatterns draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST monthPatterns references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST monthPatterns validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT monthPatternContext ( alias | ( monthPatternWidth*, special* ) ) >
+<!ATTLIST monthPatternContext type (format | stand-alone | numeric) #REQUIRED >
+<!ATTLIST monthPatternContext alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST monthPatternContext draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST monthPatternContext references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST monthPatternContext validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT monthPatternWidth ( alias | ( monthPattern*, special* ) ) >
+<!ATTLIST monthPatternWidth type (abbreviated | narrow | wide | all) #REQUIRED >
+<!ATTLIST monthPatternWidth alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST monthPatternWidth draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST monthPatternWidth references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST monthPatternWidth validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT monthPattern ( #PCDATA ) >
+<!ATTLIST monthPattern type (leap | standardAfterLeap | combined) #REQUIRED >
+<!ATTLIST monthPattern alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST monthPattern draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST monthPattern references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT days ( alias | ( default*, dayContext*, special* ) ) >
+<!ATTLIST days alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST days draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST days standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST days references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST days validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT dayContext ( alias | ( default*, dayWidth*, special* ) ) >
+<!ATTLIST dayContext type (format | stand-alone) #REQUIRED >
+<!ATTLIST dayContext alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST dayContext draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dayContext standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dayContext references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST dayContext validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT dayWidth ( alias | ( day*, special* ) ) >
+<!ATTLIST dayWidth type (abbreviated | narrow | short | wide) #REQUIRED >
+<!ATTLIST dayWidth alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST dayWidth draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dayWidth standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dayWidth references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST dayWidth validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT day ( #PCDATA ) >
+<!ATTLIST day type (sun | mon | tue | wed | thu | fri | sat) #REQUIRED >
+<!ATTLIST day alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST day draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST day references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT dayNames ( alias | ( day*, special* ) ) >
+ <!--@DEPRECATED-->
+<!ATTLIST dayNames draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT dayAbbr ( alias | ( day*, special* ) ) >
+ <!--@DEPRECATED-->
+<!ATTLIST dayAbbr draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT quarters ( alias | ( default*, quarterContext*, special* ) ) >
+<!ATTLIST quarters alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST quarters draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST quarters references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST quarters validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT quarterContext ( alias | ( default*, quarterWidth*, special* ) ) >
+<!ATTLIST quarterContext type (format | stand-alone) #REQUIRED >
+<!ATTLIST quarterContext alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST quarterContext draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST quarterContext references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST quarterContext validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT quarterWidth ( alias | ( quarter*, special* ) ) >
+<!ATTLIST quarterWidth type (abbreviated | narrow | wide) #REQUIRED >
+<!ATTLIST quarterWidth alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST quarterWidth draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST quarterWidth references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST quarterWidth validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT quarter ( #PCDATA ) >
+<!ATTLIST quarter type (1 | 2 | 3 | 4) #REQUIRED >
+<!ATTLIST quarter alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST quarter draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST quarter references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT week ( alias | ( minDays*, firstDay*, weekendStart*, weekendEnd*, special* ) ) >
+ <!-- use supplemental weekData -->
+ <!--@DEPRECATED-->
+<!ATTLIST week alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST week draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST week standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST week references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST week validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT minDays ( special* ) >
+ <!--@DEPRECATED-->
+<!ATTLIST minDays count (1 | 2 | 3 | 4 | 5 | 6 | 7) #REQUIRED >
+ <!--@DEPRECATED-->
+<!ATTLIST minDays alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST minDays draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST minDays references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT firstDay ( special* ) >
+ <!-- use supplemental data -->
+ <!--@DEPRECATED-->
+<!ATTLIST firstDay day (sun | mon | tue | wed | thu | fri | sat) #REQUIRED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST firstDay alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST firstDay draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST firstDay references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT weekendStart ( special* ) >
+ <!-- use supplemental data -->
+ <!--@DEPRECATED-->
+<!ATTLIST weekendStart day (sun | mon | tue | wed | thu | fri | sat) #REQUIRED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST weekendStart time CDATA "00:00" >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST weekendStart alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST weekendStart draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST weekendStart references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT weekendEnd ( special* ) >
+ <!-- use supplemental data -->
+ <!--@DEPRECATED-->
+<!ATTLIST weekendEnd day (sun | mon | tue | wed | thu | fri | sat) #REQUIRED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST weekendEnd time CDATA "24:00" >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST weekendEnd alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST weekendEnd draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST weekendEnd references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT am ( #PCDATA ) >
+ <!-- use dayPeriods -->
+ <!--@DEPRECATED-->
+<!ATTLIST am alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST am draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST am references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST am validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT pm ( #PCDATA ) >
+ <!-- use dayPeriods -->
+ <!--@DEPRECATED-->
+<!ATTLIST pm alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST pm draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST pm references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST pm validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT dayPeriods ( alias | ( dayPeriodContext*, special* ) ) >
+<!ATTLIST dayPeriods draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dayPeriods references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT dayPeriodContext ( alias | ( dayPeriodWidth*, special* ) ) >
+<!ATTLIST dayPeriodContext type NMTOKEN #REQUIRED >
+ <!--@MATCH:literal/format, stand-alone-->
+<!ATTLIST dayPeriodContext draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dayPeriodContext references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT dayPeriodWidth ( alias | ( dayPeriod*, special* ) ) >
+<!ATTLIST dayPeriodWidth type (abbreviated | narrow | wide) #REQUIRED >
+<!ATTLIST dayPeriodWidth draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dayPeriodWidth references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT dayPeriod ( #PCDATA ) >
+<!ATTLIST dayPeriod type NMTOKEN #REQUIRED >
+ <!--@MATCH:literal/afternoon1, afternoon2, am, evening1, evening2, midnight, morning1, morning2, night1, night2, noon, pm-->
+<!ATTLIST dayPeriod alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST dayPeriod draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST dayPeriod references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT eras ( alias | ( eraNames?, eraAbbr?, eraNarrow?, special* ) ) >
+<!ATTLIST eras alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST eras draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST eras standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST eras references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST eras validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT eraNames ( alias | ( era*, special* ) ) >
+<!ATTLIST eraNames alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST eraNames draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST eraNames references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST eraNames validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT era ( #PCDATA ) >
+<!ATTLIST era type NMTOKEN #REQUIRED >
+ <!--@MATCH:range/0~237-->
+<!ATTLIST era alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST era draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST era references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT eraAbbr ( alias | ( era*, special* ) ) >
+<!ATTLIST eraAbbr alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST eraAbbr draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST eraAbbr references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST eraAbbr validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT eraNarrow ( alias | ( era*, special* ) ) >
+<!ATTLIST eraNarrow alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST eraNarrow draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST eraNarrow references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST eraNarrow validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT cyclicNameSets ( alias | ( cyclicNameSet*, special* ) ) >
+<!ATTLIST cyclicNameSets alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST cyclicNameSets draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST cyclicNameSets references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST cyclicNameSets validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT cyclicNameSet ( alias | ( cyclicNameContext*, special* ) ) >
+<!ATTLIST cyclicNameSet type (years | months | days | dayParts | zodiacs | solarTerms) #REQUIRED >
+<!ATTLIST cyclicNameSet alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST cyclicNameSet draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST cyclicNameSet references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST cyclicNameSet validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT cyclicNameContext ( alias | ( cyclicNameWidth*, special* ) ) >
+<!ATTLIST cyclicNameContext type (format | stand-alone) #REQUIRED >
+<!ATTLIST cyclicNameContext alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST cyclicNameContext draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST cyclicNameContext references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST cyclicNameContext validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT cyclicNameWidth ( alias | ( cyclicName*, special* ) ) >
+<!ATTLIST cyclicNameWidth type (abbreviated | narrow | wide) #REQUIRED >
+<!ATTLIST cyclicNameWidth alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST cyclicNameWidth draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST cyclicNameWidth references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST cyclicNameWidth validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT cyclicName ( #PCDATA ) >
+<!ATTLIST cyclicName type NMTOKEN #REQUIRED >
+ <!--@MATCH:range/1~60-->
+<!ATTLIST cyclicName alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST cyclicName draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST cyclicName references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT dateFormats ( alias | ( default*, dateFormatLength*, special* ) ) >
+<!ATTLIST dateFormats draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dateFormats validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT dateFormatLength ( alias | ( default*, dateFormat*, special* ) ) >
+<!ATTLIST dateFormatLength type (full | long | medium | short) #REQUIRED >
+<!ATTLIST dateFormatLength alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST dateFormatLength draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dateFormatLength standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dateFormatLength references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST dateFormatLength validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT dateFormat ( alias | ( pattern*, datetimeSkeleton*, displayName*, special* ) ) >
+<!ATTLIST dateFormat type NMTOKEN "standard" >
+ <!--@MATCH:literal/standard-->
+<!ATTLIST dateFormat alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST dateFormat draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dateFormat standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dateFormat references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST dateFormat validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT pattern ( #PCDATA ) >
+<!ATTLIST pattern type NMTOKEN "standard" >
+ <!--@MATCH:literal/1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, approximately, atLeast, atMost, range, standard-->
+<!ATTLIST pattern numbers CDATA #IMPLIED >
+ <!-- TODO: generalize this to be any (M=|d=)?<numberSystem> -->
+ <!--@MATCH:literal/M=romanlow, d=hanidays, hanidec, hebr, y=jpanyear-->
+ <!--@VALUE-->
+<!ATTLIST pattern count (0 | 1 | zero | one | two | few | many | other) #IMPLIED >
+ <!-- Only used for decimalFormats type="1000..." -->
+<!ATTLIST pattern alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST pattern draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST pattern references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT datetimeSkeleton ( #PCDATA ) >
+<!ATTLIST datetimeSkeleton numbers CDATA #IMPLIED >
+ <!-- TODO: generalize this to be any (M=|d=)?<numberSystem> -->
+ <!--@MATCH:literal/M=romanlow, d=hanidays, hanidec, hebr, y=jpanyear-->
+ <!--@VALUE-->
+<!ATTLIST datetimeSkeleton alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST datetimeSkeleton draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST datetimeSkeleton references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT displayName ( #PCDATA ) >
+<!ATTLIST displayName count (0 | 1 | zero | one | two | few | many | other) #IMPLIED >
+ <!-- only for currencies -->
+<!ATTLIST displayName alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST displayName draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST displayName references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT timeFormats ( alias | ( default*, timeFormatLength*, special* ) ) >
+<!ATTLIST timeFormats draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST timeFormats validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT timeFormatLength ( alias | ( default*, timeFormat*, special* ) ) >
+<!ATTLIST timeFormatLength type (full | long | medium | short) #REQUIRED >
+<!ATTLIST timeFormatLength alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST timeFormatLength draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST timeFormatLength standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST timeFormatLength references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST timeFormatLength validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT timeFormat ( alias | ( pattern*, datetimeSkeleton*, displayName*, special* ) ) >
+<!ATTLIST timeFormat type NMTOKEN "standard" >
+ <!--@MATCH:literal/standard-->
+<!ATTLIST timeFormat alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST timeFormat draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST timeFormat standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST timeFormat references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST timeFormat validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT dateTimeFormats ( alias | ( default*, dateTimeFormatLength*, availableFormats*, appendItems*, intervalFormats*, special* ) ) >
+<!ATTLIST dateTimeFormats draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dateTimeFormats validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT dateTimeFormatLength ( alias | ( default*, dateTimeFormat*, special* ) ) >
+<!ATTLIST dateTimeFormatLength type (full | long | medium | short) #IMPLIED >
+<!ATTLIST dateTimeFormatLength alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST dateTimeFormatLength draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dateTimeFormatLength standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dateTimeFormatLength references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST dateTimeFormatLength validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT dateTimeFormat ( alias | ( pattern*, displayName*, special* ) ) >
+<!ATTLIST dateTimeFormat type NMTOKEN "standard" >
+ <!--@MATCH:literal/standard-->
+<!ATTLIST dateTimeFormat alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST dateTimeFormat draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dateTimeFormat standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST dateTimeFormat references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST dateTimeFormat validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT availableFormats ( alias | ( dateFormatItem*, special* ) ) >
+<!ATTLIST availableFormats alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST availableFormats draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST availableFormats references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST availableFormats validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT dateFormatItem ( #PCDATA ) >
+<!ATTLIST dateFormatItem id CDATA #REQUIRED >
+ <!-- TODO rationalize this list -->
+ <!--@MATCH:literal/Bh, Bhm, Bhms, E, EBhm, EBhms, EEEEd, EHm, EHms, Ed, Ehm, Ehms, Gy, GyM, GyMEEEEd, GyMMM, GyMMMEEEEd, GyMMMEd, GyMMMM, GyMMMMEd, GyMMMMd, GyMMMd, GyMd, H, HHmm, HHmmZ, HHmmss, Hm, HmZ, Hmm, Hms, Hmsv, Hmsvvvv, Hmv, Hmvvvv, M, MEEEEd, MEd, MMM, MMMEEEEd, MMMEd, MMMM, MMMMEEEEd, MMMMEd, MMMMW, MMMMd, MMMMdd, MMMd, MMMdd, MMd, MMdd, Md, Mdd, UM, UMMM, UMMMd, UMd, d, h, hhmm, hhmmss, hm, hms, hmsv, hmsvvvv, hmv, hmvvvv, mmss, ms, y, yM, yMEEEEd, yMEd, yMM, yMMM, yMMMEEEEd, yMMMEd, yMMMM, yMMMMEEEEd, yMMMMEd, yMMMMccccd, yMMMMd, yMMMd, yMMdd, yMd, yQ, yQQQ, yQQQQ, yw, yyyy, yyyyM, yyyyMEEEEd, yyyyMEd, yyyyMM, yyyyMMM, yyyyMMMEEEEd, yyyyMMMEd, yyyyMMMM, yyyyMMMMEd, yyyyMMMMccccd, yyyyMMMMd, yyyyMMMd, yyyyMMdd, yyyyMd, yyyyQQQ, yyyyQQQQ-->
+<!ATTLIST dateFormatItem count (zero | one | two | few | many | other) #IMPLIED >
+<!ATTLIST dateFormatItem alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST dateFormatItem draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST dateFormatItem references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT appendItems ( alias | ( appendItem*, special* ) ) >
+<!ATTLIST appendItems alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST appendItems draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST appendItems references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST appendItems validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT appendItem ( #PCDATA ) >
+<!ATTLIST appendItem request CDATA #REQUIRED >
+ <!--@MATCH:literal/Day, Day-Of-Week, Era, Hour, Minute, Month, Quarter, Second, Timezone, Week, Year-->
+<!ATTLIST appendItem alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST appendItem draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST appendItem references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT intervalFormats ( alias | ( intervalFormatFallback*, intervalFormatItem*, special* ) ) >
+<!ATTLIST intervalFormats alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST intervalFormats draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST intervalFormats references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST intervalFormats validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT intervalFormatFallback ( #PCDATA ) >
+<!ATTLIST intervalFormatFallback alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST intervalFormatFallback draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST intervalFormatFallback references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST intervalFormatFallback validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT intervalFormatItem ( alias | ( greatestDifference*, special* ) ) >
+<!ATTLIST intervalFormatItem id NMTOKEN #REQUIRED >
+ <!-- TODO: check to see if this should be minimized -->
+ <!--@MATCH:literal/Bh, Bhm, Gy, GyM, GyMEd, GyMMM, GyMMMEd, GyMMMd, GyMd, H, Hm, Hmv, Hv, M, MEd, MMM, MMMEEEEd, MMMEd, MMMM, MMMMEd, MMMMd, MMMd, Md, d, h, hm, hmv, hv, y, yM, yMEd, yMMM, yMMMEEEEd, yMMMEd, yMMMM, yMMMMEEEEd, yMMMMEd, yMMMMd, yMMMd, yMd, GGGGGyM, GGGGGyMEd, GGGGGyMd, GyMMMM, GyMMMMEd, GyMMMMd-->
+<!ATTLIST intervalFormatItem alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST intervalFormatItem draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST intervalFormatItem references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST intervalFormatItem validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT greatestDifference ( #PCDATA ) >
+<!ATTLIST greatestDifference id NMTOKEN #REQUIRED >
+ <!--@MATCH:literal/B, G, H, M, a, d, h, m, y-->
+<!ATTLIST greatestDifference alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST greatestDifference draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST greatestDifference references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST greatestDifference validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT fields ( alias | ( field*, special* ) ) >
+<!ATTLIST fields alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST fields draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST fields standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST fields references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST fields validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT field ( alias | ( displayName*, relative*, relativeTime*, relativePeriod*, special* ) ) >
+<!ATTLIST field type (era | era-short | era-narrow | year | year-short | year-narrow | quarter | quarter-short | quarter-narrow | month | month-short | month-narrow | week | week-short | week-narrow | weekOfMonth | weekOfMonth-short | weekOfMonth-narrow | day | day-short | day-narrow | dayOfYear | dayOfYear-short | dayOfYear-narrow | weekday | weekday-short | weekday-narrow | weekdayOfMonth | weekdayOfMonth-short | weekdayOfMonth-narrow | sun | sun-short | sun-narrow | mon | mon-short | mon-narrow | tue | tue-short | tue-narrow | wed | wed-short | wed-narrow | thu | thu-short | thu-narrow | fri | fri-short | fri-narrow | sat | sat-short | sat-narrow | dayperiod | dayperiod-short | dayperiod-narrow | hour | hour-short | hour-narrow | minute | minute-short | minute-narrow | second | second-short | second-narrow | zone | zone-short | zone-narrow) #REQUIRED >
+<!ATTLIST field alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST field draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST field standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST field references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST field validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT relative ( #PCDATA ) >
+<!ATTLIST relative type NMTOKEN #REQUIRED >
+ <!-- TODO: determine whether to allow 3 -->
+ <!--@MATCH:range/-2~3-->
+<!ATTLIST relative alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST relative draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST relative references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST relative validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT relativeTime ( alias | ( relativeTimePattern*, special* ) ) >
+<!ATTLIST relativeTime type NMTOKEN #REQUIRED >
+ <!--@MATCH:literal/future, past-->
+<!ATTLIST relativeTime alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST relativeTime draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST relativeTime references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST relativeTime validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT relativeTimePattern ( #PCDATA ) >
+<!ATTLIST relativeTimePattern count (zero | one | two | few | many | other) #REQUIRED >
+<!ATTLIST relativeTimePattern alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST relativeTimePattern draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST relativeTimePattern references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST relativeTimePattern validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT relativePeriod ( #PCDATA ) >
+<!ATTLIST relativePeriod alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST relativePeriod draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT timeZoneNames ( alias | ( hourFormat*, hoursFormat*, gmtFormat*, gmtZeroFormat*, regionFormat*, fallbackFormat*, fallbackRegionFormat*, abbreviationFallback*, preferenceOrdering*, singleCountries*, default*, zone*, metazone*, special* ) ) >
+<!ATTLIST timeZoneNames draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST timeZoneNames validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT hourFormat ( #PCDATA ) >
+<!ATTLIST hourFormat alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST hourFormat draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST hourFormat references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT hoursFormat ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST hoursFormat alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST hoursFormat draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST hoursFormat references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT gmtFormat ( #PCDATA ) >
+<!ATTLIST gmtFormat alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST gmtFormat draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST gmtFormat references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT gmtZeroFormat ( #PCDATA ) >
+<!ATTLIST gmtZeroFormat alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST gmtZeroFormat draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST gmtZeroFormat references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT regionFormat ( #PCDATA ) >
+<!ATTLIST regionFormat type (standard | daylight) #IMPLIED >
+<!ATTLIST regionFormat alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST regionFormat draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST regionFormat references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT fallbackFormat ( #PCDATA ) >
+<!ATTLIST fallbackFormat alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST fallbackFormat draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST fallbackFormat references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT fallbackRegionFormat ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST fallbackRegionFormat alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST fallbackRegionFormat draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST fallbackRegionFormat references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT abbreviationFallback EMPTY >
+ <!--@DEPRECATED-->
+<!ATTLIST abbreviationFallback type (GMT | standard) #IMPLIED >
+ <!-- use choice instead -->
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST abbreviationFallback choice (GMT | standard) #IMPLIED >
+ <!-- really required, but needs to be optional to support type also -->
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST abbreviationFallback alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST abbreviationFallback draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST abbreviationFallback references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT preferenceOrdering EMPTY >
+ <!-- use metazones instead -->
+ <!--@DEPRECATED-->
+<!ATTLIST preferenceOrdering type CDATA #IMPLIED >
+ <!-- use choice instead -->
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST preferenceOrdering choice CDATA #IMPLIED >
+ <!-- really required, but needs to be optional to support type also -->
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST preferenceOrdering alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST preferenceOrdering draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST preferenceOrdering references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT singleCountries EMPTY >
+ <!--@DEPRECATED-->
+<!ATTLIST singleCountries list CDATA #REQUIRED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST singleCountries alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST singleCountries draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST singleCountries references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT zone ( alias | ( long*, short*, commonlyUsed*, exemplarCity*, special* ) ) >
+<!ATTLIST zone type CDATA #REQUIRED >
+ <!--@MATCH:bcp47/tz-->
+<!ATTLIST zone alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST zone draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST zone standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST zone references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST zone validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT long ( alias | ( generic*, standard*, daylight*, special* ) ) >
+<!ATTLIST long alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST long draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST long references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST long validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT generic ( #PCDATA ) >
+<!ATTLIST generic alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST generic draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST generic references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT standard ( #PCDATA ) >
+<!ATTLIST standard alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST standard draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST standard references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT daylight ( #PCDATA ) >
+<!ATTLIST daylight alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST daylight draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST daylight references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT short ( alias | ( generic*, standard*, daylight*, special* ) ) >
+<!ATTLIST short alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST short draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST short references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST short validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT commonlyUsed ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST commonlyUsed used (true | false) #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST commonlyUsed alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST commonlyUsed draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST commonlyUsed references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT exemplarCity ( #PCDATA ) >
+<!ATTLIST exemplarCity alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/formal, secondary-->
+<!ATTLIST exemplarCity draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST exemplarCity references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT metazone ( alias | ( long*, short*, commonlyUsed*, special* ) ) >
+<!ATTLIST metazone type CDATA #REQUIRED >
+ <!--@MATCH:metazone-->
+<!ATTLIST metazone alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST metazone draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST metazone standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST metazone references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST metazone validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!-- ######################################################### -->
+
+<!ELEMENT numbers ( alias | ( defaultNumberingSystem*, otherNumberingSystems*, minimumGroupingDigits*, symbols*, decimalFormats*, scientificFormats*, percentFormats*, currencyFormats*, currencies?, miscPatterns*, minimalPairs*, special* ) ) >
+<!ATTLIST numbers alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST numbers draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST numbers standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST numbers references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST numbers validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT defaultNumberingSystem ( #PCDATA ) >
+<!ATTLIST defaultNumberingSystem alt NMTOKENS #IMPLIED >
+ <!--@MATCH:bcp47/nu-->
+<!ATTLIST defaultNumberingSystem draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST defaultNumberingSystem references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT otherNumberingSystems ( alias | ( native*, traditional*, finance*, special* ) ) >
+<!ATTLIST otherNumberingSystems alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST otherNumberingSystems draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT native ( #PCDATA ) >
+<!ATTLIST native alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST native draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+
+<!ELEMENT traditional ( #PCDATA ) >
+<!ATTLIST traditional alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST traditional draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+
+<!ELEMENT finance ( #PCDATA ) >
+<!ATTLIST finance alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST finance draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+
+<!ELEMENT minimumGroupingDigits ( #PCDATA ) >
+<!ATTLIST minimumGroupingDigits alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST minimumGroupingDigits draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST minimumGroupingDigits references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT symbols ( alias | ( decimal*, group*, list*, percentSign*, nativeZeroDigit*, patternDigit*, plusSign*, minusSign*, approximatelySign*, exponential*, superscriptingExponent*, perMille*, infinity*, nan*, currencyDecimal*, currencyGroup*, timeSeparator*, special* ) ) >
+<!ATTLIST symbols alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST symbols draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST symbols standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST symbols references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST symbols validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST symbols numberSystem CDATA #IMPLIED >
+ <!--@MATCH:bcp47/nu-->
+
+<!ELEMENT decimal ( #PCDATA ) >
+<!ATTLIST decimal alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST decimal draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST decimal references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST decimal numberSystem CDATA #IMPLIED >
+ <!--@DEPRECATED-->
+
+<!ELEMENT group ( #PCDATA ) >
+<!ATTLIST group alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST group draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST group references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST group numberSystem CDATA #IMPLIED >
+ <!--@DEPRECATED-->
+
+<!ELEMENT list ( #PCDATA ) >
+<!ATTLIST list alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST list draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST list references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST list numberSystem CDATA #IMPLIED >
+ <!--@DEPRECATED-->
+
+<!ELEMENT percentSign ( #PCDATA ) >
+<!ATTLIST percentSign alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST percentSign draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST percentSign references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST percentSign numberSystem CDATA #IMPLIED >
+ <!--@DEPRECATED-->
+
+<!ELEMENT nativeZeroDigit ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST nativeZeroDigit alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST nativeZeroDigit draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST nativeZeroDigit references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST nativeZeroDigit numberSystem CDATA #IMPLIED >
+ <!--@DEPRECATED-->
+
+<!ELEMENT patternDigit ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST patternDigit alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST patternDigit draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST patternDigit references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST patternDigit numberSystem CDATA #IMPLIED >
+ <!--@DEPRECATED-->
+
+<!ELEMENT plusSign ( #PCDATA ) >
+<!ATTLIST plusSign alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST plusSign draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST plusSign references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST plusSign numberSystem CDATA #IMPLIED >
+ <!--@DEPRECATED-->
+
+<!ELEMENT minusSign ( #PCDATA ) >
+<!ATTLIST minusSign alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST minusSign draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST minusSign references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST minusSign numberSystem CDATA #IMPLIED >
+ <!--@DEPRECATED-->
+
+<!ELEMENT approximatelySign ( #PCDATA ) >
+<!ATTLIST approximatelySign alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST approximatelySign draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST approximatelySign references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT exponential ( #PCDATA ) >
+<!ATTLIST exponential alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST exponential draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST exponential references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST exponential numberSystem CDATA #IMPLIED >
+ <!--@DEPRECATED-->
+
+<!ELEMENT superscriptingExponent ( #PCDATA ) >
+<!ATTLIST superscriptingExponent alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST superscriptingExponent draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST superscriptingExponent references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT perMille ( #PCDATA ) >
+<!ATTLIST perMille alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST perMille draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST perMille references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST perMille numberSystem CDATA #IMPLIED >
+ <!--@DEPRECATED-->
+
+<!ELEMENT infinity ( #PCDATA ) >
+<!ATTLIST infinity alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST infinity draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST infinity references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST infinity numberSystem CDATA #IMPLIED >
+ <!--@DEPRECATED-->
+
+<!ELEMENT nan ( #PCDATA ) >
+<!ATTLIST nan alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST nan draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST nan references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST nan numberSystem CDATA #IMPLIED >
+ <!--@DEPRECATED-->
+
+<!ELEMENT currencyDecimal ( #PCDATA ) >
+<!ATTLIST currencyDecimal alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST currencyDecimal draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST currencyDecimal references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST currencyDecimal numberSystem CDATA #IMPLIED >
+ <!--@DEPRECATED-->
+
+<!ELEMENT currencyGroup ( #PCDATA ) >
+<!ATTLIST currencyGroup alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST currencyGroup draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST currencyGroup references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST currencyGroup numberSystem CDATA #IMPLIED >
+ <!--@DEPRECATED-->
+
+<!ELEMENT timeSeparator ( #PCDATA ) >
+<!ATTLIST timeSeparator alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST timeSeparator draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST timeSeparator references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT decimalFormats ( alias | ( default*, decimalFormatLength*, special* ) ) >
+<!ATTLIST decimalFormats draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST decimalFormats validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST decimalFormats numberSystem CDATA #IMPLIED >
+ <!--@MATCH:bcp47/nu-->
+
+<!ELEMENT decimalFormatLength ( alias | ( default*, decimalFormat*, special* ) ) >
+<!ATTLIST decimalFormatLength type (full | long | medium | short) #IMPLIED >
+<!ATTLIST decimalFormatLength alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST decimalFormatLength draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST decimalFormatLength standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST decimalFormatLength references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST decimalFormatLength validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT decimalFormat ( alias | ( pattern*, special* ) ) >
+<!ATTLIST decimalFormat type NMTOKEN "standard" >
+ <!--@MATCH:literal/standard-->
+<!ATTLIST decimalFormat alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST decimalFormat draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST decimalFormat standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST decimalFormat references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST decimalFormat validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT scientificFormats ( alias | ( default*, scientificFormatLength*, special* ) ) >
+<!ATTLIST scientificFormats draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST scientificFormats validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST scientificFormats numberSystem CDATA #IMPLIED >
+ <!--@MATCH:bcp47/nu-->
+
+<!ELEMENT scientificFormatLength ( alias | ( default*, scientificFormat*, special* ) ) >
+<!ATTLIST scientificFormatLength type (full | long | medium | short) #IMPLIED >
+<!ATTLIST scientificFormatLength alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST scientificFormatLength draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST scientificFormatLength standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST scientificFormatLength references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST scientificFormatLength validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT scientificFormat ( alias | ( pattern*, special* ) ) >
+<!ATTLIST scientificFormat type NMTOKEN "standard" >
+ <!--@MATCH:literal/standard-->
+<!ATTLIST scientificFormat alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST scientificFormat draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST scientificFormat standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST scientificFormat references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST scientificFormat validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT percentFormats ( alias | ( default*, percentFormatLength*, special* ) ) >
+<!ATTLIST percentFormats draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST percentFormats validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST percentFormats numberSystem CDATA #IMPLIED >
+ <!--@MATCH:bcp47/nu-->
+
+<!ELEMENT percentFormatLength ( alias | ( default*, percentFormat*, special* ) ) >
+<!ATTLIST percentFormatLength type (full | long | medium | short) #IMPLIED >
+<!ATTLIST percentFormatLength alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST percentFormatLength draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST percentFormatLength standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST percentFormatLength references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST percentFormatLength validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT percentFormat ( alias | ( pattern*, special* ) ) >
+<!ATTLIST percentFormat type NMTOKEN "standard" >
+ <!--@MATCH:literal/standard-->
+<!ATTLIST percentFormat alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST percentFormat draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST percentFormat standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST percentFormat references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST percentFormat validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT currencyFormats ( alias | ( default*, currencySpacing*, currencyFormatLength*, unitPattern*, special* ) ) >
+<!ATTLIST currencyFormats draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST currencyFormats validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST currencyFormats numberSystem CDATA #IMPLIED >
+ <!--@MATCH:bcp47/nu-->
+
+<!ELEMENT currencySpacing ( alias | ( beforeCurrency*, afterCurrency*, special* ) ) >
+
+<!ELEMENT beforeCurrency ( alias | ( currencyMatch*, surroundingMatch*, insertBetween*, special* ) ) >
+
+<!ELEMENT currencyMatch ( #PCDATA ) >
+<!ATTLIST currencyMatch alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST currencyMatch draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST currencyMatch references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT surroundingMatch ( #PCDATA ) >
+<!ATTLIST surroundingMatch alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST surroundingMatch draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST surroundingMatch references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT insertBetween ( #PCDATA ) >
+<!ATTLIST insertBetween alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST insertBetween draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST insertBetween references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT afterCurrency ( alias | ( currencyMatch*, surroundingMatch*, insertBetween*, special* ) ) >
+
+<!ELEMENT currencyFormatLength ( alias | ( default*, currencyFormat*, special* ) ) >
+<!ATTLIST currencyFormatLength type (full | long | medium | short) #IMPLIED >
+<!ATTLIST currencyFormatLength alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST currencyFormatLength draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST currencyFormatLength standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST currencyFormatLength references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST currencyFormatLength validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT currencyFormat ( alias | ( pattern*, special* ) ) >
+<!ATTLIST currencyFormat type NMTOKEN "standard" >
+ <!--@MATCH:literal/accounting, standard-->
+<!ATTLIST currencyFormat alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST currencyFormat draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST currencyFormat standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST currencyFormat references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST currencyFormat validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT unitPattern ( #PCDATA ) >
+<!ATTLIST unitPattern count (0 | 1 | zero | one | two | few | many | other) #REQUIRED >
+<!ATTLIST unitPattern case NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/ablative, accusative, comitative, dative, ergative, genitive, instrumental, locative, locativecopulative, nominative, oblique, prepositional, sociative, vocative, elative, illative, partitive, terminative, translative-->
+<!ATTLIST unitPattern alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST unitPattern draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST unitPattern references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST unitPattern validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT currencies ( alias | ( default?, currency*, special* ) ) >
+<!ATTLIST currencies draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST currencies validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT currency ( alias | ( ( ( pattern+, displayName*, symbol* ) | ( displayName+, symbol*, pattern* ) | ( symbol+, pattern* ) )?, decimal*, group*, special* ) ) >
+
+<!-- # warning: pattern appears twice in the above. The first is for consistency with all other cases of
+ pattern + displayName; the second is for backwards compatibility -->
+<!ATTLIST currency type NMTOKEN "standard" >
+ <!--@MATCH:validity/currency-->
+<!ATTLIST currency alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST currency draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST currency references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST currency validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT symbol ( #PCDATA ) >
+<!ATTLIST symbol choice (true | false) #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST symbol alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/formal, narrow, variant-->
+<!ATTLIST symbol draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST symbol references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT miscPatterns ( alias | ( default*, pattern*, special* ) ) >
+<!ATTLIST miscPatterns draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST miscPatterns numberSystem CDATA #IMPLIED >
+ <!--@MATCH:bcp47/nu-->
+
+<!ELEMENT minimalPairs ( alias | ( pluralMinimalPairs*, ordinalMinimalPairs*, caseMinimalPairs*, genderMinimalPairs*, special* ) ) >
+<!ATTLIST minimalPairs alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST minimalPairs draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT pluralMinimalPairs ( #PCDATA ) >
+<!ATTLIST pluralMinimalPairs count NMTOKEN #REQUIRED >
+ <!--@MATCH:literal/few, many, one, other, two, zero-->
+<!ATTLIST pluralMinimalPairs alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST pluralMinimalPairs draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT ordinalMinimalPairs ( #PCDATA ) >
+<!ATTLIST ordinalMinimalPairs ordinal NMTOKEN #REQUIRED >
+ <!--@MATCH:literal/few, many, one, other, two, zero-->
+<!ATTLIST ordinalMinimalPairs alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST ordinalMinimalPairs draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT caseMinimalPairs ( #PCDATA ) >
+<!ATTLIST caseMinimalPairs case NMTOKEN #REQUIRED >
+ <!--@MATCH:literal/ablative, accusative, comitative, dative, ergative, genitive, instrumental, locative, locativecopulative, nominative, oblique, prepositional, sociative, vocative, elative, illative, partitive, terminative, translative-->
+<!ATTLIST caseMinimalPairs alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST caseMinimalPairs draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT genderMinimalPairs ( #PCDATA ) >
+<!ATTLIST genderMinimalPairs gender NMTOKEN #REQUIRED >
+ <!--@MATCH:literal/animate, common, feminine, inanimate, masculine, neuter, personal-->
+<!ATTLIST genderMinimalPairs alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST genderMinimalPairs draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!-- ######################################################### -->
+
+<!ELEMENT units ( alias | ( unit*, unitLength*, durationUnit*, special* ) ) >
+<!ATTLIST units alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST units draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST units references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST units validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT unit ( alias | ( gender*, displayName*, unitPattern*, perUnitPattern*, special* ) ) >
+<!ATTLIST unit type NMTOKEN #REQUIRED >
+ <!--@MATCH:validity/unit-->
+<!ATTLIST unit alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST unit draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST unit references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST unit validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT gender ( #PCDATA ) >
+<!ATTLIST gender alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/animate, common, feminine, inanimate, masculine, neuter, personal-->
+<!ATTLIST gender draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT perUnitPattern ( #PCDATA ) >
+<!ATTLIST perUnitPattern alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST perUnitPattern draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST perUnitPattern references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT unitLength ( alias | ( compoundUnit*, unit*, coordinateUnit*, special* ) ) >
+<!ATTLIST unitLength type (long | short | narrow) #REQUIRED >
+<!ATTLIST unitLength alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST unitLength draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST unitLength references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST unitLength validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT compoundUnit ( alias | ( compoundUnitPattern1*, compoundUnitPattern*, unitPrefixPattern*, special* ) ) >
+<!ATTLIST compoundUnit type NMTOKEN #REQUIRED >
+ <!--@MATCH:or/regex/10p-?[0-9]{1,2}||regex/1024p[1-8]||literal/per, times, power2, power3-->
+<!ATTLIST compoundUnit alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST compoundUnit draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST compoundUnit references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST compoundUnit validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT compoundUnitPattern1 ( #PCDATA ) >
+<!ATTLIST compoundUnitPattern1 count (0 | 1 | zero | one | two | few | many | other) #IMPLIED >
+<!ATTLIST compoundUnitPattern1 gender NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/animate, common, feminine, inanimate, masculine, neuter, personal-->
+<!ATTLIST compoundUnitPattern1 case NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/ablative, accusative, comitative, dative, ergative, genitive, instrumental, locative, locativecopulative, nominative, oblique, prepositional, sociative, vocative-->
+<!ATTLIST compoundUnitPattern1 alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST compoundUnitPattern1 draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST compoundUnitPattern1 references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT compoundUnitPattern ( #PCDATA ) >
+<!ATTLIST compoundUnitPattern case NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/ablative, accusative, comitative, dative, ergative, genitive, instrumental, locative, locativecopulative, nominative, oblique, prepositional, sociative, vocative-->
+<!ATTLIST compoundUnitPattern alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST compoundUnitPattern draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST compoundUnitPattern references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST compoundUnitPattern validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT unitPrefixPattern ( #PCDATA ) >
+<!ATTLIST unitPrefixPattern alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST unitPrefixPattern draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST unitPrefixPattern references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT coordinateUnit ( alias | ( displayName*, coordinateUnitPattern*, special* ) ) >
+<!ATTLIST coordinateUnit alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST coordinateUnit draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT coordinateUnitPattern ( #PCDATA ) >
+<!ATTLIST coordinateUnitPattern type (north | east | south | west) #REQUIRED >
+<!ATTLIST coordinateUnitPattern alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST coordinateUnitPattern draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT durationUnit ( alias | ( durationUnitPattern*, special* ) ) >
+<!ATTLIST durationUnit type NMTOKEN #REQUIRED >
+ <!--@MATCH:literal/hm, hms, ms-->
+<!ATTLIST durationUnit alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST durationUnit draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST durationUnit references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT durationUnitPattern ( #PCDATA ) >
+<!ATTLIST durationUnitPattern alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST durationUnitPattern draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST durationUnitPattern references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST durationUnitPattern validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT listPatterns ( alias | ( listPattern*, special* ) ) >
+<!ATTLIST listPatterns alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST listPatterns draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST listPatterns references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST listPatterns validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT listPattern ( alias | ( listPatternPart*, special* ) ) >
+<!ATTLIST listPattern type NMTOKEN #IMPLIED >
+ <!--@MATCH:literal/or, or-narrow, or-short, standard-narrow, standard-short, unit, unit-narrow, unit-short-->
+<!ATTLIST listPattern alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST listPattern draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST listPattern references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST listPattern validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT listPatternPart ( #PCDATA ) >
+<!ATTLIST listPatternPart type (start | middle | end | 2 | 3) #REQUIRED >
+<!ATTLIST listPatternPart alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST listPatternPart draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST listPatternPart references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST listPatternPart validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!-- ######################################################### -->
+
+<!ELEMENT collations ( alias | ( defaultCollation?, default*, collation*, special* ) ) >
+<!ATTLIST collations version NMTOKEN #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST collations draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!-- should be DEPRECATED, but needs some cleanup first -->
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST collations validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT defaultCollation ( #PCDATA ) >
+<!ATTLIST defaultCollation alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST defaultCollation draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT collation ( alias | ( base?, import*, settings?, suppress_contractions?, optimize?, ( cr* | rules? ), special* ) ) >
+<!ATTLIST collation type NMTOKEN "standard" >
+ <!--@MATCH:or/bcp47/co||regex/private-.*||literal/digits-after-->
+<!ATTLIST collation visibility (internal | external) #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST collation alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/proposed, short, variant-->
+<!ATTLIST collation draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST collation standard CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST collation references CDATA #IMPLIED >
+ <!--@MATCH:any-->
+ <!--@METADATA-->
+<!ATTLIST collation validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT base ( alias | special ) >
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT import EMPTY >
+ <!-- deprecated, see CLDR ticket #8289 -->
+ <!--@DEPRECATED-->
+<!ATTLIST import source CDATA #REQUIRED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST import type CDATA #IMPLIED >
+ <!--@DEPRECATED-->
+<!ATTLIST import draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST import references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT settings ( special* ) >
+ <!-- deprecated, see CLDR ticket #8289 -->
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+<!ATTLIST settings strength (primary | secondary | tertiary | quaternary | identical) #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST settings alternate (non-ignorable | shifted) #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST settings backwards (on | off) #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST settings normalization (on | off) #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST settings caseLevel (on | off) #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST settings caseFirst (upper | lower | off) #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST settings hiraganaQuarternary (on | off) #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST settings hiraganaQuaternary (on | off) #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST settings maxVariable (space | punct | symbol | currency) #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST settings numeric (on | off) #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST settings private (true | false) #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST settings variableTop CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST settings reorder NMTOKENS #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT suppress_contractions ( #PCDATA | cp )* >
+ <!-- deprecated, see CLDR ticket #8289 -->
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT optimize ( #PCDATA | cp )* >
+ <!-- deprecated, see CLDR ticket #8289 -->
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT cr ( #PCDATA ) >
+<!ATTLIST cr alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST cr draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST cr references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!-- # Use the cr element instead, with ICU syntax. -->
+
+<!ELEMENT rules ( alias | ( ( reset | import ), ( reset | import | p | pc | s | sc | t | tc | q | qc | i | ic | x )* ) ) >
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT reset ( #PCDATA | cp | first_variable | last_variable | first_tertiary_ignorable | last_tertiary_ignorable | first_secondary_ignorable | last_secondary_ignorable | first_primary_ignorable | last_primary_ignorable | first_non_ignorable | last_non_ignorable | first_trailing | last_trailing )* >
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+<!ATTLIST reset before NMTOKEN #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT first_variable EMPTY >
+ <!--@DEPRECATED-->
+
+<!ELEMENT last_variable EMPTY >
+ <!--@DEPRECATED-->
+
+<!ELEMENT first_tertiary_ignorable EMPTY >
+ <!--@DEPRECATED-->
+
+<!ELEMENT last_tertiary_ignorable EMPTY >
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT first_secondary_ignorable EMPTY >
+ <!--@DEPRECATED-->
+
+<!ELEMENT last_secondary_ignorable EMPTY >
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT first_primary_ignorable EMPTY >
+ <!--@DEPRECATED-->
+
+<!ELEMENT last_primary_ignorable EMPTY >
+ <!--@DEPRECATED-->
+
+<!ELEMENT first_non_ignorable EMPTY >
+ <!--@DEPRECATED-->
+
+<!ELEMENT last_non_ignorable EMPTY >
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT first_trailing EMPTY >
+ <!--@DEPRECATED-->
+
+<!ELEMENT last_trailing EMPTY >
+ <!--@DEPRECATED-->
+
+<!ELEMENT p ( #PCDATA | cp | last_variable )* >
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT pc ( #PCDATA | cp | last_variable )* >
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT s ( #PCDATA | cp | last_variable )* >
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT sc ( #PCDATA | cp | last_variable )* >
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT t ( #PCDATA | cp | last_variable )* >
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT tc ( #PCDATA | cp | last_variable )* >
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT q ( #PCDATA | cp | last_variable )* >
+ <!--@DEPRECATED-->
+
+<!ELEMENT qc ( #PCDATA | cp | last_variable )* >
+ <!--@DEPRECATED-->
+
+<!ELEMENT i ( #PCDATA | cp | last_variable )* >
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT ic ( #PCDATA | cp | last_variable )* >
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT x ( context?, ( p | pc | s | sc | t | tc | q | qc | i | ic )*, extend? ) >
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT context ( #PCDATA | cp )* >
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT extend ( #PCDATA | cp )* >
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+
+<!-- ######################################################### -->
+
+<!ELEMENT posix ( alias | ( messages*, special* ) ) >
+<!ATTLIST posix draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST posix references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST posix validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT messages ( alias | ( yesstr*, nostr*, yesexpr*, noexpr*, special* ) ) >
+<!ATTLIST messages alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST messages draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST messages references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST messages validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT yesstr ( #PCDATA ) >
+<!ATTLIST yesstr alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST yesstr draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST yesstr references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT nostr ( #PCDATA ) >
+<!ATTLIST nostr alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST nostr draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST nostr references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT yesexpr ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST yesexpr alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST yesexpr draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST yesexpr references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT noexpr ( #PCDATA ) >
+ <!--@DEPRECATED-->
+<!ATTLIST noexpr alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST noexpr draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST noexpr references CDATA #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT characterLabels ( alias | ( characterLabelPattern*, characterLabel*, special* ) ) >
+
+<!ELEMENT characterLabelPattern ( #PCDATA ) >
+<!ATTLIST characterLabelPattern type NMTOKEN #REQUIRED >
+ <!--@MATCH:literal/all, category-list, compatibility, enclosed, extended, historic, miscellaneous, other, scripts, strokes, subscript, superscript-->
+<!ATTLIST characterLabelPattern count (0 | 1 | zero | one | two | few | many | other) #IMPLIED >
+ <!-- count only used for certain patterns" -->
+<!ATTLIST characterLabelPattern alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST characterLabelPattern draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT characterLabel ( #PCDATA ) >
+<!ATTLIST characterLabel type NMTOKEN #REQUIRED >
+ <!--@MATCH:literal/activities, african_scripts, american_scripts, animal, animals_nature, arrows, body, box_drawing, braille, building, bullets_stars, consonantal_jamo, currency_symbols, dash_connector, digits, dingbats, divination_symbols, downwards_arrows, downwards_upwards_arrows, east_asian_scripts, emoji, european_scripts, female, flag, flags, food_drink, format, format_whitespace, full_width_form_variant, geometric_shapes, half_width_form_variant, han_characters, han_radicals, hanja, hanzi_simplified, hanzi_traditional, heart, historic_scripts, ideographic_desc_characters, japanese_kana, kanbun, kanji, keycap, leftwards_arrows, leftwards_rightwards_arrows, letterlike_symbols, limited_use, male, math_symbols, middle_eastern_scripts, miscellaneous, modern_scripts, modifier, musical_symbols, nature, nonspacing, numbers, objects, other, paired, person, phonetic_alphabet, pictographs, place, plant, punctuation, rightwards_arrows, sign_standard_symbols, small_form_variant, smiley, smileys_people, south_asian_scripts, southeast_asian_scripts, spacing, sport, symbols, technical_symbols, tone_marks, travel, travel_places, upwards_arrows, variant_forms, vocalic_jamo, weather, western_asian_scripts, whitespace-->
+<!ATTLIST characterLabel alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST characterLabel draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT segmentations ( alias | ( segmentation*, special* ) ) >
+<!ATTLIST segmentations alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST segmentations draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST segmentations references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST segmentations validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT segmentation ( alias | ( variables?, segmentRules?, exceptions?, suppressions? ) | special* ) >
+<!ATTLIST segmentation type NMTOKEN #REQUIRED >
+ <!--@MATCH:literal/GraphemeClusterBreak, LineBreak, SentenceBreak, WordBreak-->
+<!ATTLIST segmentation alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST segmentation draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST segmentation references CDATA #IMPLIED >
+ <!--@METADATA-->
+<!ATTLIST segmentation validSubLocales CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT variables ( alias | ( variable*, special* ) ) >
+
+<!ELEMENT variable ( #PCDATA ) >
+ <!--@ORDERED-->
+<!ATTLIST variable id CDATA #REQUIRED >
+ <!--@MATCH:regex/\$[a-zA-Z0-9_]+-->
+<!ATTLIST variable alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST variable draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST variable references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT segmentRules ( alias | ( rule*, special* ) ) >
+
+<!ELEMENT rule ( #PCDATA ) >
+<!ATTLIST rule id NMTOKEN #REQUIRED >
+ <!--@MATCH:range/0.0~9999.0-->
+<!ATTLIST rule alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST rule draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+<!ATTLIST rule references CDATA #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT exceptions ( exception* ) >
+ <!-- use suppressions instead -->
+ <!--@DEPRECATED-->
+
+<!ELEMENT exception ( #PCDATA ) >
+ <!--@ORDERED-->
+ <!--@DEPRECATED-->
+<!ATTLIST exception draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT suppressions ( alias | ( suppression*, special* ) ) >
+<!ATTLIST suppressions type NMTOKEN "standard" >
+ <!--@MATCH:literal/standard-->
+<!ATTLIST suppressions draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT suppression ( #PCDATA ) >
+ <!--@ORDERED-->
+<!ATTLIST suppression alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST suppression draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT rbnf ( alias | ( rulesetGrouping*, special* ) ) >
+
+<!ELEMENT rulesetGrouping ( alias | ( ruleset*, special* ) ) >
+<!ATTLIST rulesetGrouping type NMTOKEN #REQUIRED >
+ <!--@MATCH:literal/NumberingSystemRules, OrdinalRules, SpelloutRules-->
+<!ATTLIST rulesetGrouping draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT ruleset ( alias | ( rbnfrule*, special* ) ) >
+ <!--@ORDERED-->
+<!ATTLIST ruleset type NMTOKEN #REQUIRED >
+ <!--@MATCH:regex/(ord-M-)?[\-0-9a-z]+-->
+<!ATTLIST ruleset access (public | private) #IMPLIED >
+ <!--@VALUE-->
+<!ATTLIST ruleset allowsParsing (true | false) #IMPLIED >
+ <!--@VALUE-->
+<!ATTLIST ruleset draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT rbnfrule ( #PCDATA ) >
+ <!--@ORDERED-->
+<!ATTLIST rbnfrule value CDATA #REQUIRED >
+ <!--@MATCH:or/range/-1.0E20~1.0E20||literal/-x, 0, 0.x, NaN, -Inf, Inf, x,x, x.x-->
+ <!--@VALUE-->
+<!ATTLIST rbnfrule radix CDATA #IMPLIED >
+ <!--@MATCH:literal/1,000, 100, 1000, 100000, 20-->
+ <!--@VALUE-->
+<!ATTLIST rbnfrule decexp CDATA #IMPLIED >
+ <!--@VALUE-->
+<!ATTLIST rbnfrule alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST rbnfrule draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED:true, false-->
+
+<!ELEMENT typographicNames ( alias | ( axisName*, styleName*, featureName*, special* ) ) >
+
+<!ELEMENT axisName ( #PCDATA ) >
+<!ATTLIST axisName type (ital | opsz | slnt | wdth | wght) #REQUIRED >
+<!ATTLIST axisName alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST axisName draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT styleName ( #PCDATA ) >
+<!ATTLIST styleName type (ital | opsz | slnt | wdth | wght) #REQUIRED >
+<!ATTLIST styleName subtype NMTOKEN #REQUIRED >
+ <!--@MATCH:literal/-12, 0, 1, 100, 112.5, 12, 125, 144, 150, 18, 200, 24, 300, 350, 380, 400, 50, 500, 600, 62.5, 700, 72, 75, 8, 800, 87.5, 900, 950-->
+<!ATTLIST styleName alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/compressed, demi, extended, heavy, narrow, short, ultra, ultrablack, ultraheavy, wide-->
+<!ATTLIST styleName draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT featureName ( #PCDATA ) >
+<!ATTLIST featureName type (afrc | cpsp | dlig | frac | lnum | onum | ordn | pnum | smcp | tnum | zero) #REQUIRED >
+<!ATTLIST featureName alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/short, variant-->
+<!ATTLIST featureName draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT annotations ( alias | ( annotation*, special* ) ) >
+
+<!ELEMENT annotation ( #PCDATA ) >
+<!ATTLIST annotation cp CDATA #REQUIRED >
+ <!--@MATCH:any-->
+<!ATTLIST annotation tts CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST annotation type (tts) #IMPLIED >
+<!ATTLIST annotation alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST annotation draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!-- ######################################################### -->
+<!-- # This element contains metadata for Survey Tool internal use (optimization, etc). -->
+
+<!ELEMENT metadata ( alias | ( casingData?, special* ) ) >
+ <!--@METADATA-->
+
+<!ELEMENT casingData ( alias | ( casingItem*, special* ) ) >
+ <!--@METADATA-->
+
+<!ELEMENT casingItem ( #PCDATA ) >
+<!ATTLIST casingItem type CDATA #REQUIRED >
+ <!--@MATCH:any-->
+<!ATTLIST casingItem override (true | false) #IMPLIED >
+ <!--@VALUE-->
+<!ATTLIST casingItem forceError (true | false) #IMPLIED >
+ <!--@VALUE-->
+<!ATTLIST casingItem alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+<!ATTLIST casingItem draft (approved | contributed | provisional | unconfirmed) #IMPLIED >
+ <!--@METADATA-->
+
+<!ELEMENT references ( reference* ) >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+
+<!ELEMENT reference ( #PCDATA ) >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST reference type NMTOKEN #REQUIRED >
+ <!--@DEPRECATED-->
+<!ATTLIST reference uri CDATA #IMPLIED >
+ <!--@VALUE-->
+ <!--@DEPRECATED-->
+<!ATTLIST reference alt NMTOKENS #IMPLIED >
+ <!--@MATCH:literal/variant-->
+ <!--@DEPRECATED-->
+<!ATTLIST reference draft (approved | contributed | provisional | unconfirmed | true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
+<!ATTLIST reference standard (true | false) #IMPLIED >
+ <!--@METADATA-->
+ <!--@DEPRECATED-->
diff --git a/Build/source/libs/icu/icu-src/source/data/dtd/cldr/common/dtd/ldmlICU.dtd b/Build/source/libs/icu/icu-src/source/data/dtd/cldr/common/dtd/ldmlICU.dtd
new file mode 100644
index 00000000000..e8abdedcbab
--- /dev/null
+++ b/Build/source/libs/icu/icu-src/source/data/dtd/cldr/common/dtd/ldmlICU.dtd
@@ -0,0 +1,125 @@
+<!--
+Copyright © 1991-2021 Unicode, Inc.
+For terms of use, see http://www.unicode.org/copyright.html
+SPDX-License-Identifier: Unicode-DFS-2016
+CLDR data files are interpreted according to the LDML specification (http://unicode.org/reports/tr35/)
+-->
+
+<!--
+NOTE: Unlike the other DTDs, this file is manually maintained.
+-->
+
+<!-- ######################################################### -->
+<!-- The alias, default, special and cp elements are already defined in ldml.dtd. Defining them here as well would break locale conversion. -->
+<!-- ######################################################### -->
+
+<!-- ICU Specific elements -->
+<!-- ######################################################### -->
+<!ATTLIST special xmlns:icu CDATA #IMPLIED>
+<!ATTLIST special icu:version CDATA #IMPLIED>
+
+<!ELEMENT icu:version EMPTY>
+<!ATTLIST icu:version icu:specialVersion CDATA #FIXED "41" >
+<!ATTLIST icu:version icu:requiredLDMLVersion CDATA #FIXED "41" >
+
+<!-- ICU Scripts -->
+
+<!ELEMENT icu:scripts (alias | icu:script* ) >
+<!ATTLIST icu:scripts draft ( true | false ) #IMPLIED >
+<!ATTLIST icu:scripts standard CDATA #IMPLIED >
+
+<!ELEMENT icu:script ( #PCDATA ) >
+<!ATTLIST icu:script type NMTOKEN #REQUIRED >
+<!ATTLIST icu:script draft ( true | false ) #IMPLIED >
+
+<!-- RBNF data -->
+<!ELEMENT icu:ruleBasedNumberFormats ( alias | (default?, icu:ruleBasedNumberFormat*)) >
+
+<!-- Either bare data or any number of cp -->
+<!ELEMENT icu:ruleBasedNumberFormat (#PCDATA | cp)* >
+<!ATTLIST icu:ruleBasedNumberFormat type NMTOKEN #IMPLIED >
+
+<!-- RBBI data -->
+<!ELEMENT icu:breakIteratorData (alias | (icu:boundaries?, icu:dictionaries?, icu:extensions?, icu:lstm?)) >
+
+<!ELEMENT icu:boundaries (alias | (icu:grapheme?, icu:word?, icu:line*, icu:sentence?, icu:title?, icu:xgc?)) >
+
+<!ELEMENT icu:dictionaries (alias | (icu:dictionary*)) >
+
+<!ELEMENT icu:extensions (alias | (icu:extension*)) >
+
+<!ELEMENT icu:extension ( #PCDATA ) >
+ <!--@ORDERED-->
+
+<!ELEMENT icu:lstm (alias | (icu:lstmdata*)) >
+
+<!ELEMENT icu:lstmdata ( #PCDATA ) >
+<!ATTLIST icu:lstmdata icu:dependency NMTOKEN #IMPLIED >
+<!ATTLIST icu:lstmdata type NMTOKEN #REQUIRED >
+
+<!ELEMENT icu:dictionary ( #PCDATA ) >
+<!ATTLIST icu:dictionary icu:dependency NMTOKEN #IMPLIED >
+<!ATTLIST icu:dictionary type NMTOKEN #REQUIRED >
+
+<!ELEMENT icu:grapheme ( #PCDATA ) >
+<!ATTLIST icu:grapheme icu:class NMTOKEN #IMPLIED >
+<!ATTLIST icu:grapheme icu:append NMTOKEN #IMPLIED >
+<!ATTLIST icu:grapheme icu:import NMTOKEN #IMPLIED >
+<!ATTLIST icu:grapheme icu:dependency NMTOKEN #IMPLIED >
+
+<!ELEMENT icu:word ( #PCDATA ) >
+<!ATTLIST icu:word icu:class NMTOKEN #IMPLIED >
+<!ATTLIST icu:word icu:append NMTOKEN #IMPLIED >
+<!ATTLIST icu:word icu:import NMTOKEN #IMPLIED >
+<!ATTLIST icu:word icu:dependency NMTOKEN #IMPLIED >
+
+<!ELEMENT icu:line ( #PCDATA ) >
+<!ATTLIST icu:line icu:class NMTOKEN #IMPLIED >
+<!ATTLIST icu:line icu:append NMTOKEN #IMPLIED >
+<!ATTLIST icu:line icu:import NMTOKEN #IMPLIED >
+<!ATTLIST icu:line icu:dependency NMTOKEN #IMPLIED >
+<!ATTLIST icu:line alt NMTOKENS #IMPLIED >
+
+<!ELEMENT icu:sentence ( #PCDATA ) >
+<!ATTLIST icu:sentence icu:class NMTOKEN #IMPLIED >
+<!ATTLIST icu:sentence icu:append NMTOKEN #IMPLIED >
+<!ATTLIST icu:sentence icu:import NMTOKEN #IMPLIED >
+<!ATTLIST icu:sentence icu:dependency NMTOKEN #IMPLIED >
+
+<!ELEMENT icu:title ( #PCDATA ) >
+<!ATTLIST icu:title icu:class NMTOKEN #IMPLIED >
+<!ATTLIST icu:title icu:append NMTOKEN #IMPLIED >
+<!ATTLIST icu:title icu:import NMTOKEN #IMPLIED >
+<!ATTLIST icu:title icu:dependency NMTOKEN #IMPLIED >
+
+<!ELEMENT icu:xgc ( #PCDATA ) >
+<!ATTLIST icu:xgc icu:class NMTOKEN #IMPLIED >
+<!ATTLIST icu:xgc icu:append NMTOKEN #IMPLIED >
+<!ATTLIST icu:xgc icu:import NMTOKEN #IMPLIED >
+<!ATTLIST icu:xgc icu:dependency NMTOKEN #IMPLIED >
+
+<!--deprecated -->
+<!ELEMENT icu:breakDictionaryData EMPTY >
+<!ATTLIST icu:breakDictionaryData icu:class NMTOKEN #IMPLIED >
+<!ATTLIST icu:breakDictionaryData icu:import NMTOKEN #IMPLIED >
+<!ATTLIST icu:breakDictionaryData icu:importFile CDATA #IMPLIED >
+
+<!-- RBT data -->
+<!ELEMENT icu:transforms ( alias | (default?, icu:transform*)) >
+<!ELEMENT icu:transform ( #PCDATA |cp )* >
+<!ATTLIST icu:transform type NMTOKEN #REQUIRED >
+
+<!-- leap month information, all deprecated -->
+<!ELEMENT icu:isLeapMonth ( alias | (icu:nonLeapSymbol?, icu:leapSymbol? ))> <!-- deprecated -->
+<!ELEMENT icu:nonLeapSymbol ( #PCDATA ) > <!-- deprecated -->
+<!ELEMENT icu:leapSymbol ( #PCDATA ) > <!-- deprecated -->
+
+<!-- UCA Rules -->
+<!ELEMENT icu:UCARules EMPTY >
+<!ATTLIST icu:UCARules icu:uca_rules CDATA #REQUIRED >
+
+<!-- Dependencies Rules -->
+<!ELEMENT icu:depends EMPTY >
+<!ATTLIST icu:depends icu:dependency CDATA #REQUIRED >
+
+<!-- ######################################################### -->
diff --git a/Build/source/libs/icu/icu-src/source/data/in/icudt70l.dat b/Build/source/libs/icu/icu-src/source/data/in/icudt71l.dat
index b0d5cf5cc98..113bc3d0fd3 100644
--- a/Build/source/libs/icu/icu-src/source/data/in/icudt70l.dat
+++ b/Build/source/libs/icu/icu-src/source/data/in/icudt71l.dat
Binary files differ
diff --git a/Build/source/libs/icu/icu-src/source/data/makedata.mak b/Build/source/libs/icu/icu-src/source/data/makedata.mak
index e8a33ff85dd..3825da92b9b 100644
--- a/Build/source/libs/icu/icu-src/source/data/makedata.mak
+++ b/Build/source/libs/icu/icu-src/source/data/makedata.mak
@@ -12,11 +12,11 @@
##############################################################################
# Keep the following in sync with the version - see common/unicode/uvernum.h
-U_ICUDATA_NAME=icudt70
+U_ICUDATA_NAME=icudt71
##############################################################################
!IF "$(UWP)" == "UWP"
# Optionally change the name of the data file for the UWP version.
-U_ICUDATA_NAME=icudt70
+U_ICUDATA_NAME=icudt71
!ENDIF
U_ICUDATA_ENDIAN_SUFFIX=l
UNICODE_VERSION=14.0
@@ -142,13 +142,20 @@ TESTDATABLD=$(ICUP)\source\test\testdata\out\build
ICUTOOLS=$(ICUP)\source\tools
!MESSAGE ICU tools path is $(ICUTOOLS)
+NATIVE_ARM=
+!IF "$(PROCESSOR_ARCHITECTURE)" == "ARM64" || "$(PROCESSOR_ARCHITEW6432)" == "ARM64"
+NATIVE_ARM=ARM64
+!ELSE IF "$(PROCESSOR_ARCHITECTURE)" == "ARM" || "$(PROCESSOR_ARCHITEW6432)" == "ARM"
+NATIVE_ARM=ARM
+!ENDIF
+
# ARM_CROSS_BUILD
# In order to support cross-compiling for ARM/ARM64 using the x64 tools
# we need to know if we're building the ARM/ARM64 data DLL, otherwise
# the existence of the x64 bits will cause us to think we are already done.
# Note: This is only for the "regular" builds, the UWP builds have a separate project file entirely.
ARM_CROSS_BUILD=
-!IF "$(UWP)" == ""
+!IF "$(UWP)" == "" && "$(NATIVE_ARM)" == ""
!IF "$(CFG)" == "ARM\Release" || "$(CFG)" == "ARM\Debug"
ARM_CROSS_BUILD=ARM
ARM_CROSSBUILD_TS=$(ICUTMP)\$(ARM_CROSS_BUILD).timestamp
@@ -185,6 +192,18 @@ CFGTOOLS=x64\Debug
!IF "$(CFG)" == "x86\Release" || "$(CFG)" == "x86\Debug"
PATH = $(ICUP)\bin;$(PATH)
ICUPBIN=$(ICUP)\bin
+# Use these path whether or not it's UWP build.
+!ELSE IF "$(NATIVE_ARM)" != ""
+!IF "$(CFG)" == "ARM\Release" || "$(CFG)" == "ARM\Debug"
+PATH = $(ICUP)\binARM;$(PATH)
+ICUPBIN=$(ICUP)\binARM
+!ELSE IF "$(CFG)" == "ARM64\Release" || "$(CFG)" == "ARM64\Debug"
+PATH = $(ICUP)\binARM64;$(PATH)
+ICUPBIN=$(ICUP)\binARM64
+!ELSE
+!ERROR Cross-build from ARM to x86 is not supported!
+!ENDIF
+# Build x86_64 or cross-build ARM
!ELSE
PATH = $(ICUP)\bin64;$(PATH)
ICUPBIN=$(ICUP)\bin64
diff --git a/Build/source/libs/icu/icu-src/source/data/unidata/norm2/BUILD b/Build/source/libs/icu/icu-src/source/data/unidata/norm2/BUILD.bazel
index 049e19bd41a..049e19bd41a 100644
--- a/Build/source/libs/icu/icu-src/source/data/unidata/norm2/BUILD
+++ b/Build/source/libs/icu/icu-src/source/data/unidata/norm2/BUILD.bazel
diff --git a/Build/source/libs/icu/icu-src/source/data/unidata/ucdterms.txt b/Build/source/libs/icu/icu-src/source/data/unidata/ucdterms.txt
deleted file mode 100644
index 34ecc1bf9b5..00000000000
--- a/Build/source/libs/icu/icu-src/source/data/unidata/ucdterms.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
-
-Unicode Data Files include all data files under the directories
-http://www.unicode.org/Public/ and http://www.unicode.org/reports/.
-Unicode Software includes any source code under the directories
-http://www.unicode.org/Public/ and http://www.unicode.org/reports/.
-
-NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING,
-INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES ("DATA FILES"),
-AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND
-BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE,
-DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
-
-COPYRIGHT AND PERMISSION NOTICE
-
-Copyright (C) 2016 and later: Unicode, Inc. and others.
-License & terms of use: http://www.unicode.org/copyright.html
-Copyright (c) 1991-2004 Unicode, Inc. All rights reserved. Distributed under the
-Terms of Use in http://www.unicode.org/copyright.html.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-the Unicode data files and associated documentation (the "Data Files") or
-Unicode software and associated documentation (the "Software") to deal in the
-Data Files or Software without restriction, including without limitation the
-rights to use, copy, modify, merge, publish, distribute, and/or sell copies of
-the Data Files or Software, and to permit persons to whom the Data Files or
-Software are furnished to do so, provided that (a) the above copyright notice(s)
-and this permission notice appear in all copies of the Data Files or Software,
-(b) both the above copyright notice(s) and this permission notice appear in
-associated documentation, and (c) there is clear notice in each modified Data
-File or in the Software as well as in the documentation associated with the Data
-File(s) or Software that the data or software has been modified.
-
-THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD
-PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
-NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
-DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
-OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR
-SOFTWARE.
-
-Except as contained in this notice, the name of a copyright holder shall not be
-used in advertising or otherwise to promote the sale, use or other dealings in
-these Data Files or Software without prior written authorization of the
-copyright holder.
diff --git a/Build/source/libs/icu/icu-src/source/extra/uconv/makedata.mak b/Build/source/libs/icu/icu-src/source/extra/uconv/makedata.mak
index b30f59728b5..81fcc908ee6 100644
--- a/Build/source/libs/icu/icu-src/source/extra/uconv/makedata.mak
+++ b/Build/source/libs/icu/icu-src/source/extra/uconv/makedata.mak
@@ -51,8 +51,16 @@ PKGMODE=static
ICD=$(ICUDATA)^\
DATA_PATH=$(ICUP)\data^\
+NATIVE_ARM=
+!IF "$(PROCESSOR_ARCHITECTURE)" == "ARM64" || "$(PROCESSOR_ARCHITEW6432)" == "ARM64"
+NATIVE_ARM=ARM64
+!ELSE IF "$(PROCESSOR_ARCHITECTURE)" == "ARM" || "$(PROCESSOR_ARCHITEW6432)" == "ARM"
+NATIVE_ARM=ARM
+!ENDIF
+
# Use the x64 tools for building ARM and ARM64.
# Note: This is similar to the TOOLS CFG PATH in source\data\makedata.mak
+!IF "$(NATIVE_ARM)" == ""
!IF "$(CFG)" == "x64\Release" || "$(CFG)" == "x64\Debug" || "$(CFG)" == "ARM\Release" || "$(CFG)" == "ARM\Debug" || "$(CFG)" == "ARM64\Release" || "$(CFG)" == "ARM64\Debug"
ICUTOOLS=$(ICUP)\bin64
PATH = $(ICUP)\bin64;$(PATH)
@@ -60,6 +68,15 @@ PATH = $(ICUP)\bin64;$(PATH)
ICUTOOLS=$(ICUP)\bin
PATH = $(ICUP)\bin;$(PATH)
!ENDIF
+!ELSE
+!IF "$(CFG)" == "ARM\Release" || "$(CFG)" == "ARM\Debug"
+ICUTOOLS=$(ICUP)\binARM
+PATH = $(ICUP)\binARM;$(PATH)
+!ELSE
+ICUTOOLS=$(ICUP)\binARM64
+PATH = $(ICUP)\binARM64;$(PATH)
+!ENDIF
+!ENDIF
# If building ARM/ARM, then we need to pass the arch as an argument.
EXTRA_PKGDATA_ARGUMENTS=
diff --git a/Build/source/libs/icu/icu-src/source/i18n/BUILD b/Build/source/libs/icu/icu-src/source/i18n/BUILD.bazel
index 2d85cdb180e..2d85cdb180e 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/BUILD
+++ b/Build/source/libs/icu/icu-src/source/i18n/BUILD.bazel
diff --git a/Build/source/libs/icu/icu-src/source/i18n/alphaindex.cpp b/Build/source/libs/icu/icu-src/source/i18n/alphaindex.cpp
index 34407f677a6..88d63675a7c 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/alphaindex.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/alphaindex.cpp
@@ -451,12 +451,11 @@ BucketList *AlphabeticIndex::createBucketList(UErrorCode &errorCode) const {
bucketList->setDeleter(uprv_deleteUObject);
// underflow bucket
- Bucket *bucket = new Bucket(getUnderflowLabel(), emptyString_, U_ALPHAINDEX_UNDERFLOW);
- if (bucket == NULL) {
- errorCode = U_MEMORY_ALLOCATION_ERROR;
+ LocalPointer<Bucket> bucket(new Bucket(getUnderflowLabel(), emptyString_, U_ALPHAINDEX_UNDERFLOW), errorCode);
+ if (U_FAILURE(errorCode)) {
return NULL;
}
- bucketList->addElementX(bucket, errorCode);
+ bucketList->adoptElement(bucket.orphan(), errorCode);
if (U_FAILURE(errorCode)) { return NULL; }
UnicodeString temp;
@@ -481,28 +480,24 @@ BucketList *AlphabeticIndex::createBucketList(UErrorCode &errorCode) const {
if (skippedScript && bucketList->size() > 1) {
// We are skipping one or more scripts,
// and we are not just getting out of the underflow label.
- bucket = new Bucket(getInflowLabel(), inflowBoundary, U_ALPHAINDEX_INFLOW);
- if (bucket == NULL) {
- errorCode = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
- }
- bucketList->addElementX(bucket, errorCode);
+ bucket.adoptInsteadAndCheckErrorCode(
+ new Bucket(getInflowLabel(), inflowBoundary, U_ALPHAINDEX_INFLOW), errorCode);
+ bucketList->adoptElement(bucket.orphan(), errorCode);
+ if (U_FAILURE(errorCode)) { return nullptr; }
}
}
// Add a bucket with the current label.
- bucket = new Bucket(fixLabel(current, temp), current, U_ALPHAINDEX_NORMAL);
- if (bucket == NULL) {
- errorCode = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
- }
- bucketList->addElementX(bucket, errorCode);
+ bucket.adoptInsteadAndCheckErrorCode(
+ new Bucket(fixLabel(current, temp), current, U_ALPHAINDEX_NORMAL), errorCode);
+ bucketList->adoptElement(bucket.orphan(), errorCode);
+ if (U_FAILURE(errorCode)) { return nullptr; }
// Remember ASCII and Pinyin buckets for Pinyin redirects.
UChar c;
if (current.length() == 1 && 0x41 <= (c = current.charAt(0)) && c <= 0x5A) { // A-Z
- asciiBuckets[c - 0x41] = bucket;
+ asciiBuckets[c - 0x41] = (Bucket *)bucketList->lastElement();
} else if (current.length() == BASE_LENGTH + 1 && current.startsWith(BASE, BASE_LENGTH) &&
0x41 <= (c = current.charAt(BASE_LENGTH)) && c <= 0x5A) {
- pinyinBuckets[c - 0x41] = bucket;
+ pinyinBuckets[c - 0x41] = (Bucket *)bucketList->lastElement();
hasPinyin = TRUE;
}
// Check for multiple primary weights.
@@ -526,15 +521,16 @@ BucketList *AlphabeticIndex::createBucketList(UErrorCode &errorCode) const {
// to the previous single-character bucket.
// For example, after ... Q R S Sch we add Sch\uFFFF->S
// and after ... Q R S Sch Sch\uFFFF St we add St\uFFFF->S.
- bucket = new Bucket(emptyString_,
+ bucket.adoptInsteadAndCheckErrorCode(new Bucket(emptyString_,
UnicodeString(current).append((UChar)0xFFFF),
- U_ALPHAINDEX_NORMAL);
- if (bucket == NULL) {
- errorCode = U_MEMORY_ALLOCATION_ERROR;
+ U_ALPHAINDEX_NORMAL),
+ errorCode);
+ if (U_FAILURE(errorCode)) {
return NULL;
}
bucket->displayBucket_ = singleBucket;
- bucketList->addElementX(bucket, errorCode);
+ bucketList->adoptElement(bucket.orphan(), errorCode);
+ if (U_FAILURE(errorCode)) { return nullptr; }
hasInvisibleBuckets = TRUE;
break;
}
@@ -553,12 +549,10 @@ BucketList *AlphabeticIndex::createBucketList(UErrorCode &errorCode) const {
return bl;
}
// overflow bucket
- bucket = new Bucket(getOverflowLabel(), *scriptUpperBoundary, U_ALPHAINDEX_OVERFLOW);
- if (bucket == NULL) {
- errorCode = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
- }
- bucketList->addElementX(bucket, errorCode); // final
+ bucket.adoptInsteadAndCheckErrorCode(
+ new Bucket(getOverflowLabel(), *scriptUpperBoundary, U_ALPHAINDEX_OVERFLOW), errorCode);
+ bucketList->adoptElement(bucket.orphan(), errorCode); // final
+ if (U_FAILURE(errorCode)) { return nullptr; }
if (hasPinyin) {
// Redirect Pinyin buckets.
@@ -589,7 +583,7 @@ BucketList *AlphabeticIndex::createBucketList(UErrorCode &errorCode) const {
int32_t i = bucketList->size() - 1;
Bucket *nextBucket = getBucket(*bucketList, i);
while (--i > 0) {
- bucket = getBucket(*bucketList, i);
+ Bucket *bucket = getBucket(*bucketList, i);
if (bucket->displayBucket_ != NULL) {
continue; // skip invisible buckets
}
@@ -609,9 +603,9 @@ BucketList *AlphabeticIndex::createBucketList(UErrorCode &errorCode) const {
// Do not call publicBucketList->setDeleter():
// This vector shares its objects with the bucketList.
for (int32_t j = 0; j < bucketList->size(); ++j) {
- bucket = getBucket(*bucketList, j);
+ Bucket *bucket = getBucket(*bucketList, j);
if (bucket->displayBucket_ == NULL) {
- publicBucketList->addElementX(bucket, errorCode);
+ publicBucketList->addElement(bucket, errorCode);
}
}
if (U_FAILURE(errorCode)) { return NULL; }
@@ -679,13 +673,13 @@ void AlphabeticIndex::initBuckets(UErrorCode &errorCode) {
bucket = bucket->displayBucket_;
}
if (bucket->records_ == NULL) {
- bucket->records_ = new UVector(errorCode);
- if (bucket->records_ == NULL) {
- errorCode = U_MEMORY_ALLOCATION_ERROR;
+ LocalPointer<UVector> records(new UVector(errorCode), errorCode);
+ if (U_FAILURE(errorCode)) {
return;
}
+ bucket->records_ = records.orphan();
}
- bucket->records_->addElementX(r, errorCode);
+ bucket->records_->addElement(r, errorCode);
}
}
@@ -1011,12 +1005,11 @@ UVector *AlphabeticIndex::firstStringsInScript(UErrorCode &status) {
// and the one for unassigned implicit weights (Cn).
continue;
}
- UnicodeString *s = new UnicodeString(boundary);
- if (s == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
+ LocalPointer<UnicodeString> s(new UnicodeString(boundary), status);
+ dest->adoptElement(s.orphan(), status);
+ if (U_FAILURE(status)) {
+ return nullptr;
}
- dest->addElementX(s, status);
}
return dest.orphan();
}
@@ -1067,19 +1060,18 @@ AlphabeticIndex & AlphabeticIndex::addRecord(const UnicodeString &name, const vo
return *this;
}
if (inputList_ == NULL) {
- inputList_ = new UVector(status);
- if (inputList_ == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
+ LocalPointer<UVector> inputList(new UVector(status), status);
+ if (U_FAILURE(status)) {
return *this;
}
+ inputList_ = inputList.orphan();
inputList_->setDeleter(alphaIndex_deleteRecord);
}
- Record *r = new Record(name, data);
- if (r == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
+ LocalPointer<Record> r(new Record(name, data), status);
+ inputList_->adoptElement(r.orphan(), status);
+ if (U_FAILURE(status)) {
return *this;
}
- inputList_->addElementX(r, status);
clearBuckets();
//std::string ss;
//std::string ss2;
diff --git a/Build/source/libs/icu/icu-src/source/i18n/collationdatabuilder.cpp b/Build/source/libs/icu/icu-src/source/i18n/collationdatabuilder.cpp
index 25050aa777e..b10de993c27 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/collationdatabuilder.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/collationdatabuilder.cpp
@@ -522,12 +522,11 @@ CollationDataBuilder::addConditionalCE32(const UnicodeString &context, uint32_t
errorCode = U_BUFFER_OVERFLOW_ERROR;
return -1;
}
- ConditionalCE32 *cond = new ConditionalCE32(context, ce32);
- if(cond == NULL) {
- errorCode = U_MEMORY_ALLOCATION_ERROR;
+ LocalPointer<ConditionalCE32> cond(new ConditionalCE32(context, ce32), errorCode);
+ conditionalCE32s.adoptElement(cond.orphan(), errorCode);
+ if(U_FAILURE(errorCode)) {
return -1;
}
- conditionalCE32s.addElementX(cond, errorCode);
return index;
}
diff --git a/Build/source/libs/icu/icu-src/source/i18n/csdetect.cpp b/Build/source/libs/icu/icu-src/source/i18n/csdetect.cpp
index 84f0776542d..d866eb66286 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/csdetect.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/csdetect.cpp
@@ -270,6 +270,11 @@ const CharsetMatch * const *CharsetDetector::detectAll(int32_t &maxMatchesFound,
maxMatchesFound = resultCount;
+ if (maxMatchesFound == 0) {
+ status = U_INVALID_CHAR_FOUND;
+ return NULL;
+ }
+
return resultArray;
}
diff --git a/Build/source/libs/icu/icu-src/source/i18n/double-conversion-ieee.h b/Build/source/libs/icu/icu-src/source/i18n/double-conversion-ieee.h
index 31c35867de5..2940acb1698 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/double-conversion-ieee.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/double-conversion-ieee.h
@@ -164,11 +164,19 @@ class Double {
}
bool IsQuietNan() const {
+#if (defined(__mips__) && !defined(__mips_nan2008)) || defined(__hppa__)
+ return IsNan() && ((AsUint64() & kQuietNanBit) == 0);
+#else
return IsNan() && ((AsUint64() & kQuietNanBit) != 0);
+#endif
}
bool IsSignalingNan() const {
+#if (defined(__mips__) && !defined(__mips_nan2008)) || defined(__hppa__)
+ return IsNan() && ((AsUint64() & kQuietNanBit) != 0);
+#else
return IsNan() && ((AsUint64() & kQuietNanBit) == 0);
+#endif
}
@@ -250,7 +258,12 @@ class Double {
private:
static const int kDenormalExponent = -kExponentBias + 1;
static const uint64_t kInfinity = DOUBLE_CONVERSION_UINT64_2PART_C(0x7FF00000, 00000000);
+#if (defined(__mips__) && !defined(__mips_nan2008)) || defined(__hppa__)
+ static const uint64_t kNaN = DOUBLE_CONVERSION_UINT64_2PART_C(0x7FF7FFFF, FFFFFFFF);
+#else
static const uint64_t kNaN = DOUBLE_CONVERSION_UINT64_2PART_C(0x7FF80000, 00000000);
+#endif
+
const uint64_t d64_;
@@ -350,11 +363,19 @@ class Single {
}
bool IsQuietNan() const {
+#if (defined(__mips__) && !defined(__mips_nan2008)) || defined(__hppa__)
+ return IsNan() && ((AsUint32() & kQuietNanBit) == 0);
+#else
return IsNan() && ((AsUint32() & kQuietNanBit) != 0);
+#endif
}
bool IsSignalingNan() const {
+#if (defined(__mips__) && !defined(__mips_nan2008)) || defined(__hppa__)
+ return IsNan() && ((AsUint32() & kQuietNanBit) != 0);
+#else
return IsNan() && ((AsUint32() & kQuietNanBit) == 0);
+#endif
}
@@ -424,7 +445,11 @@ class Single {
static const int kDenormalExponent = -kExponentBias + 1;
static const int kMaxExponent = 0xFF - kExponentBias;
static const uint32_t kInfinity = 0x7F800000;
+#if (defined(__mips__) && !defined(__mips_nan2008)) || defined(__hppa__)
+ static const uint32_t kNaN = 0x7FBFFFFF;
+#else
static const uint32_t kNaN = 0x7FC00000;
+#endif
const uint32_t d32_;
diff --git a/Build/source/libs/icu/icu-src/source/i18n/double-conversion-utils.h b/Build/source/libs/icu/icu-src/source/i18n/double-conversion-utils.h
index 7f23e0a8250..11c92717c10 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/double-conversion-utils.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/double-conversion-utils.h
@@ -37,6 +37,9 @@
#ifndef DOUBLE_CONVERSION_UTILS_H_
#define DOUBLE_CONVERSION_UTILS_H_
+// Use DOUBLE_CONVERSION_NON_PREFIXED_MACROS to get unprefixed macros as was
+// the case in double-conversion releases prior to 3.1.6
+
#include <cstdlib>
#include <cstring>
@@ -46,9 +49,17 @@
#define DOUBLE_CONVERSION_ASSERT(condition) \
U_ASSERT(condition)
#endif
+#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(ASSERT)
+#define ASSERT DOUBLE_CONVERSION_ASSERT
+#endif
+
#ifndef DOUBLE_CONVERSION_UNIMPLEMENTED
#define DOUBLE_CONVERSION_UNIMPLEMENTED() (abort())
#endif
+#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(UNIMPLEMENTED)
+#define UNIMPLEMENTED DOUBLE_CONVERSION_UNIMPLEMENTED
+#endif
+
#ifndef DOUBLE_CONVERSION_NO_RETURN
#ifdef _MSC_VER
#define DOUBLE_CONVERSION_NO_RETURN __declspec(noreturn)
@@ -56,6 +67,10 @@
#define DOUBLE_CONVERSION_NO_RETURN __attribute__((noreturn))
#endif
#endif
+#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(NO_RETURN)
+#define NO_RETURN DOUBLE_CONVERSION_NO_RETURN
+#endif
+
#ifndef DOUBLE_CONVERSION_UNREACHABLE
#ifdef _MSC_VER
void DOUBLE_CONVERSION_NO_RETURN abort_noreturn();
@@ -65,6 +80,9 @@ inline void abort_noreturn() { abort(); }
#define DOUBLE_CONVERSION_UNREACHABLE() (abort())
#endif
#endif
+#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(UNREACHABLE)
+#define UNREACHABLE DOUBLE_CONVERSION_UNREACHABLE
+#endif
// Not all compilers support __has_attribute and combining a check for both
// ifdef and __has_attribute on the same preprocessor line isn't portable.
@@ -81,12 +99,18 @@ inline void abort_noreturn() { abort(); }
#define DOUBLE_CONVERSION_UNUSED
#endif
#endif
+#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(UNUSED)
+#define UNUSED DOUBLE_CONVERSION_UNUSED
+#endif
#if DOUBLE_CONVERSION_HAS_ATTRIBUTE(uninitialized)
#define DOUBLE_CONVERSION_STACK_UNINITIALIZED __attribute__((uninitialized))
#else
#define DOUBLE_CONVERSION_STACK_UNINITIALIZED
#endif
+#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(STACK_UNINITIALIZED)
+#define STACK_UNINITIALIZED DOUBLE_CONVERSION_STACK_UNINITIALIZED
+#endif
// Double operations detection based on target architecture.
// Linux uses a 80bit wide floating point stack on x86. This induces double
@@ -127,7 +151,7 @@ int main(int argc, char** argv) {
defined(_MIPS_ARCH_MIPS32R2) || defined(__ARMEB__) ||\
defined(__AARCH64EL__) || defined(__aarch64__) || defined(__AARCH64EB__) || \
defined(__riscv) || defined(__e2k__) || \
- defined(__or1k__) || defined(__arc__) || \
+ defined(__or1k__) || defined(__arc__) || defined(__ARC64__) || \
defined(__microblaze__) || defined(__XTENSA__) || \
defined(__EMSCRIPTEN__) || defined(__wasm32__)
#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
@@ -144,6 +168,9 @@ int main(int argc, char** argv) {
#else
#error Target architecture was not detected as supported by Double-Conversion.
#endif
+#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(CORRECT_DOUBLE_OPERATIONS)
+#define CORRECT_DOUBLE_OPERATIONS DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
+#endif
#if defined(_WIN32) && !defined(__MINGW32__)
@@ -169,7 +196,9 @@ typedef uint16_t uc16;
// Usage: instead of writing 0x1234567890123456
// write DOUBLE_CONVERSION_UINT64_2PART_C(0x12345678,90123456);
#define DOUBLE_CONVERSION_UINT64_2PART_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
-
+#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(UINT64_2PART_C)
+#define UINT64_2PART_C DOUBLE_CONVERSION_UINT64_2PART_C
+#endif
// The expression DOUBLE_CONVERSION_ARRAY_SIZE(a) is a compile-time constant of type
// size_t which represents the number of elements of the given
@@ -180,6 +209,9 @@ typedef uint16_t uc16;
((sizeof(a) / sizeof(*(a))) / \
static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
#endif
+#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(ARRAY_SIZE)
+#define ARRAY_SIZE DOUBLE_CONVERSION_ARRAY_SIZE
+#endif
// A macro to disallow the evil copy constructor and operator= functions
// This should be used in the private: declarations for a class
@@ -188,6 +220,9 @@ typedef uint16_t uc16;
TypeName(const TypeName&); \
void operator=(const TypeName&)
#endif
+#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(DC_DISALLOW_COPY_AND_ASSIGN)
+#define DC_DISALLOW_COPY_AND_ASSIGN DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN
+#endif
// A macro to disallow all the implicit constructors, namely the
// default constructor, copy constructor and operator= functions.
@@ -200,6 +235,9 @@ typedef uint16_t uc16;
TypeName(); \
DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(TypeName)
#endif
+#if defined(DOUBLE_CONVERSION_NON_PREFIXED_MACROS) && !defined(DC_DISALLOW_IMPLICIT_CONSTRUCTORS)
+#define DC_DISALLOW_IMPLICIT_CONSTRUCTORS DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS
+#endif
// ICU PATCH: Wrap in ICU namespace
U_NAMESPACE_BEGIN
diff --git a/Build/source/libs/icu/icu-src/source/i18n/dtfmtsym.cpp b/Build/source/libs/icu/icu-src/source/i18n/dtfmtsym.cpp
index ab5f2b612c1..134b919f06e 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/dtfmtsym.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/dtfmtsym.cpp
@@ -1574,26 +1574,20 @@ struct CalendarDataSink : public ResourceSink {
errorCode);
if (U_FAILURE(errorCode)) { return; }
}
- LocalPointer<UnicodeString> aliasRelativePathCopy(new UnicodeString(aliasRelativePath), errorCode);
- resourcesToVisitNext->addElementX(aliasRelativePathCopy.getAlias(), errorCode);
+ LocalPointer<UnicodeString> aliasRelativePathCopy(aliasRelativePath.clone(), errorCode);
+ resourcesToVisitNext->adoptElement(aliasRelativePathCopy.orphan(), errorCode);
if (U_FAILURE(errorCode)) { return; }
- // Only release ownership after resourcesToVisitNext takes it (no error happened):
- aliasRelativePathCopy.orphan();
continue;
} else if (aliasType == SAME_CALENDAR) {
// Register same-calendar alias
if (arrays.get(aliasRelativePath) == NULL && maps.get(aliasRelativePath) == NULL) {
- LocalPointer<UnicodeString> aliasRelativePathCopy(new UnicodeString(aliasRelativePath), errorCode);
- aliasPathPairs.addElementX(aliasRelativePathCopy.getAlias(), errorCode);
+ LocalPointer<UnicodeString> aliasRelativePathCopy(aliasRelativePath.clone(), errorCode);
+ aliasPathPairs.adoptElement(aliasRelativePathCopy.orphan(), errorCode);
if (U_FAILURE(errorCode)) { return; }
- // Only release ownership after aliasPathPairs takes it (no error happened):
- aliasRelativePathCopy.orphan();
- LocalPointer<UnicodeString> keyUStringCopy(new UnicodeString(keyUString), errorCode);
- aliasPathPairs.addElementX(keyUStringCopy.getAlias(), errorCode);
+ LocalPointer<UnicodeString> keyUStringCopy(keyUString.clone(), errorCode);
+ aliasPathPairs.adoptElement(keyUStringCopy.orphan(), errorCode);
if (U_FAILURE(errorCode)) { return; }
- // Only release ownership after aliasPathPairs takes it (no error happened):
- keyUStringCopy.orphan();
}
continue;
}
@@ -1760,16 +1754,12 @@ struct CalendarDataSink : public ResourceSink {
if (U_FAILURE(errorCode)) { return; }
if (aliasType == SAME_CALENDAR) {
// Store the alias path and the current path on aliasPathPairs
- LocalPointer<UnicodeString> aliasRelativePathCopy(new UnicodeString(aliasRelativePath), errorCode);
- aliasPathPairs.addElementX(aliasRelativePathCopy.getAlias(), errorCode);
+ LocalPointer<UnicodeString> aliasRelativePathCopy(aliasRelativePath.clone(), errorCode);
+ aliasPathPairs.adoptElement(aliasRelativePathCopy.orphan(), errorCode);
if (U_FAILURE(errorCode)) { return; }
- // Only release ownership after aliasPathPairs takes it (no error happened):
- aliasRelativePathCopy.orphan();
- LocalPointer<UnicodeString> pathCopy(new UnicodeString(path), errorCode);
- aliasPathPairs.addElementX(pathCopy.getAlias(), errorCode);
+ LocalPointer<UnicodeString> pathCopy(path.clone(), errorCode);
+ aliasPathPairs.adoptElement(pathCopy.orphan(), errorCode);
if (U_FAILURE(errorCode)) { return; }
- // Only release ownership after aliasPathPairs takes it (no error happened):
- pathCopy.orphan();
// Drop the latest key on the path and continue
path.retainBetween(0, pathLength);
diff --git a/Build/source/libs/icu/icu-src/source/i18n/dtitvfmt.cpp b/Build/source/libs/icu/icu-src/source/i18n/dtitvfmt.cpp
index 298fb62be0c..d51ddcd5c70 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/dtitvfmt.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/dtitvfmt.cpp
@@ -965,16 +965,22 @@ DateIntervalFormat::normalizeHourMetacharacters(const UnicodeString& skeleton) c
UnicodeString result = skeleton;
UChar hourMetachar = u'\0';
+ UChar dayPeriodChar = u'\0';
int32_t metacharStart = 0;
int32_t metacharCount = 0;
for (int32_t i = 0; i < result.length(); i++) {
UChar c = result[i];
- if (c == LOW_J || c == CAP_J || c == CAP_C) {
+ if (c == LOW_J || c == CAP_J || c == CAP_C || c == LOW_H || c == CAP_H || c == LOW_K || c == CAP_K) {
if (hourMetachar == u'\0') {
hourMetachar = c;
metacharStart = i;
}
++metacharCount;
+ } else if (c == LOW_A || c == LOW_B || c == CAP_B) {
+ if (dayPeriodChar == u'\0') {
+ dayPeriodChar = c;
+ }
+ ++metacharCount;
} else {
if (hourMetachar != u'\0') {
break;
@@ -985,7 +991,6 @@ DateIntervalFormat::normalizeHourMetacharacters(const UnicodeString& skeleton) c
if (hourMetachar != u'\0') {
UErrorCode err = U_ZERO_ERROR;
UChar hourChar = CAP_H;
- UChar dayPeriodChar = LOW_A;
UnicodeString convertedPattern = DateFormat::getBestPattern(fLocale, UnicodeString(hourMetachar), err);
if (U_SUCCESS(err)) {
@@ -1012,6 +1017,8 @@ DateIntervalFormat::normalizeHourMetacharacters(const UnicodeString& skeleton) c
dayPeriodChar = LOW_B;
} else if (convertedPattern.indexOf(CAP_B) != -1) {
dayPeriodChar = CAP_B;
+ } else if (dayPeriodChar == u'\0') {
+ dayPeriodChar = LOW_A;
}
}
diff --git a/Build/source/libs/icu/icu-src/source/i18n/dtptngen.cpp b/Build/source/libs/icu/icu-src/source/i18n/dtptngen.cpp
index 6aee1750f90..e781c6e26f5 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/dtptngen.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/dtptngen.cpp
@@ -273,8 +273,6 @@ static const char* const CLDR_FIELD_WIDTH[] = { // [UDATPG_WIDTH_COUNT]
"", "-short", "-narrow"
};
-// TODO(ticket:13619): remove when definition uncommented in dtptngen.h.
-static const int32_t UDATPG_WIDTH_COUNT = UDATPG_NARROW + 1;
static constexpr UDateTimePGDisplayWidth UDATPG_WIDTH_APPENDITEM = UDATPG_WIDE;
static constexpr int32_t UDATPG_FIELD_KEY_MAX = 24; // max length of CLDR field tag (type + width)
@@ -393,10 +391,13 @@ DateTimePatternGenerator::operator=(const DateTimePatternGenerator& other) {
*fp = *(other.fp);
dtMatcher->copyFrom(other.dtMatcher->skeleton);
*distanceInfo = *(other.distanceInfo);
- dateTimeFormat = other.dateTimeFormat;
+ for (int32_t style = UDAT_FULL; style <= UDAT_SHORT; style++) {
+ dateTimeFormat[style] = other.dateTimeFormat[style];
+ }
decimal = other.decimal;
- // NUL-terminate for the C API.
- dateTimeFormat.getTerminatedBuffer();
+ for (int32_t style = UDAT_FULL; style <= UDAT_SHORT; style++) {
+ dateTimeFormat[style].getTerminatedBuffer(); // NUL-terminate for the C API.
+ }
decimal.getTerminatedBuffer();
delete skipMatcher;
if ( other.skipMatcher == nullptr ) {
@@ -430,7 +431,12 @@ DateTimePatternGenerator::operator==(const DateTimePatternGenerator& other) cons
return true;
}
if ((pLocale==other.pLocale) && (patternMap->equals(*other.patternMap)) &&
- (dateTimeFormat==other.dateTimeFormat) && (decimal==other.decimal)) {
+ (decimal==other.decimal)) {
+ for (int32_t style = UDAT_FULL; style <= UDAT_SHORT; style++) {
+ if (dateTimeFormat[style] != other.dateTimeFormat[style]) {
+ return false;
+ }
+ }
for ( int32_t i=0 ; i<UDATPG_FIELD_COUNT; ++i ) {
if (appendItemFormats[i] != other.appendItemFormats[i]) {
return false;
@@ -1199,7 +1205,21 @@ DateTimePatternGenerator::getBestPattern(const UnicodeString& patternForm, UDate
}
resultPattern.remove();
status = U_ZERO_ERROR;
- dtFormat=getDateTimeFormat();
+ // determine which dateTimeFormat to use
+ PtnSkeleton* reqSkeleton = dtMatcher->getSkeletonPtr();
+ UDateFormatStyle style = UDAT_SHORT;
+ int32_t monthFieldLen = reqSkeleton->baseOriginal.getFieldLength(UDATPG_MONTH_FIELD);
+ if (monthFieldLen == 4) {
+ if (reqSkeleton->baseOriginal.getFieldLength(UDATPG_WEEKDAY_FIELD) > 0) {
+ style = UDAT_FULL;
+ } else {
+ style = UDAT_LONG;
+ }
+ } else if (monthFieldLen == 3) {
+ style = UDAT_MEDIUM;
+ }
+ // and now use it to compose date and time
+ dtFormat=getDateTimeFormat(style, status);
SimpleFormatter(dtFormat, 2, 2, status).format(timePattern, datePattern, resultPattern, status);
return resultPattern;
}
@@ -1335,14 +1355,45 @@ DateTimePatternGenerator::addCanonicalItems(UErrorCode& status) {
void
DateTimePatternGenerator::setDateTimeFormat(const UnicodeString& dtFormat) {
- dateTimeFormat = dtFormat;
- // NUL-terminate for the C API.
- dateTimeFormat.getTerminatedBuffer();
+ UErrorCode status = U_ZERO_ERROR;
+ for (int32_t style = UDAT_FULL; style <= UDAT_SHORT; style++) {
+ setDateTimeFormat((UDateFormatStyle)style, dtFormat, status);
+ }
}
const UnicodeString&
DateTimePatternGenerator::getDateTimeFormat() const {
- return dateTimeFormat;
+ UErrorCode status = U_ZERO_ERROR;
+ return getDateTimeFormat(UDAT_MEDIUM, status);
+}
+
+void
+DateTimePatternGenerator::setDateTimeFormat(UDateFormatStyle style, const UnicodeString& dtFormat, UErrorCode& status) {
+ if (U_FAILURE(status)) {
+ return;
+ }
+ if (style < UDAT_FULL || style > UDAT_SHORT) {
+ status = U_ILLEGAL_ARGUMENT_ERROR;
+ return;
+ }
+ dateTimeFormat[style] = dtFormat;
+ // Note for the following: getTerminatedBuffer() can re-allocate the UnicodeString
+ // buffer so we do this here before clients request a const ref to the UnicodeString
+ // or its buffer.
+ dateTimeFormat[style].getTerminatedBuffer(); // NUL-terminate for the C API.
+}
+
+const UnicodeString&
+DateTimePatternGenerator::getDateTimeFormat(UDateFormatStyle style, UErrorCode& status) const {
+ static const UnicodeString emptyString = UNICODE_STRING_SIMPLE("");
+ if (U_FAILURE(status)) {
+ return emptyString;
+ }
+ if (style < UDAT_FULL || style > UDAT_SHORT) {
+ status = U_ILLEGAL_ARGUMENT_ERROR;
+ return emptyString;
+ }
+ return dateTimeFormat[style];
}
void
@@ -1378,13 +1429,15 @@ DateTimePatternGenerator::setDateTimeFromCalendar(const Locale& locale, UErrorCo
}
if (U_FAILURE(status)) { return; }
- if (ures_getSize(dateTimePatterns.getAlias()) <= DateFormat::kDateTime)
+ if (ures_getSize(dateTimePatterns.getAlias()) <= DateFormat::kDateTimeOffset + DateFormat::kShort)
{
status = U_INVALID_FORMAT_ERROR;
return;
}
- resStr = ures_getStringByIndex(dateTimePatterns.getAlias(), (int32_t)DateFormat::kDateTime, &resStrLen, &status);
- setDateTimeFormat(UnicodeString(TRUE, resStr, resStrLen));
+ for (int32_t style = UDAT_FULL; style <= UDAT_SHORT; style++) {
+ resStr = ures_getStringByIndex(dateTimePatterns.getAlias(), (int32_t)DateFormat::kDateTimeOffset + style, &resStrLen, &status);
+ setDateTimeFormat((UDateFormatStyle)style, UnicodeString(TRUE, resStr, resStrLen), status);
+ }
}
void
@@ -2788,16 +2841,17 @@ DTSkeletonEnumeration::DTSkeletonEnumeration(PatternMap& patternMap, dtStrEnum t
break;
}
if ( !isCanonicalItem(s) ) {
- LocalPointer<UnicodeString> newElem(new UnicodeString(s), status);
+ LocalPointer<UnicodeString> newElem(s.clone(), status);
if (U_FAILURE(status)) {
return;
}
- fSkeletons->addElementX(newElem.getAlias(), status);
+ fSkeletons->addElement(newElem.getAlias(), status);
if (U_FAILURE(status)) {
fSkeletons.adoptInstead(nullptr);
return;
}
- newElem.orphan(); // fSkeletons vector now owns the UnicodeString.
+ newElem.orphan(); // fSkeletons vector now owns the UnicodeString (although it
+ // does not use a deleter function to manage the ownership).
}
curElem = curElem->next.getAlias();
}
@@ -2865,12 +2919,13 @@ DTRedundantEnumeration::add(const UnicodeString& pattern, UErrorCode& status) {
if (U_FAILURE(status)) {
return;
}
- fPatterns->addElementX(newElem.getAlias(), status);
+ fPatterns->addElement(newElem.getAlias(), status);
if (U_FAILURE(status)) {
fPatterns.adoptInstead(nullptr);
return;
}
- newElem.orphan(); // fPatterns now owns the string.
+ newElem.orphan(); // fPatterns now owns the string, although a UVector
+ // deleter function is not used to manage that ownership.
}
const UnicodeString*
diff --git a/Build/source/libs/icu/icu-src/source/i18n/formattedval_sbimpl.cpp b/Build/source/libs/icu/icu-src/source/i18n/formattedval_sbimpl.cpp
index 70ffacac4b7..72197cdd8c7 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/formattedval_sbimpl.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/formattedval_sbimpl.cpp
@@ -230,6 +230,11 @@ bool FormattedValueStringBuilderImpl::nextPositionImpl(ConstrainedFieldPosition&
if (si + 1 < spanIndicesCount) {
nextSpanStart = spanIndices[si + 1].start;
}
+ if (length == 0) {
+ // ICU-21871: Don't return fields on empty spans
+ i--;
+ continue;
+ }
if (cfpos.matchesField(spanCategory, spanValue)) {
fieldStart = i - fString.fZero;
int32_t end = fieldStart + length;
diff --git a/Build/source/libs/icu/icu-src/source/i18n/i18n.vcxproj b/Build/source/libs/icu/icu-src/source/i18n/i18n.vcxproj
index 3471cf3e55d..23b8527cf0e 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/i18n.vcxproj
+++ b/Build/source/libs/icu/icu-src/source/i18n/i18n.vcxproj
@@ -60,7 +60,7 @@
</ClCompile>
<Link>
<AdditionalDependencies>icuucd.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <OutputFile>..\..\$(IcuBinOutputDir)\icuin70d.dll</OutputFile>
+ <OutputFile>..\..\$(IcuBinOutputDir)\icuin71d.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\$(IcuLibOutputDir)\icuind.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\$(IcuLibOutputDir)\icuind.lib</ImportLibrary>
</Link>
@@ -73,7 +73,7 @@
</ClCompile>
<Link>
<AdditionalDependencies>icuuc.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <OutputFile>..\..\$(IcuBinOutputDir)\icuin70.dll</OutputFile>
+ <OutputFile>..\..\$(IcuBinOutputDir)\icuin71.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\$(IcuLibOutputDir)\icuin.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\$(IcuLibOutputDir)\icuin.lib</ImportLibrary>
</Link>
diff --git a/Build/source/libs/icu/icu-src/source/i18n/i18n_uwp.vcxproj b/Build/source/libs/icu/icu-src/source/i18n/i18n_uwp.vcxproj
index c7358d72e59..ca0f335927b 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/i18n_uwp.vcxproj
+++ b/Build/source/libs/icu/icu-src/source/i18n/i18n_uwp.vcxproj
@@ -186,7 +186,7 @@
<ProgramDataBaseFileName>.\x86\ReleaseUWP/</ProgramDataBaseFileName>
</ClCompile>
<Link>
- <OutputFile>..\..\bin32uwp\icuin70.dll</OutputFile>
+ <OutputFile>..\..\bin32uwp\icuin71.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\lib32uwp\icuin.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\lib32uwp\icuin.lib</ImportLibrary>
<AdditionalDependencies>..\..\lib32uwp\icuuc.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -203,7 +203,7 @@
<ProgramDataBaseFileName>.\x86\DebugUWP/</ProgramDataBaseFileName>
</ClCompile>
<Link>
- <OutputFile>..\..\bin32uwp\icuin70d.dll</OutputFile>
+ <OutputFile>..\..\bin32uwp\icuin71d.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\lib32uwp\icuind.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\lib32uwp\icuind.lib</ImportLibrary>
<AdditionalDependencies>..\..\lib32uwp\icuucd.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -220,7 +220,7 @@
<ProgramDataBaseFileName>.\x64\ReleaseUWP/</ProgramDataBaseFileName>
</ClCompile>
<Link>
- <OutputFile>..\..\bin64uwp\icuin70.dll</OutputFile>
+ <OutputFile>..\..\bin64uwp\icuin71.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\lib64uwp\icuin.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\lib64uwp\icuin.lib</ImportLibrary>
<AdditionalDependencies>..\..\lib64uwp\icuuc.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -237,7 +237,7 @@
<ProgramDataBaseFileName>.\x64\DebugUWP/</ProgramDataBaseFileName>
</ClCompile>
<Link>
- <OutputFile>..\..\bin64uwp\icuin70d.dll</OutputFile>
+ <OutputFile>..\..\bin64uwp\icuin71d.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\lib64uwp\icuind.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\lib64uwp\icuind.lib</ImportLibrary>
<AdditionalDependencies>..\..\lib64uwp\icuucd.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -254,7 +254,7 @@
<ProgramDataBaseFileName>.\ARM\ReleaseUWP/</ProgramDataBaseFileName>
</ClCompile>
<Link>
- <OutputFile>..\..\binARMuwp\icuin70.dll</OutputFile>
+ <OutputFile>..\..\binARMuwp\icuin71.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\libARMuwp\icuin.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\libARMuwp\icuin.lib</ImportLibrary>
<AdditionalDependencies>..\..\libARMuwp\icuuc.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -271,7 +271,7 @@
<ProgramDataBaseFileName>.\ARM\DebugUWP/</ProgramDataBaseFileName>
</ClCompile>
<Link>
- <OutputFile>..\..\binARMuwp\icuin70d.dll</OutputFile>
+ <OutputFile>..\..\binARMuwp\icuin71d.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\libARMuwp\icuind.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\libARMuwp\icuind.lib</ImportLibrary>
<AdditionalDependencies>..\..\libARMuwp\icuucd.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -288,7 +288,7 @@
<ProgramDataBaseFileName>.\ARM64\ReleaseUWP/</ProgramDataBaseFileName>
</ClCompile>
<Link>
- <OutputFile>..\..\binARM64uwp\icuin70.dll</OutputFile>
+ <OutputFile>..\..\binARM64uwp\icuin71.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\libARM64uwp\icuin.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\libARM64uwp\icuin.lib</ImportLibrary>
<AdditionalDependencies>..\..\libARM64uwp\icuuc.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -305,7 +305,7 @@
<ProgramDataBaseFileName>.\ARM64\DebugUWP/</ProgramDataBaseFileName>
</ClCompile>
<Link>
- <OutputFile>..\..\binARM64uwp\icuin70d.dll</OutputFile>
+ <OutputFile>..\..\binARM64uwp\icuin71d.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\libARM64uwp\icuind.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\libARM64uwp\icuind.lib</ImportLibrary>
<AdditionalDependencies>..\..\libARM64uwp\icuucd.lib;%(AdditionalDependencies)</AdditionalDependencies>
diff --git a/Build/source/libs/icu/icu-src/source/i18n/measunit_extra.cpp b/Build/source/libs/icu/icu-src/source/i18n/measunit_extra.cpp
index 82811190079..2df9edee96a 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/measunit_extra.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/measunit_extra.cpp
@@ -615,7 +615,7 @@ private:
// Set to true when we've seen a "-per-" or a "per-", after which all units
// are in the denominator. Until we find an "-and-", at which point the
- // identifier is invalid pending TODO(CLDR-13700).
+ // identifier is invalid pending TODO(CLDR-13701).
bool fAfterPer = false;
Parser() : fSource(""), fTrie(u"") {}
@@ -669,7 +669,7 @@ private:
* dimensionality.
*
* Returns an error if we parse both compound units and "-and-", since mixed
- * compound units are not yet supported - TODO(CLDR-13700).
+ * compound units are not yet supported - TODO(CLDR-13701).
*
* @param result Will be overwritten by the result, if status shows success.
* @param sawAnd If an "-and-" was parsed prior to finding the "single
diff --git a/Build/source/libs/icu/icu-src/source/i18n/msgfmt.cpp b/Build/source/libs/icu/icu-src/source/i18n/msgfmt.cpp
index b8cb2e2ca56..13a5a089516 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/msgfmt.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/msgfmt.cpp
@@ -854,19 +854,21 @@ StringEnumeration*
MessageFormat::getFormatNames(UErrorCode& status) {
if (U_FAILURE(status)) return NULL;
- UVector *fFormatNames = new UVector(status);
+ LocalPointer<UVector> formatNames(new UVector(status), status);
if (U_FAILURE(status)) {
- status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
+ return nullptr;
}
- fFormatNames->setDeleter(uprv_deleteUObject);
+ formatNames->setDeleter(uprv_deleteUObject);
for (int32_t partIndex = 0; (partIndex = nextTopLevelArgStart(partIndex)) >= 0;) {
- fFormatNames->addElementX(new UnicodeString(getArgName(partIndex + 1)), status);
+ LocalPointer<UnicodeString> name(getArgName(partIndex + 1).clone(), status);
+ formatNames->adoptElement(name.orphan(), status);
+ if (U_FAILURE(status)) return nullptr;
}
- StringEnumeration* nameEnumerator = new FormatNameEnumeration(fFormatNames, status);
- return nameEnumerator;
+ LocalPointer<StringEnumeration> nameEnumerator(
+ new FormatNameEnumeration(std::move(formatNames), status), status);
+ return U_SUCCESS(status) ? nameEnumerator.orphan() : nullptr;
}
// -------------------------------------
@@ -1912,9 +1914,9 @@ void MessageFormat::DummyFormat::parseObject(const UnicodeString&,
}
-FormatNameEnumeration::FormatNameEnumeration(UVector *fNameList, UErrorCode& /*status*/) {
+FormatNameEnumeration::FormatNameEnumeration(LocalPointer<UVector> nameList, UErrorCode& /*status*/) {
pos=0;
- fFormatNames = fNameList;
+ fFormatNames = std::move(nameList);
}
const UnicodeString*
@@ -1936,7 +1938,6 @@ FormatNameEnumeration::count(UErrorCode& /*status*/) const {
}
FormatNameEnumeration::~FormatNameEnumeration() {
- delete fFormatNames;
}
MessageFormat::PluralSelectorProvider::PluralSelectorProvider(const MessageFormat &mf, UPluralType t)
diff --git a/Build/source/libs/icu/icu-src/source/i18n/msgfmt_impl.h b/Build/source/libs/icu/icu-src/source/i18n/msgfmt_impl.h
index 57988389132..80cb8a691eb 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/msgfmt_impl.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/msgfmt_impl.h
@@ -26,7 +26,7 @@ U_NAMESPACE_BEGIN
class FormatNameEnumeration : public StringEnumeration {
public:
- FormatNameEnumeration(UVector *fFormatNames, UErrorCode& status);
+ FormatNameEnumeration(LocalPointer<UVector> fFormatNames, UErrorCode& status);
virtual ~FormatNameEnumeration();
static UClassID U_EXPORT2 getStaticClassID(void);
virtual UClassID getDynamicClassID(void) const override;
@@ -35,7 +35,7 @@ public:
virtual int32_t count(UErrorCode& status) const override;
private:
int32_t pos;
- UVector *fFormatNames;
+ LocalPointer<UVector> fFormatNames;
};
U_NAMESPACE_END
diff --git a/Build/source/libs/icu/icu-src/source/i18n/number_affixutils.cpp b/Build/source/libs/icu/icu-src/source/i18n/number_affixutils.cpp
index f9c154c885c..5f5ff4c3a63 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/number_affixutils.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/number_affixutils.cpp
@@ -135,8 +135,7 @@ Field AffixUtils::getFieldForType(AffixPatternType type) {
case TYPE_PLUS_SIGN:
return {UFIELD_CATEGORY_NUMBER, UNUM_SIGN_FIELD};
case TYPE_APPROXIMATELY_SIGN:
- // TODO: Introduce a new field for the approximately sign?
- return {UFIELD_CATEGORY_NUMBER, UNUM_SIGN_FIELD};
+ return {UFIELD_CATEGORY_NUMBER, UNUM_APPROXIMATELY_SIGN_FIELD};
case TYPE_PERCENT:
return {UFIELD_CATEGORY_NUMBER, UNUM_PERCENT_FIELD};
case TYPE_PERMILLE:
diff --git a/Build/source/libs/icu/icu-src/source/i18n/number_compact.cpp b/Build/source/libs/icu/icu-src/source/i18n/number_compact.cpp
index 62692f444df..60cd7bedf66 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/number_compact.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/number_compact.cpp
@@ -157,8 +157,8 @@ void CompactData::getUniquePatterns(UVector &output, UErrorCode &status) const {
}
// The string was not found; add it to the UVector.
- // ANDY: This requires a const_cast. Why?
- output.addElementX(const_cast<UChar *>(pattern), status);
+ // Note: must cast off const from pattern to store it in a UVector, which expects (void *)
+ output.addElement(const_cast<UChar *>(pattern), status);
continue_outer:
continue;
diff --git a/Build/source/libs/icu/icu-src/source/i18n/number_decimalquantity.cpp b/Build/source/libs/icu/icu-src/source/i18n/number_decimalquantity.cpp
index 6a2847b1c18..b40e1276c35 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/number_decimalquantity.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/number_decimalquantity.cpp
@@ -181,20 +181,22 @@ uint64_t DecimalQuantity::getPositionFingerprint() const {
return fingerprint;
}
-void DecimalQuantity::roundToIncrement(double roundingIncrement, RoundingMode roundingMode,
- UErrorCode& status) {
+void DecimalQuantity::roundToIncrement(
+ uint64_t increment,
+ digits_t magnitude,
+ RoundingMode roundingMode,
+ UErrorCode& status) {
// Do not call this method with an increment having only a 1 or a 5 digit!
// Use a more efficient call to either roundToMagnitude() or roundToNickel().
// Check a few popular rounding increments; a more thorough check is in Java.
- U_ASSERT(roundingIncrement != 0.01);
- U_ASSERT(roundingIncrement != 0.05);
- U_ASSERT(roundingIncrement != 0.1);
- U_ASSERT(roundingIncrement != 0.5);
- U_ASSERT(roundingIncrement != 1);
- U_ASSERT(roundingIncrement != 5);
+ U_ASSERT(increment != 1);
+ U_ASSERT(increment != 5);
+ DecimalQuantity incrementDQ;
+ incrementDQ.setToLong(increment);
+ incrementDQ.adjustMagnitude(magnitude);
DecNum incrementDN;
- incrementDN.setTo(roundingIncrement, status);
+ incrementDQ.toDecNum(incrementDN, status);
if (U_FAILURE(status)) { return; }
// Divide this DecimalQuantity by the increment, round, then multiply back.
@@ -254,6 +256,12 @@ bool DecimalQuantity::adjustMagnitude(int32_t delta) {
return false;
}
+int32_t DecimalQuantity::adjustToZeroScale() {
+ int32_t retval = scale;
+ scale = 0;
+ return retval;
+}
+
double DecimalQuantity::getPluralOperand(PluralOperand operand) const {
// If this assertion fails, you need to call roundToInfinity() or some other rounding method.
// See the comment at the top of this file explaining the "isApproximate" field.
@@ -549,6 +557,65 @@ void DecimalQuantity::_setToDecNum(const DecNum& decnum, UErrorCode& status) {
}
}
+DecimalQuantity DecimalQuantity::fromExponentString(UnicodeString num, UErrorCode& status) {
+ if (num.indexOf(u'e') >= 0 || num.indexOf(u'c') >= 0
+ || num.indexOf(u'E') >= 0 || num.indexOf(u'C') >= 0) {
+ int32_t ePos = num.lastIndexOf('e');
+ if (ePos < 0) {
+ ePos = num.lastIndexOf('c');
+ }
+ if (ePos < 0) {
+ ePos = num.lastIndexOf('E');
+ }
+ if (ePos < 0) {
+ ePos = num.lastIndexOf('C');
+ }
+ int32_t expNumPos = ePos + 1;
+ UnicodeString exponentStr = num.tempSubString(expNumPos, num.length() - expNumPos);
+
+ // parse exponentStr into exponent, but note that parseAsciiInteger doesn't handle the minus sign
+ bool isExpStrNeg = num[expNumPos] == u'-';
+ int32_t exponentParsePos = isExpStrNeg ? 1 : 0;
+ int32_t exponent = ICU_Utility::parseAsciiInteger(exponentStr, exponentParsePos);
+ exponent = isExpStrNeg ? -exponent : exponent;
+
+ // Compute the decNumber representation
+ UnicodeString fractionStr = num.tempSubString(0, ePos);
+ CharString fracCharStr = CharString();
+ fracCharStr.appendInvariantChars(fractionStr, status);
+ DecNum decnum;
+ decnum.setTo(fracCharStr.toStringPiece(), status);
+
+ // Clear and set this DecimalQuantity instance
+ DecimalQuantity dq;
+ dq.setToDecNum(decnum, status);
+ int32_t numFracDigit = getVisibleFractionCount(fractionStr);
+ dq.setMinFraction(numFracDigit);
+ dq.adjustExponent(exponent);
+
+ return dq;
+ } else {
+ DecimalQuantity dq;
+ int numFracDigit = getVisibleFractionCount(num);
+
+ CharString numCharStr = CharString();
+ numCharStr.appendInvariantChars(num, status);
+ dq.setToDecNumber(numCharStr.toStringPiece(), status);
+
+ dq.setMinFraction(numFracDigit);
+ return dq;
+ }
+}
+
+int32_t DecimalQuantity::getVisibleFractionCount(UnicodeString value) {
+ int decimalPos = value.indexOf('.') + 1;
+ if (decimalPos == 0) {
+ return 0;
+ } else {
+ return value.length() - decimalPos;
+ }
+}
+
int64_t DecimalQuantity::toLong(bool truncateIfOverflow) const {
// NOTE: Call sites should be guarded by fitsInLong(), like this:
// if (dq.fitsInLong()) { /* use dq.toLong() */ } else { /* use some fallback */ }
@@ -948,6 +1015,44 @@ UnicodeString DecimalQuantity::toPlainString() const {
return sb;
}
+
+UnicodeString DecimalQuantity::toExponentString() const {
+ U_ASSERT(!isApproximate);
+ UnicodeString sb;
+ if (isNegative()) {
+ sb.append(u'-');
+ }
+
+ int32_t upper = scale + precision - 1;
+ int32_t lower = scale;
+ if (upper < lReqPos - 1) {
+ upper = lReqPos - 1;
+ }
+ if (lower > rReqPos) {
+ lower = rReqPos;
+ }
+ int32_t p = upper;
+ if (p < 0) {
+ sb.append(u'0');
+ }
+ for (; p >= 0; p--) {
+ sb.append(u'0' + getDigitPos(p - scale));
+ }
+ if (lower < 0) {
+ sb.append(u'.');
+ }
+ for(; p >= lower; p--) {
+ sb.append(u'0' + getDigitPos(p - scale));
+ }
+
+ if (exponent != 0) {
+ sb.append(u'c');
+ ICU_Utility::appendNumber(sb, exponent);
+ }
+
+ return sb;
+}
+
UnicodeString DecimalQuantity::toScientificString() const {
U_ASSERT(!isApproximate);
UnicodeString result;
diff --git a/Build/source/libs/icu/icu-src/source/i18n/number_decimalquantity.h b/Build/source/libs/icu/icu-src/source/i18n/number_decimalquantity.h
index 107c09a96a5..862addf5d6c 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/number_decimalquantity.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/number_decimalquantity.h
@@ -81,11 +81,15 @@ class U_I18N_API DecimalQuantity : public IFixedDecimal, public UMemory {
*
* <p>If rounding to a power of ten, use the more efficient {@link #roundToMagnitude} instead.
*
- * @param roundingIncrement The increment to which to round.
+ * @param increment The increment to which to round.
+ * @param magnitude The power of 10 to which to round.
* @param roundingMode The {@link RoundingMode} to use if rounding is necessary.
*/
- void roundToIncrement(double roundingIncrement, RoundingMode roundingMode,
- UErrorCode& status);
+ void roundToIncrement(
+ uint64_t increment,
+ digits_t magnitude,
+ RoundingMode roundingMode,
+ UErrorCode& status);
/** Removes all fraction digits. */
void truncate();
@@ -141,6 +145,13 @@ class U_I18N_API DecimalQuantity : public IFixedDecimal, public UMemory {
bool adjustMagnitude(int32_t delta);
/**
+ * Scales the number such that the least significant nonzero digit is at magnitude 0.
+ *
+ * @return The previous magnitude of the least significant digit.
+ */
+ int32_t adjustToZeroScale();
+
+ /**
* @return The power of ten corresponding to the most significant nonzero digit.
* The number must not be zero.
*/
@@ -234,6 +245,9 @@ class U_I18N_API DecimalQuantity : public IFixedDecimal, public UMemory {
/** Internal method if the caller already has a DecNum. */
DecimalQuantity &setToDecNum(const DecNum& n, UErrorCode& status);
+ /** Returns a DecimalQuantity after parsing the input string. */
+ static DecimalQuantity fromExponentString(UnicodeString n, UErrorCode& status);
+
/**
* Appends a digit, optionally with one or more leading zeros, to the end of the value represented
* by this DecimalQuantity.
@@ -315,6 +329,10 @@ class U_I18N_API DecimalQuantity : public IFixedDecimal, public UMemory {
/** Returns the string without exponential notation. Slightly slower than toScientificString(). */
UnicodeString toPlainString() const;
+ /** Returns the string using ASCII digits and using exponential notation for non-zero
+ exponents, following the UTS 35 specification for plural rule samples. */
+ UnicodeString toExponentString() const;
+
/** Visible for testing */
inline bool isUsingBytes() { return usingBytes; }
@@ -518,6 +536,8 @@ class U_I18N_API DecimalQuantity : public IFixedDecimal, public UMemory {
void _setToDecNum(const DecNum& dn, UErrorCode& status);
+ static int32_t getVisibleFractionCount(UnicodeString value);
+
void convertToAccurateDouble();
/** Ensure that a byte array of at least 40 digits is allocated. */
diff --git a/Build/source/libs/icu/icu-src/source/i18n/number_longnames.cpp b/Build/source/libs/icu/icu-src/source/i18n/number_longnames.cpp
index 5a4cf6321c8..b4e96504ded 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/number_longnames.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/number_longnames.cpp
@@ -431,13 +431,33 @@ void getMeasureData(const Locale &locale,
subKey.append(unit.getType(), status);
subKey.append("/", status);
+ // Check if unitSubType is an alias or not.
+ LocalUResourceBundlePointer aliasBundle(ures_open(U_ICUDATA_ALIAS, "metadata", &status));
+
+ UErrorCode aliasStatus = status;
+ StackUResourceBundle aliasFillIn;
+ CharString aliasKey;
+ aliasKey.append("alias/unit/", aliasStatus);
+ aliasKey.append(unit.getSubtype(), aliasStatus);
+ aliasKey.append("/replacement", aliasStatus);
+ ures_getByKeyWithFallback(aliasBundle.getAlias(), aliasKey.data(), aliasFillIn.getAlias(),
+ &aliasStatus);
+ CharString unitSubType;
+ if (!U_FAILURE(aliasStatus)) {
+ // This means the subType is an alias. Then, replace unitSubType with the replacement.
+ auto replacement = ures_getUnicodeString(aliasFillIn.getAlias(), &status);
+ unitSubType.appendInvariantChars(replacement, status);
+ } else {
+ unitSubType.append(unit.getSubtype(), status);
+ }
+
// Map duration-year-person, duration-week-person, etc. to duration-year, duration-week, ...
// TODO(ICU-20400): Get duration-*-person data properly with aliases.
- int32_t subtypeLen = static_cast<int32_t>(uprv_strlen(unit.getSubtype()));
- if (subtypeLen > 7 && uprv_strcmp(unit.getSubtype() + subtypeLen - 7, "-person") == 0) {
- subKey.append({unit.getSubtype(), subtypeLen - 7}, status);
+ int32_t subtypeLen = static_cast<int32_t>(uprv_strlen(unitSubType.data()));
+ if (subtypeLen > 7 && uprv_strcmp(unitSubType.data() + subtypeLen - 7, "-person") == 0) {
+ subKey.append({unitSubType.data(), subtypeLen - 7}, status);
} else {
- subKey.append({unit.getSubtype(), subtypeLen}, status);
+ subKey.append({unitSubType.data(), subtypeLen}, status);
}
if (width != UNUM_UNIT_WIDTH_FULL_NAME) {
diff --git a/Build/source/libs/icu/icu-src/source/i18n/number_mapper.cpp b/Build/source/libs/icu/icu-src/source/i18n/number_mapper.cpp
index 2d4d47a094d..350c431dfdd 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/number_mapper.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/number_mapper.cpp
@@ -134,7 +134,8 @@ MacroProps NumberPropertyMapper::oldToNew(const DecimalFormatProperties& propert
if (PatternStringUtils::ignoreRoundingIncrement(roundingIncrement, maxFrac)) {
precision = Precision::constructFraction(minFrac, maxFrac);
} else {
- precision = Precision::constructIncrement(roundingIncrement, minFrac);
+ // Convert the double increment to an integer increment
+ precision = Precision::increment(roundingIncrement).withMinFraction(minFrac);
}
} else if (explicitMinMaxSig) {
minSig = minSig < 1 ? 1 : minSig > kMaxIntFracSig ? kMaxIntFracSig : minSig;
@@ -293,9 +294,14 @@ MacroProps NumberPropertyMapper::oldToNew(const DecimalFormatProperties& propert
} else if (rounding_.fType == Precision::PrecisionType::RND_INCREMENT
|| rounding_.fType == Precision::PrecisionType::RND_INCREMENT_ONE
|| rounding_.fType == Precision::PrecisionType::RND_INCREMENT_FIVE) {
- increment_ = rounding_.fUnion.increment.fIncrement;
minFrac_ = rounding_.fUnion.increment.fMinFrac;
+ // If incrementRounding is used, maxFrac is set equal to minFrac
maxFrac_ = rounding_.fUnion.increment.fMinFrac;
+ // Convert the integer increment to a double
+ DecimalQuantity dq;
+ dq.setToLong(rounding_.fUnion.increment.fIncrement);
+ dq.adjustMagnitude(rounding_.fUnion.increment.fIncrementMagnitude);
+ increment_ = dq.toDouble();
} else if (rounding_.fType == Precision::PrecisionType::RND_SIGNIFICANT) {
minSig_ = rounding_.fUnion.fracSig.fMinSig;
maxSig_ = rounding_.fUnion.fracSig.fMaxSig;
diff --git a/Build/source/libs/icu/icu-src/source/i18n/number_output.cpp b/Build/source/libs/icu/icu-src/source/i18n/number_output.cpp
index 2c2c25eaedb..78006da8c42 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/number_output.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/number_output.cpp
@@ -39,6 +39,49 @@ MeasureUnit FormattedNumber::getOutputUnit(UErrorCode& status) const {
return fData->outputUnit;
}
+NounClass FormattedNumber::getNounClass(UErrorCode &status) const {
+ UPRV_FORMATTED_VALUE_METHOD_GUARD(NounClass::OTHER);
+ const char *nounClass = fData->gender;
+
+ // if it is not exist, return `OTHER`
+ if (uprv_strcmp(nounClass, "") == 0) {
+ return NounClass::OTHER;
+ }
+
+ if (uprv_strcmp(nounClass, "neuter") == 0) {
+ return NounClass::NEUTER;
+ }
+
+ if (uprv_strcmp(nounClass, "feminine") == 0) {
+ return NounClass::FEMININE;
+ }
+
+ if (uprv_strcmp(nounClass, "masculine") == 0) {
+ return NounClass::MASCULINE;
+ }
+
+ if (uprv_strcmp(nounClass, "animate") == 0) {
+ return NounClass::ANIMATE;
+ }
+
+ if (uprv_strcmp(nounClass, "inanimate") == 0) {
+ return NounClass::INANIMATE;
+ }
+
+ if (uprv_strcmp(nounClass, "personal") == 0) {
+ return NounClass::PERSONAL;
+ }
+
+ if (uprv_strcmp(nounClass, "common") == 0) {
+ return NounClass::COMMON;
+ }
+
+ // In case there is no matching, this means there are noun classes
+ // that are not supported yet.
+ status = U_INTERNAL_PROGRAM_ERROR;
+ return NounClass::OTHER;
+}
+
const char *FormattedNumber::getGender(UErrorCode &status) const {
UPRV_FORMATTED_VALUE_METHOD_GUARD("")
return fData->gender;
diff --git a/Build/source/libs/icu/icu-src/source/i18n/number_patternstring.cpp b/Build/source/libs/icu/icu-src/source/i18n/number_patternstring.cpp
index e819d39e967..2738895d8ad 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/number_patternstring.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/number_patternstring.cpp
@@ -750,7 +750,7 @@ UnicodeString PatternStringUtils::propertiesToPatternString(const DecimalFormatP
int32_t groupingLength = grouping1 + grouping2 + 1;
// Figure out the digits we need to put in the pattern.
- double roundingInterval = properties.roundingIncrement;
+ double increment = properties.roundingIncrement;
UnicodeString digitsString;
int32_t digitsStringScale = 0;
if (maxSig != uprv_min(dosMax, -1)) {
@@ -761,14 +761,14 @@ UnicodeString PatternStringUtils::propertiesToPatternString(const DecimalFormatP
while (digitsString.length() < maxSig) {
digitsString.append(u'#');
}
- } else if (roundingInterval != 0.0 && !ignoreRoundingIncrement(roundingInterval,maxFrac)) {
- // Rounding Interval.
- digitsStringScale = -roundingutils::doubleFractionLength(roundingInterval, nullptr);
- // TODO: Check for DoS here?
+ } else if (increment != 0.0 && !ignoreRoundingIncrement(increment,maxFrac)) {
+ // Rounding Increment.
DecimalQuantity incrementQuantity;
- incrementQuantity.setToDouble(roundingInterval);
+ incrementQuantity.setToDouble(increment);
+ incrementQuantity.roundToInfinity();
+ digitsStringScale = incrementQuantity.getLowerDisplayMagnitude();
incrementQuantity.adjustMagnitude(-digitsStringScale);
- incrementQuantity.roundToMagnitude(0, kDefaultMode, status);
+ incrementQuantity.setMinInteger(minInt - digitsStringScale);
UnicodeString str = incrementQuantity.toPlainString();
if (str.charAt(0) == u'-') {
// TODO: Unsupported operation exception or fail silently?
diff --git a/Build/source/libs/icu/icu-src/source/i18n/number_rounding.cpp b/Build/source/libs/icu/icu-src/source/i18n/number_rounding.cpp
index 877df63c8f6..a9b3f16c050 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/number_rounding.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/number_rounding.cpp
@@ -36,27 +36,24 @@ void number::impl::parseIncrementOption(const StringSegment &segment,
// Utilize DecimalQuantity/decNumber to parse this for us.
DecimalQuantity dq;
UErrorCode localStatus = U_ZERO_ERROR;
- DecNum decnum;
- decnum.setTo({buffer.data(), buffer.length()}, localStatus);
- dq.setToDecNum(decnum, localStatus);
- if (U_FAILURE(localStatus) || decnum.isSpecial()) {
+ dq.setToDecNumber({buffer.data(), buffer.length()}, localStatus);
+ if (U_FAILURE(localStatus) || dq.isNaN() || dq.isInfinite()) {
// throw new SkeletonSyntaxException("Invalid rounding increment", segment, e);
status = U_NUMBER_SKELETON_SYNTAX_ERROR;
return;
}
- double increment = dq.toDouble();
-
- // We also need to figure out how many digits. Do a brute force string operation.
- int decimalOffset = 0;
- while (decimalOffset < segment.length() && segment.charAt(decimalOffset) != '.') {
- decimalOffset++;
- }
- if (decimalOffset == segment.length()) {
- outPrecision = Precision::increment(increment);
- } else {
- int32_t fractionLength = segment.length() - decimalOffset - 1;
- outPrecision = Precision::increment(increment).withMinFraction(fractionLength);
+ // Now we break apart the number into a mantissa and exponent (magnitude).
+ int32_t magnitude = dq.adjustToZeroScale();
+ // setToDecNumber drops trailing zeros, so we search for the '.' manually.
+ for (int32_t i=0; i<buffer.length(); i++) {
+ if (buffer[i] == '.') {
+ int32_t newMagnitude = i - buffer.length() + 1;
+ dq.adjustMagnitude(magnitude - newMagnitude);
+ magnitude = newMagnitude;
+ break;
+ }
}
+ outPrecision = Precision::incrementExact(dq.toLong(), magnitude);
}
namespace {
@@ -94,34 +91,6 @@ int32_t getDisplayMagnitudeSignificant(const DecimalQuantity &value, int minSig)
MultiplierProducer::~MultiplierProducer() = default;
-digits_t roundingutils::doubleFractionLength(double input, int8_t* singleDigit) {
- char buffer[DoubleToStringConverter::kBase10MaximalLength + 1];
- bool sign; // unused; always positive
- int32_t length;
- int32_t point;
- DoubleToStringConverter::DoubleToAscii(
- input,
- DoubleToStringConverter::DtoaMode::SHORTEST,
- 0,
- buffer,
- sizeof(buffer),
- &sign,
- &length,
- &point
- );
-
- if (singleDigit == nullptr) {
- // no-op
- } else if (length == 1) {
- *singleDigit = buffer[0] - '0';
- } else {
- *singleDigit = -1;
- }
-
- return static_cast<digits_t>(length - point);
-}
-
-
Precision Precision::unlimited() {
return Precision(RND_NONE, {});
}
@@ -204,7 +173,19 @@ Precision Precision::trailingZeroDisplay(UNumberTrailingZeroDisplay trailingZero
IncrementPrecision Precision::increment(double roundingIncrement) {
if (roundingIncrement > 0.0) {
- return constructIncrement(roundingIncrement, 0);
+ DecimalQuantity dq;
+ dq.setToDouble(roundingIncrement);
+ dq.roundToInfinity();
+ int32_t magnitude = dq.adjustToZeroScale();
+ return constructIncrement(dq.toLong(), magnitude);
+ } else {
+ return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
+ }
+}
+
+IncrementPrecision Precision::incrementExact(uint64_t mantissa, int16_t magnitude) {
+ if (mantissa > 0.0) {
+ return constructIncrement(mantissa, magnitude);
} else {
return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
@@ -226,7 +207,8 @@ Precision FractionPrecision::withSignificantDigits(
*this,
minSignificantDigits,
maxSignificantDigits,
- priority);
+ priority,
+ false);
} else {
return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
@@ -239,7 +221,8 @@ Precision FractionPrecision::withMinDigits(int32_t minSignificantDigits) const {
*this,
1,
minSignificantDigits,
- UNUM_ROUNDING_PRIORITY_RELAXED);
+ UNUM_ROUNDING_PRIORITY_RELAXED,
+ true);
} else {
return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
@@ -251,7 +234,8 @@ Precision FractionPrecision::withMaxDigits(int32_t maxSignificantDigits) const {
return constructFractionSignificant(*this,
1,
maxSignificantDigits,
- UNUM_ROUNDING_PRIORITY_STRICT);
+ UNUM_ROUNDING_PRIORITY_STRICT,
+ true);
} else {
return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
@@ -266,8 +250,8 @@ Precision Precision::withCurrency(const CurrencyUnit &currency, UErrorCode &stat
int32_t minMaxFrac = ucurr_getDefaultFractionDigitsForUsage(
isoCode, fUnion.currencyUsage, &status);
Precision retval = (increment != 0.0)
- ? static_cast<Precision>(constructIncrement(increment, minMaxFrac))
- : static_cast<Precision>(constructFraction(minMaxFrac, minMaxFrac));
+ ? Precision::increment(increment)
+ : static_cast<Precision>(Precision::fixedFraction(minMaxFrac));
retval.fTrailingZeroDisplay = fTrailingZeroDisplay;
return retval;
}
@@ -285,7 +269,9 @@ Precision CurrencyPrecision::withCurrency(const CurrencyUnit &currency) const {
Precision IncrementPrecision::withMinFraction(int32_t minFrac) const {
if (fType == RND_ERROR) { return *this; } // no-op in error state
if (minFrac >= 0 && minFrac <= kMaxIntFracSig) {
- return constructIncrement(fUnion.increment.fIncrement, minFrac);
+ IncrementPrecision copy = *this;
+ copy.fUnion.increment.fMinFrac = minFrac;
+ return copy;
} else {
return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
}
@@ -318,35 +304,34 @@ Precision::constructFractionSignificant(
const FractionPrecision &base,
int32_t minSig,
int32_t maxSig,
- UNumberRoundingPriority priority) {
+ UNumberRoundingPriority priority,
+ bool retain) {
FractionSignificantSettings settings = base.fUnion.fracSig;
settings.fMinSig = static_cast<digits_t>(minSig);
settings.fMaxSig = static_cast<digits_t>(maxSig);
settings.fPriority = priority;
+ settings.fRetain = retain;
PrecisionUnion union_;
union_.fracSig = settings;
return {RND_FRACTION_SIGNIFICANT, union_};
}
-IncrementPrecision Precision::constructIncrement(double increment, int32_t minFrac) {
+IncrementPrecision Precision::constructIncrement(uint64_t increment, digits_t magnitude) {
IncrementSettings settings;
// Note: For number formatting, fIncrement is used for RND_INCREMENT but not
// RND_INCREMENT_ONE or RND_INCREMENT_FIVE. However, fIncrement is used in all
// three when constructing a skeleton.
settings.fIncrement = increment;
- settings.fMinFrac = static_cast<digits_t>(minFrac);
- // One of the few pre-computed quantities:
- // Note: it is possible for minFrac to be more than maxFrac... (misleading)
- int8_t singleDigit;
- settings.fMaxFrac = roundingutils::doubleFractionLength(increment, &singleDigit);
+ settings.fIncrementMagnitude = magnitude;
+ settings.fMinFrac = magnitude > 0 ? 0 : -magnitude;
PrecisionUnion union_;
union_.increment = settings;
- if (singleDigit == 1) {
+ if (increment == 1) {
// NOTE: In C++, we must return the correct value type with the correct union.
// It would be invalid to return a RND_FRACTION here because the methods on the
// IncrementPrecision type assume that the union is backed by increment data.
return {RND_INCREMENT_ONE, union_};
- } else if (singleDigit == 5) {
+ } else if (increment == 5) {
return {RND_INCREMENT_FIVE, union_};
} else {
return {RND_INCREMENT, union_};
@@ -457,6 +442,23 @@ void RoundingImpl::apply(impl::DecimalQuantity &value, UErrorCode& status) const
break;
case Precision::RND_FRACTION_SIGNIFICANT: {
+ // From ECMA-402:
+ /*
+ Let sResult be ToRawPrecision(...).
+ Let fResult be ToRawFixed(...).
+ If intlObj.[[RoundingType]] is morePrecision, then
+ If sResult.[[RoundingMagnitude]] ≤ fResult.[[RoundingMagnitude]], then
+ Let result be sResult.
+ Else,
+ Let result be fResult.
+ Else,
+ Assert: intlObj.[[RoundingType]] is lessPrecision.
+ If sResult.[[RoundingMagnitude]] ≤ fResult.[[RoundingMagnitude]], then
+ Let result be fResult.
+ Else,
+ Let result be sResult.
+ */
+
int32_t roundingMag1 = getRoundingMagnitudeFraction(fPrecision.fUnion.fracSig.fMaxFrac);
int32_t roundingMag2 = getRoundingMagnitudeSignificant(value, fPrecision.fUnion.fracSig.fMaxSig);
int32_t roundingMag;
@@ -465,11 +467,35 @@ void RoundingImpl::apply(impl::DecimalQuantity &value, UErrorCode& status) const
} else {
roundingMag = uprv_max(roundingMag1, roundingMag2);
}
- value.roundToMagnitude(roundingMag, fRoundingMode, status);
+ if (!value.isZeroish()) {
+ int32_t upperMag = value.getMagnitude();
+ value.roundToMagnitude(roundingMag, fRoundingMode, status);
+ if (!value.isZeroish() && value.getMagnitude() != upperMag && roundingMag1 == roundingMag2) {
+ // roundingMag2 needs to be the magnitude after rounding
+ roundingMag2 += 1;
+ }
+ }
int32_t displayMag1 = getDisplayMagnitudeFraction(fPrecision.fUnion.fracSig.fMinFrac);
int32_t displayMag2 = getDisplayMagnitudeSignificant(value, fPrecision.fUnion.fracSig.fMinSig);
- int32_t displayMag = uprv_min(displayMag1, displayMag2);
+ int32_t displayMag;
+ if (fPrecision.fUnion.fracSig.fRetain) {
+ // withMinDigits + withMaxDigits
+ displayMag = uprv_min(displayMag1, displayMag2);
+ } else if (fPrecision.fUnion.fracSig.fPriority == UNUM_ROUNDING_PRIORITY_RELAXED) {
+ if (roundingMag2 <= roundingMag1) {
+ displayMag = displayMag2;
+ } else {
+ displayMag = displayMag1;
+ }
+ } else {
+ U_ASSERT(fPrecision.fUnion.fracSig.fPriority == UNUM_ROUNDING_PRIORITY_STRICT);
+ if (roundingMag2 <= roundingMag1) {
+ displayMag = displayMag1;
+ } else {
+ displayMag = displayMag2;
+ }
+ }
resolvedMinFraction = uprv_max(0, -displayMag);
break;
@@ -478,6 +504,7 @@ void RoundingImpl::apply(impl::DecimalQuantity &value, UErrorCode& status) const
case Precision::RND_INCREMENT:
value.roundToIncrement(
fPrecision.fUnion.increment.fIncrement,
+ fPrecision.fUnion.increment.fIncrementMagnitude,
fRoundingMode,
status);
resolvedMinFraction = fPrecision.fUnion.increment.fMinFrac;
@@ -485,7 +512,7 @@ void RoundingImpl::apply(impl::DecimalQuantity &value, UErrorCode& status) const
case Precision::RND_INCREMENT_ONE:
value.roundToMagnitude(
- -fPrecision.fUnion.increment.fMaxFrac,
+ fPrecision.fUnion.increment.fIncrementMagnitude,
fRoundingMode,
status);
resolvedMinFraction = fPrecision.fUnion.increment.fMinFrac;
@@ -493,7 +520,7 @@ void RoundingImpl::apply(impl::DecimalQuantity &value, UErrorCode& status) const
case Precision::RND_INCREMENT_FIVE:
value.roundToNickel(
- -fPrecision.fUnion.increment.fMaxFrac,
+ fPrecision.fUnion.increment.fIncrementMagnitude,
fRoundingMode,
status);
resolvedMinFraction = fPrecision.fUnion.increment.fMinFrac;
diff --git a/Build/source/libs/icu/icu-src/source/i18n/number_roundingutils.h b/Build/source/libs/icu/icu-src/source/i18n/number_roundingutils.h
index 06fadd29fd5..66571272545 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/number_roundingutils.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/number_roundingutils.h
@@ -174,15 +174,6 @@ inline bool roundsAtMidpoint(int roundingMode) {
}
}
-/**
- * Computes the number of fraction digits in a double. Used for computing maxFrac for an increment.
- * Calls into the DoubleToStringConverter library to do so.
- *
- * @param singleDigit An output parameter; set to a number if that is the
- * only digit in the double, or -1 if there is more than one digit.
- */
-digits_t doubleFractionLength(double input, int8_t* singleDigit);
-
} // namespace roundingutils
diff --git a/Build/source/libs/icu/icu-src/source/i18n/number_skeletons.cpp b/Build/source/libs/icu/icu-src/source/i18n/number_skeletons.cpp
index de70c5cedff..c51831b6823 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/number_skeletons.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/number_skeletons.cpp
@@ -1344,8 +1344,9 @@ bool blueprint_helpers::parseFracSigOption(const StringSegment& segment, MacroPr
// @, @@, @@@
maxSig = minSig;
}
- UNumberRoundingPriority priority;
+ auto& oldPrecision = static_cast<const FractionPrecision&>(macros.precision);
if (offset < segment.length()) {
+ UNumberRoundingPriority priority;
if (maxSig == -1) {
// The wildcard character is not allowed with the priority annotation
status = U_NUMBER_SKELETON_SYNTAX_ERROR;
@@ -1367,22 +1368,19 @@ bool blueprint_helpers::parseFracSigOption(const StringSegment& segment, MacroPr
status = U_NUMBER_SKELETON_SYNTAX_ERROR;
return false;
}
+ macros.precision = oldPrecision.withSignificantDigits(minSig, maxSig, priority);
} else if (maxSig == -1) {
// withMinDigits
- maxSig = minSig;
- minSig = 1;
- priority = UNUM_ROUNDING_PRIORITY_RELAXED;
+ macros.precision = oldPrecision.withMinDigits(minSig);
} else if (minSig == 1) {
// withMaxDigits
- priority = UNUM_ROUNDING_PRIORITY_STRICT;
+ macros.precision = oldPrecision.withMaxDigits(maxSig);
} else {
// Digits options with both min and max sig require the priority option
status = U_NUMBER_SKELETON_SYNTAX_ERROR;
return false;
}
- auto& oldPrecision = static_cast<const FractionPrecision&>(macros.precision);
- macros.precision = oldPrecision.withSignificantDigits(minSig, maxSig, priority);
return true;
}
@@ -1399,12 +1397,16 @@ void blueprint_helpers::parseIncrementOption(const StringSegment &segment, Macro
number::impl::parseIncrementOption(segment, macros.precision, status);
}
-void blueprint_helpers::generateIncrementOption(double increment, int32_t minFrac, UnicodeString& sb,
- UErrorCode&) {
+void blueprint_helpers::generateIncrementOption(
+ uint32_t increment,
+ digits_t incrementMagnitude,
+ int32_t minFrac,
+ UnicodeString& sb,
+ UErrorCode&) {
// Utilize DecimalQuantity/double_conversion to format this for us.
DecimalQuantity dq;
- dq.setToDouble(increment);
- dq.roundToInfinity();
+ dq.setToLong(increment);
+ dq.adjustMagnitude(incrementMagnitude);
dq.setMinFraction(minFrac);
sb.append(dq.toPlainString());
}
@@ -1617,11 +1619,21 @@ bool GeneratorHelpers::precision(const MacroProps& macros, UnicodeString& sb, UE
const Precision::FractionSignificantSettings& impl = macros.precision.fUnion.fracSig;
blueprint_helpers::generateFractionStem(impl.fMinFrac, impl.fMaxFrac, sb, status);
sb.append(u'/');
- blueprint_helpers::generateDigitsStem(impl.fMinSig, impl.fMaxSig, sb, status);
- if (impl.fPriority == UNUM_ROUNDING_PRIORITY_RELAXED) {
- sb.append(u'r');
+ if (impl.fRetain) {
+ if (impl.fPriority == UNUM_ROUNDING_PRIORITY_RELAXED) {
+ // withMinDigits
+ blueprint_helpers::generateDigitsStem(impl.fMaxSig, -1, sb, status);
+ } else {
+ // withMaxDigits
+ blueprint_helpers::generateDigitsStem(1, impl.fMaxSig, sb, status);
+ }
} else {
- sb.append(u's');
+ blueprint_helpers::generateDigitsStem(impl.fMinSig, impl.fMaxSig, sb, status);
+ if (impl.fPriority == UNUM_ROUNDING_PRIORITY_RELAXED) {
+ sb.append(u'r');
+ } else {
+ sb.append(u's');
+ }
}
} else if (macros.precision.fType == Precision::RND_INCREMENT
|| macros.precision.fType == Precision::RND_INCREMENT_ONE
@@ -1630,6 +1642,7 @@ bool GeneratorHelpers::precision(const MacroProps& macros, UnicodeString& sb, UE
sb.append(u"precision-increment/", -1);
blueprint_helpers::generateIncrementOption(
impl.fIncrement,
+ impl.fIncrementMagnitude,
impl.fMinFrac,
sb,
status);
diff --git a/Build/source/libs/icu/icu-src/source/i18n/number_skeletons.h b/Build/source/libs/icu/icu-src/source/i18n/number_skeletons.h
index be41f1b3237..27f69cd48c3 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/number_skeletons.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/number_skeletons.h
@@ -286,7 +286,7 @@ bool parseTrailingZeroOption(const StringSegment& segment, MacroProps& macros, U
void parseIncrementOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status);
void
-generateIncrementOption(double increment, int32_t minFrac, UnicodeString& sb, UErrorCode& status);
+generateIncrementOption(uint32_t increment, digits_t incrementMagnitude, int32_t minFrac, UnicodeString& sb, UErrorCode& status);
void parseIntegerWidthOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status);
diff --git a/Build/source/libs/icu/icu-src/source/i18n/numsys.cpp b/Build/source/libs/icu/icu-src/source/i18n/numsys.cpp
index 44aaf8e2a5f..934149039c5 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/numsys.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/numsys.cpp
@@ -313,12 +313,7 @@ U_CFUNC void initNumsysNames(UErrorCode &status) {
}
const char *nsName = ures_getKey(nsCurrent.getAlias());
LocalPointer<UnicodeString> newElem(new UnicodeString(nsName, -1, US_INV), status);
- if (U_SUCCESS(status)) {
- numsysNames->addElementX(newElem.getAlias(), status);
- if (U_SUCCESS(status)) {
- newElem.orphan(); // on success, the numsysNames vector owns newElem.
- }
- }
+ numsysNames->adoptElement(newElem.orphan(), status);
}
ures_close(numberingSystemsInfo);
diff --git a/Build/source/libs/icu/icu-src/source/i18n/plurrule.cpp b/Build/source/libs/icu/icu-src/source/i18n/plurrule.cpp
index 336292c5458..7d1037f8bdd 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/plurrule.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/plurrule.cpp
@@ -1548,14 +1548,9 @@ PluralKeywordEnumeration::PluralKeywordEnumeration(RuleChain *header, UErrorCode
UBool addKeywordOther = TRUE;
RuleChain *node = header;
while (node != nullptr) {
- auto newElem = new UnicodeString(node->fKeyword);
- if (newElem == nullptr) {
- status = U_MEMORY_ALLOCATION_ERROR;
- return;
- }
- fKeywordNames.addElementX(newElem, status);
+ LocalPointer<UnicodeString> newElem(node->fKeyword.clone(), status);
+ fKeywordNames.adoptElement(newElem.orphan(), status);
if (U_FAILURE(status)) {
- delete newElem;
return;
}
if (0 == node->fKeyword.compare(PLURAL_KEYWORD_OTHER, 5)) {
@@ -1565,14 +1560,9 @@ PluralKeywordEnumeration::PluralKeywordEnumeration(RuleChain *header, UErrorCode
}
if (addKeywordOther) {
- auto newElem = new UnicodeString(PLURAL_KEYWORD_OTHER);
- if (newElem == nullptr) {
- status = U_MEMORY_ALLOCATION_ERROR;
- return;
- }
- fKeywordNames.addElementX(newElem, status);
+ LocalPointer<UnicodeString> newElem(new UnicodeString(PLURAL_KEYWORD_OTHER), status);
+ fKeywordNames.adoptElement(newElem.orphan(), status);
if (U_FAILURE(status)) {
- delete newElem;
return;
}
}
diff --git a/Build/source/libs/icu/icu-src/source/i18n/rbt_set.cpp b/Build/source/libs/icu/icu-src/source/i18n/rbt_set.cpp
index abc4413c2c6..6835c03a698 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/rbt_set.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/rbt_set.cpp
@@ -163,16 +163,13 @@ U_NAMESPACE_BEGIN
/**
* Construct a new empty rule set.
*/
-TransliterationRuleSet::TransliterationRuleSet(UErrorCode& status) : UMemory() {
- ruleVector = new UVector(&_deleteRule, NULL, status);
+TransliterationRuleSet::TransliterationRuleSet(UErrorCode& status) :
+ UMemory(), ruleVector(nullptr), rules(nullptr), index {}, maxContextLength(0) {
+ LocalPointer<UVector> lpRuleVector(new UVector(_deleteRule, nullptr, status), status);
if (U_FAILURE(status)) {
return;
}
- if (ruleVector == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- }
- rules = NULL;
- maxContextLength = 0;
+ ruleVector = lpRuleVector.orphan();
}
/**
@@ -180,27 +177,24 @@ TransliterationRuleSet::TransliterationRuleSet(UErrorCode& status) : UMemory() {
*/
TransliterationRuleSet::TransliterationRuleSet(const TransliterationRuleSet& other) :
UMemory(other),
- ruleVector(0),
- rules(0),
+ ruleVector(nullptr),
+ rules(nullptr),
maxContextLength(other.maxContextLength) {
int32_t i, len;
uprv_memcpy(index, other.index, sizeof(index));
UErrorCode status = U_ZERO_ERROR;
- ruleVector = new UVector(&_deleteRule, NULL, status);
- if (other.ruleVector != 0 && ruleVector != 0 && U_SUCCESS(status)) {
+ LocalPointer<UVector> lpRuleVector(new UVector(_deleteRule, nullptr, status), status);
+ if (U_FAILURE(status)) {
+ return;
+ }
+ ruleVector = lpRuleVector.orphan();
+ if (other.ruleVector != nullptr && U_SUCCESS(status)) {
len = other.ruleVector->size();
for (i=0; i<len && U_SUCCESS(status); ++i) {
- TransliterationRule *tempTranslitRule = new TransliterationRule(*(TransliterationRule*)other.ruleVector->elementAt(i));
- // Null pointer test
- if (tempTranslitRule == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- break;
- }
- ruleVector->addElementX(tempTranslitRule, status);
- if (U_FAILURE(status)) {
- break;
- }
+ LocalPointer<TransliterationRule> tempTranslitRule(
+ new TransliterationRule(*(TransliterationRule*)other.ruleVector->elementAt(i)), status);
+ ruleVector->adoptElement(tempTranslitRule.orphan(), status);
}
}
if (other.rules != 0 && U_SUCCESS(status)) {
@@ -247,11 +241,11 @@ int32_t TransliterationRuleSet::getMaximumContextLength(void) const {
*/
void TransliterationRuleSet::addRule(TransliterationRule* adoptedRule,
UErrorCode& status) {
+ LocalPointer<TransliterationRule> lpAdoptedRule(adoptedRule);
+ ruleVector->adoptElement(lpAdoptedRule.orphan(), status);
if (U_FAILURE(status)) {
- delete adoptedRule;
return;
}
- ruleVector->addElementX(adoptedRule, status);
int32_t len;
if ((len = adoptedRule->getContextLength()) > maxContextLength) {
@@ -316,7 +310,7 @@ void TransliterationRuleSet::freeze(UParseError& parseError,UErrorCode& status)
for (j=0; j<n; ++j) {
if (indexValue[j] >= 0) {
if (indexValue[j] == x) {
- v.addElementX(ruleVector->elementAt(j), status);
+ v.addElement(ruleVector->elementAt(j), status);
}
} else {
// If the indexValue is < 0, then the first key character is
@@ -325,13 +319,16 @@ void TransliterationRuleSet::freeze(UParseError& parseError,UErrorCode& status)
// rarely, so we seldom treat this code path.
TransliterationRule* r = (TransliterationRule*) ruleVector->elementAt(j);
if (r->matchesIndexValue((uint8_t)x)) {
- v.addElementX(r, status);
+ v.addElement(r, status);
}
}
}
}
uprv_free(indexValue);
index[256] = v.size();
+ if (U_FAILURE(status)) {
+ return;
+ }
/* Freeze things into an array.
*/
diff --git a/Build/source/libs/icu/icu-src/source/i18n/region.cpp b/Build/source/libs/icu/icu-src/source/i18n/region.cpp
index 2e013708bb8..277a22fd091 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/region.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/region.cpp
@@ -39,11 +39,6 @@
U_CDECL_BEGIN
-static void U_CALLCONV
-deleteRegion(void *obj) {
- delete (icu::Region *)obj;
-}
-
/**
* Cleanup callback func
*/
@@ -90,7 +85,8 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) {
LocalPointer<UVector> continents(new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status), status);
LocalPointer<UVector> groupings(new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status), status);
- allRegions = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status);
+ LocalPointer<UVector> lpAllRegions(new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status), status);
+ allRegions = lpAllRegions.orphan();
LocalUResourceBundlePointer metadata(ures_openDirect(NULL,"metadata",&status));
LocalUResourceBundlePointer metadataAlias(ures_getByKey(metadata.getAlias(),"alias",NULL,&status));
@@ -109,16 +105,17 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) {
LocalUResourceBundlePointer worldContainment(ures_getByKey(territoryContainment.getAlias(),"001",NULL,&status));
LocalUResourceBundlePointer groupingContainment(ures_getByKey(territoryContainment.getAlias(),"grouping",NULL,&status));
+ ucln_i18n_registerCleanup(UCLN_I18N_REGION, region_cleanup);
if (U_FAILURE(status)) {
return;
}
// now, initialize
- uhash_setValueDeleter(newRegionIDMap.getAlias(), deleteRegion); // regionIDMap owns objs
- uhash_setKeyDeleter(newRegionAliases.getAlias(), uprv_deleteUObject); // regionAliases owns the string keys
+ uhash_setValueDeleter(newRegionIDMap.getAlias(), uprv_deleteUObject); // regionIDMap owns objs
+ uhash_setKeyDeleter(newRegionAliases.getAlias(), uprv_deleteUObject); // regionAliases owns the string keys
- while ( ures_hasNext(regionRegular.getAlias()) ) {
+ while (U_SUCCESS(status) && ures_hasNext(regionRegular.getAlias())) {
UnicodeString regionName = ures_getNextUnicodeString(regionRegular.getAlias(),NULL,&status);
int32_t rangeMarkerLocation = regionName.indexOf(RANGE_MARKER);
UChar buf[6];
@@ -126,18 +123,18 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) {
if ( rangeMarkerLocation > 0 ) {
UChar endRange = regionName.charAt(rangeMarkerLocation+1);
buf[rangeMarkerLocation] = 0;
- while ( buf[rangeMarkerLocation-1] <= endRange ) {
+ while (U_SUCCESS(status) && buf[rangeMarkerLocation-1] <= endRange) {
LocalPointer<UnicodeString> newRegion(new UnicodeString(buf), status);
- allRegions->addElementX(newRegion.orphan(),status);
+ allRegions->adoptElement(newRegion.orphan(), status);
buf[rangeMarkerLocation-1]++;
}
} else {
LocalPointer<UnicodeString> newRegion(new UnicodeString(regionName), status);
- allRegions->addElementX(newRegion.orphan(),status);
+ allRegions->adoptElement(newRegion.orphan(), status);
}
}
- while ( ures_hasNext(regionMacro.getAlias()) ) {
+ while (U_SUCCESS(status) && ures_hasNext(regionMacro.getAlias())) {
UnicodeString regionName = ures_getNextUnicodeString(regionMacro.getAlias(),NULL,&status);
int32_t rangeMarkerLocation = regionName.indexOf(RANGE_MARKER);
UChar buf[6];
@@ -145,25 +142,29 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) {
if ( rangeMarkerLocation > 0 ) {
UChar endRange = regionName.charAt(rangeMarkerLocation+1);
buf[rangeMarkerLocation] = 0;
- while ( buf[rangeMarkerLocation-1] <= endRange ) {
+ while ( buf[rangeMarkerLocation-1] <= endRange && U_SUCCESS(status)) {
LocalPointer<UnicodeString> newRegion(new UnicodeString(buf), status);
- allRegions->addElementX(newRegion.orphan(),status);
+ allRegions->adoptElement(newRegion.orphan(),status);
buf[rangeMarkerLocation-1]++;
}
} else {
LocalPointer<UnicodeString> newRegion(new UnicodeString(regionName), status);
- allRegions->addElementX(newRegion.orphan(),status);
+ allRegions->adoptElement(newRegion.orphan(),status);
}
}
- while ( ures_hasNext(regionUnknown.getAlias()) ) {
- LocalPointer<UnicodeString> regionName (new UnicodeString(ures_getNextUnicodeString(regionUnknown.getAlias(),NULL,&status),status));
- allRegions->addElementX(regionName.orphan(),status);
+ while (U_SUCCESS(status) && ures_hasNext(regionUnknown.getAlias())) {
+ LocalPointer<UnicodeString> regionName (
+ new UnicodeString(ures_getNextUnicodeString(regionUnknown.getAlias(), nullptr, &status), status));
+ allRegions->adoptElement(regionName.orphan(),status);
}
- while ( ures_hasNext(worldContainment.getAlias()) ) {
+ while (U_SUCCESS(status) && ures_hasNext(worldContainment.getAlias())) {
UnicodeString *continentName = new UnicodeString(ures_getNextUnicodeString(worldContainment.getAlias(),NULL,&status));
- continents->addElementX(continentName,status);
+ continents->adoptElement(continentName,status);
+ }
+ if (U_FAILURE(status)) {
+ return;
}
for ( int32_t i = 0 ; i < allRegions->size() ; i++ ) {
@@ -191,22 +192,32 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) {
}
UResourceBundle *groupingBundle = nullptr;
- while ( ures_hasNext(groupingContainment.getAlias()) ) {
+ while (U_SUCCESS(status) && ures_hasNext(groupingContainment.getAlias())) {
groupingBundle = ures_getNextResource(groupingContainment.getAlias(), groupingBundle, &status);
if (U_FAILURE(status)) {
break;
}
UnicodeString *groupingName = new UnicodeString(ures_getKey(groupingBundle), -1, US_INV);
- groupings->addElementX(groupingName,status);
- Region *grouping = (Region *) uhash_get(newRegionIDMap.getAlias(),groupingName);
+ LocalPointer<UnicodeString> lpGroupingName(groupingName, status);
+ groupings->adoptElement(lpGroupingName.orphan(), status);
+ if (U_FAILURE(status)) {
+ break;
+ }
+ Region *grouping = (Region *) uhash_get(newRegionIDMap.getAlias(), groupingName);
if (grouping != NULL) {
- for (int32_t i = 0; i < ures_getSize(groupingBundle); i++) {
+ for (int32_t i = 0; i < ures_getSize(groupingBundle) && U_SUCCESS(status); i++) {
UnicodeString child = ures_getUnicodeStringByIndex(groupingBundle, i, &status);
if (U_SUCCESS(status)) {
if (grouping->containedRegions == NULL) {
- grouping->containedRegions = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status);
+ LocalPointer<UVector> lpContainedRegions(
+ new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status), status);
+ grouping->containedRegions = lpContainedRegions.orphan();
+ if (U_FAILURE(status)) {
+ break;
+ }
}
- grouping->containedRegions->addElementX(new UnicodeString(child), status);
+ LocalPointer<UnicodeString> lpChildCopy(new UnicodeString(child), status);
+ grouping->containedRegions->adoptElement(lpChildCopy.orphan(), status);
}
}
}
@@ -214,7 +225,7 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) {
ures_close(groupingBundle);
// Process the territory aliases
- while ( ures_hasNext(territoryAlias.getAlias()) ) {
+ while (U_SUCCESS(status) && ures_hasNext(territoryAlias.getAlias())) {
LocalUResourceBundlePointer res(ures_getNextResource(territoryAlias.getAlias(),NULL,&status));
const char *aliasFrom = ures_getKey(res.getAlias());
LocalPointer<UnicodeString> aliasFromStr(new UnicodeString(aliasFrom, -1, US_INV), status);
@@ -259,7 +270,7 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) {
}
UnicodeString currentRegion;
//currentRegion.remove(); TODO: was already 0 length?
- for (int32_t i = 0 ; i < aliasTo.length() ; i++ ) {
+ for (int32_t i = 0 ; i < aliasTo.length() && U_SUCCESS(status); i++ ) {
if ( aliasTo.charAt(i) != 0x0020 ) {
currentRegion.append(aliasTo.charAt(i));
}
@@ -267,7 +278,7 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) {
Region *target = (Region *)uhash_get(newRegionIDMap.getAlias(),(void *)&currentRegion);
if (target) {
LocalPointer<UnicodeString> preferredValue(new UnicodeString(target->idStr), status);
- aliasFromRegion->preferredValues->addElementX((void *)preferredValue.orphan(),status); // may add null if err
+ aliasFromRegion->preferredValues->adoptElement(preferredValue.orphan(),status); // may add null if err
}
currentRegion.remove();
}
@@ -276,9 +287,9 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) {
}
// Process the code mappings - This will allow us to assign numeric codes to most of the territories.
- while ( ures_hasNext(codeMappings.getAlias()) ) {
+ while (U_SUCCESS(status) && ures_hasNext(codeMappings.getAlias())) {
UResourceBundle *mapping = ures_getNextResource(codeMappings.getAlias(),NULL,&status);
- if ( ures_getType(mapping) == URES_ARRAY && ures_getSize(mapping) == 3) {
+ if (U_SUCCESS(status) && ures_getType(mapping) == URES_ARRAY && ures_getSize(mapping) == 3) {
UnicodeString codeMappingID = ures_getUnicodeStringByIndex(mapping,0,&status);
UnicodeString codeMappingNumber = ures_getUnicodeStringByIndex(mapping,1,&status);
UnicodeString codeMapping3Letter = ures_getUnicodeStringByIndex(mapping,2,&status);
@@ -356,15 +367,23 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) {
// Add the child region to the set of regions contained by the parent
if (parentRegion->containedRegions == NULL) {
- parentRegion->containedRegions = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status);
+ LocalPointer<UVector> lpContainedRegions(
+ new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status), status);
+ parentRegion->containedRegions = lpContainedRegions.orphan();
+ if (U_FAILURE(status)) {
+ return;
+ }
}
LocalPointer<UnicodeString> childStr(new UnicodeString(), status);
- if( U_FAILURE(status) ) {
+ if (U_FAILURE(status)) {
return; // error out
}
childStr->fastCopyFrom(childRegion->idStr);
- parentRegion->containedRegions->addElementX((void *)childStr.orphan(),status);
+ parentRegion->containedRegions->adoptElement(childStr.orphan(),status);
+ if (U_FAILURE(status)) {
+ return;
+ }
// Set the parent region to be the containing region of the child.
// Regions of type GROUPING can't be set as the parent, since another region
@@ -388,10 +407,9 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) {
if( U_FAILURE(status) ) {
return; // error out
}
- availableRegions[ar->fType]->addElementX((void *)arString.orphan(),status);
+ availableRegions[ar->fType]->adoptElement(arString.orphan(), status);
}
- ucln_i18n_registerCleanup(UCLN_I18N_REGION, region_cleanup);
// copy hashtables
numericCodeMap = newNumericCodeMap.orphan();
regionIDMap = newRegionIDMap.orphan();
@@ -402,6 +420,7 @@ void Region::cleanupRegionData() {
for (int32_t i = 0 ; i < URGN_LIMIT ; i++ ) {
if ( availableRegions[i] ) {
delete availableRegions[i];
+ availableRegions[i] = nullptr;
}
}
@@ -417,7 +436,6 @@ void Region::cleanupRegionData() {
uhash_close(regionIDMap);
}
if (allRegions) {
- allRegions->removeAllElements(); // Don't need the temporary list anymore.
delete allRegions;
allRegions = NULL;
}
@@ -615,33 +633,30 @@ Region::getContainedRegions(UErrorCode &status) const {
StringEnumeration*
Region::getContainedRegions( URegionType type, UErrorCode &status ) const {
umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status); // returns immediately if U_FAILURE(status)
+
+ UVector result(nullptr, uhash_compareChars, status);
+ LocalPointer<StringEnumeration> cr(getContainedRegions(status), status);
if (U_FAILURE(status)) {
- return NULL;
+ return nullptr;
}
- UVector *result = new UVector(NULL, uhash_compareChars, status);
-
- StringEnumeration *cr = getContainedRegions(status);
-
- for ( int32_t i = 0 ; i < cr->count(status) ; i++ ) {
- const char *regionId = cr->next(NULL,status);
- const Region *r = Region::getInstance(regionId,status);
+ const char *regionId;
+ while((regionId = cr->next(nullptr, status)) != nullptr && U_SUCCESS(status)) {
+ const Region *r = Region::getInstance(regionId, status);
if ( r->getType() == type) {
- result->addElementX((void *)&r->idStr,status);
+ result.addElement(const_cast<UnicodeString *>(&r->idStr), status);
} else {
- StringEnumeration *children = r->getContainedRegions(type, status);
- for ( int32_t j = 0 ; j < children->count(status) ; j++ ) {
- const char *id2 = children->next(NULL,status);
+ LocalPointer<StringEnumeration> children(r->getContainedRegions(type, status));
+ const char *id2;
+ while(U_SUCCESS(status) && ((id2 = children->next(nullptr, status)) != nullptr)) {
const Region *r2 = Region::getInstance(id2,status);
- result->addElementX((void *)&r2->idStr,status);
+ result.addElement(const_cast<UnicodeString *>(&r2->idStr), status);
}
- delete children;
}
}
- delete cr;
- StringEnumeration* resultEnumeration = new RegionNameEnumeration(result,status);
- delete result;
- return resultEnumeration;
+ LocalPointer<StringEnumeration> resultEnumeration(
+ new RegionNameEnumeration(&result, status), status);
+ return U_SUCCESS(status) ? resultEnumeration.orphan() : nullptr;
}
/**
@@ -706,18 +721,21 @@ Region::getType() const {
return fType;
}
-RegionNameEnumeration::RegionNameEnumeration(UVector *fNameList, UErrorCode& status) {
- pos=0;
- if (fNameList && U_SUCCESS(status)) {
- fRegionNames = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, fNameList->size(),status);
- for ( int32_t i = 0 ; i < fNameList->size() ; i++ ) {
- UnicodeString* this_region_name = (UnicodeString *)fNameList->elementAt(i);
- UnicodeString* new_region_name = new UnicodeString(*this_region_name);
- fRegionNames->addElementX((void *)new_region_name,status);
+RegionNameEnumeration::RegionNameEnumeration(UVector *nameList, UErrorCode& status) :
+ pos(0), fRegionNames(nullptr) {
+ // TODO: https://unicode-org.atlassian.net/browse/ICU-21829
+ // Is all of the copying going on here really necessary?
+ if (nameList && U_SUCCESS(status)) {
+ LocalPointer<UVector> regionNames(
+ new UVector(uprv_deleteUObject, uhash_compareUnicodeString, nameList->size(), status), status);
+ for ( int32_t i = 0 ; U_SUCCESS(status) && i < nameList->size() ; i++ ) {
+ UnicodeString* this_region_name = (UnicodeString *)nameList->elementAt(i);
+ LocalPointer<UnicodeString> new_region_name(new UnicodeString(*this_region_name), status);
+ regionNames->adoptElement(new_region_name.orphan(), status);
+ }
+ if (U_SUCCESS(status)) {
+ fRegionNames = regionNames.orphan();
}
- }
- else {
- fRegionNames = NULL;
}
}
diff --git a/Build/source/libs/icu/icu-src/source/i18n/region_impl.h b/Build/source/libs/icu/icu-src/source/i18n/region_impl.h
index 62acaa4511b..b6a281393f8 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/region_impl.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/region_impl.h
@@ -26,7 +26,11 @@ U_NAMESPACE_BEGIN
class RegionNameEnumeration : public StringEnumeration {
public:
- RegionNameEnumeration(UVector *fNameList, UErrorCode& status);
+ /**
+ * Construct an string enumeration over the supplied name list.
+ * Makes a copy of the supplied input name list; does not retain a reference to the original.
+ */
+ RegionNameEnumeration(UVector *nameList, UErrorCode& status);
virtual ~RegionNameEnumeration();
static UClassID U_EXPORT2 getStaticClassID(void);
virtual UClassID getDynamicClassID(void) const override;
diff --git a/Build/source/libs/icu/icu-src/source/i18n/smpdtfmt.cpp b/Build/source/libs/icu/icu-src/source/i18n/smpdtfmt.cpp
index 91748d82f9f..c1e943a0949 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/smpdtfmt.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/smpdtfmt.cpp
@@ -3792,6 +3792,9 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
src = &text;
}
parseInt(*src, number, pos, allowNegative,currentNumberFormat);
+ if (!isLenient() && pos.getIndex() < start + count) {
+ return -start;
+ }
if (pos.getIndex() != parseStart) {
int32_t val = number.getLong();
diff --git a/Build/source/libs/icu/icu-src/source/i18n/tmutfmt.cpp b/Build/source/libs/icu/icu-src/source/i18n/tmutfmt.cpp
index 057bb634ebb..f0335a81f50 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/tmutfmt.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/tmutfmt.cpp
@@ -320,14 +320,14 @@ void
TimeUnitFormat::setup(UErrorCode& err) {
initDataMembers(err);
- UVector pluralCounts(0, uhash_compareUnicodeString, 6, err);
+ UVector pluralCounts(nullptr, uhash_compareUnicodeString, 6, err);
LocalPointer<StringEnumeration> keywords(getPluralRules().getKeywords(err), err);
if (U_FAILURE(err)) {
return;
}
UnicodeString* pluralCount;
while ((pluralCount = const_cast<UnicodeString*>(keywords->snext(err))) != NULL) {
- pluralCounts.addElementX(pluralCount, err);
+ pluralCounts.addElement(pluralCount, err);
}
readFromCurrentLocale(UTMUTFMT_FULL_STYLE, gUnitsTag, pluralCounts, err);
checkConsistency(UTMUTFMT_FULL_STYLE, gUnitsTag, err);
diff --git a/Build/source/libs/icu/icu-src/source/i18n/tzfmt.cpp b/Build/source/libs/icu/icu-src/source/i18n/tzfmt.cpp
index ef3cfad80ce..9d046c30c8f 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/tzfmt.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/tzfmt.cpp
@@ -2459,7 +2459,7 @@ TimeZoneFormat::parseOffsetPattern(const UnicodeString& pattern, OffsetFields re
if (itemType != GMTOffsetField::TEXT) {
if (GMTOffsetField::isValid(itemType, itemLength)) {
GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, static_cast<uint8_t>(itemLength), status);
- result->addElementX(fld, status);
+ result->adoptElement(fld, status);
if (U_FAILURE(status)) {
break;
}
@@ -2485,7 +2485,7 @@ TimeZoneFormat::parseOffsetPattern(const UnicodeString& pattern, OffsetFields re
if (itemType == GMTOffsetField::TEXT) {
if (text.length() > 0) {
GMTOffsetField* textfld = GMTOffsetField::createText(text, status);
- result->addElementX(textfld, status);
+ result->adoptElement(textfld, status);
if (U_FAILURE(status)) {
break;
}
@@ -2494,7 +2494,7 @@ TimeZoneFormat::parseOffsetPattern(const UnicodeString& pattern, OffsetFields re
} else {
if (GMTOffsetField::isValid(itemType, itemLength)) {
GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, static_cast<uint8_t>(itemLength), status);
- result->addElementX(fld, status);
+ result->adoptElement(fld, status);
if (U_FAILURE(status)) {
break;
}
@@ -2512,7 +2512,7 @@ TimeZoneFormat::parseOffsetPattern(const UnicodeString& pattern, OffsetFields re
if (itemType != GMTOffsetField::TEXT) {
if (GMTOffsetField::isValid(itemType, itemLength)) {
GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, static_cast<uint8_t>(itemLength), status);
- result->addElementX(fld, status);
+ result->adoptElement(fld, status);
if (U_FAILURE(status)) {
break;
}
@@ -2532,12 +2532,12 @@ TimeZoneFormat::parseOffsetPattern(const UnicodeString& pattern, OffsetFields re
if (itemType == GMTOffsetField::TEXT) {
if (text.length() > 0) {
GMTOffsetField* tfld = GMTOffsetField::createText(text, status);
- result->addElementX(tfld, status);
+ result->adoptElement(tfld, status);
}
} else {
if (GMTOffsetField::isValid(itemType, itemLength)) {
GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, static_cast<uint8_t>(itemLength), status);
- result->addElementX(fld, status);
+ result->adoptElement(fld, status);
} else {
status = U_ILLEGAL_ARGUMENT_ERROR;
}
diff --git a/Build/source/libs/icu/icu-src/source/i18n/tzgnames.cpp b/Build/source/libs/icu/icu-src/source/i18n/tzgnames.cpp
index ed5f42d7bc1..d5ee45ced78 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/tzgnames.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/tzgnames.cpp
@@ -229,30 +229,27 @@ GNameSearchHandler::handleMatch(int32_t matchLength, const CharacterNode *node,
if ((nameinfo->type & fTypes) != 0) {
// matches a requested type
if (fResults == NULL) {
- fResults = new UVector(uprv_free, NULL, status);
- if (fResults == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
+ LocalPointer<UVector> lpResults(new UVector(uprv_free, NULL, status), status);
+ if (U_FAILURE(status)) {
+ return false;
}
+ fResults = lpResults.orphan();
}
- if (U_SUCCESS(status)) {
- U_ASSERT(fResults != NULL);
- GMatchInfo *gmatch = (GMatchInfo *)uprv_malloc(sizeof(GMatchInfo));
- if (gmatch == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- } else {
- // add the match to the vector
- gmatch->gnameInfo = nameinfo;
- gmatch->matchLength = matchLength;
- gmatch->timeType = UTZFMT_TIME_TYPE_UNKNOWN;
- fResults->addElementX(gmatch, status);
- if (U_FAILURE(status)) {
- uprv_free(gmatch);
- } else {
- if (matchLength > fMaxMatchLen) {
- fMaxMatchLen = matchLength;
- }
- }
- }
+ GMatchInfo *gmatch = (GMatchInfo *)uprv_malloc(sizeof(GMatchInfo));
+ if (gmatch == NULL) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return false;
+ }
+ // add the match to the vector
+ gmatch->gnameInfo = nameinfo;
+ gmatch->matchLength = matchLength;
+ gmatch->timeType = UTZFMT_TIME_TYPE_UNKNOWN;
+ fResults->adoptElement(gmatch, status);
+ if (U_FAILURE(status)) {
+ return false;
+ }
+ if (matchLength > fMaxMatchLen) {
+ fMaxMatchLen = matchLength;
}
}
}
diff --git a/Build/source/libs/icu/icu-src/source/i18n/tznames.cpp b/Build/source/libs/icu/icu-src/source/i18n/tznames.cpp
index 5c504d01cb6..781f1cc161f 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/tznames.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/tznames.cpp
@@ -414,15 +414,12 @@ TimeZoneNames::MatchInfoCollection::addZone(UTimeZoneNameType nameType, int32_t
if (U_FAILURE(status)) {
return;
}
- MatchInfo* matchInfo = new MatchInfo(nameType, matchLength, &tzID, NULL);
- if (matchInfo == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- return;
- }
- matches(status)->addElementX(matchInfo, status);
+ LocalPointer <MatchInfo> matchInfo(new MatchInfo(nameType, matchLength, &tzID, NULL), status);
+ UVector *matchesVec = matches(status);
if (U_FAILURE(status)) {
- delete matchInfo;
+ return;
}
+ matchesVec->adoptElement(matchInfo.orphan(), status);
}
void
@@ -431,15 +428,12 @@ TimeZoneNames::MatchInfoCollection::addMetaZone(UTimeZoneNameType nameType, int3
if (U_FAILURE(status)) {
return;
}
- MatchInfo* matchInfo = new MatchInfo(nameType, matchLength, NULL, &mzID);
- if (matchInfo == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- return;
- }
- matches(status)->addElementX(matchInfo, status);
+ LocalPointer<MatchInfo> matchInfo(new MatchInfo(nameType, matchLength, NULL, &mzID), status);
+ UVector *matchesVec = matches(status);
if (U_FAILURE(status)) {
- delete matchInfo;
+ return;
}
+ matchesVec->adoptElement(matchInfo.orphan(), status);
}
int32_t
diff --git a/Build/source/libs/icu/icu-src/source/i18n/tznames_impl.cpp b/Build/source/libs/icu/icu-src/source/i18n/tznames_impl.cpp
index d450b745648..69991dfef4b 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/tznames_impl.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/tznames_impl.cpp
@@ -148,19 +148,29 @@ CharacterNode::addValue(void *value, UObjectDeleter *valueDeleter, UErrorCode &s
if (!fHasValuesVector) {
// There is only one value so far, and not in a vector yet.
// Create a vector and add the old value.
- UVector *values = new UVector(valueDeleter, NULL, DEFAULT_CHARACTERNODE_CAPACITY, status);
+ LocalPointer<UVector> values(
+ new UVector(valueDeleter, NULL, DEFAULT_CHARACTERNODE_CAPACITY, status), status);
if (U_FAILURE(status)) {
if (valueDeleter) {
valueDeleter(value);
}
return;
}
- values->addElementX(fValues, status);
- fValues = values;
+ if (values->hasDeleter()) {
+ values->adoptElement(fValues, status);
+ } else {
+ values->addElement(fValues, status);
+ }
+ fValues = values.orphan();
fHasValuesVector = TRUE;
}
// Add the new value.
- ((UVector *)fValues)->addElementX(value, status);
+ UVector *values = (UVector *)fValues;
+ if (values->hasDeleter()) {
+ values->adoptElement(value, status);
+ } else {
+ values->addElement(value, status);
+ }
}
}
@@ -219,10 +229,8 @@ void
TextTrieMap::put(const UChar *key, void *value, UErrorCode &status) {
fIsEmpty = FALSE;
if (fLazyContents == NULL) {
- fLazyContents = new UVector(status);
- if (fLazyContents == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- }
+ LocalPointer<UVector> lpLazyContents(new UVector(status), status);
+ fLazyContents = lpLazyContents.orphan();
}
if (U_FAILURE(status)) {
if (fValueDeleter) {
@@ -233,7 +241,7 @@ TextTrieMap::put(const UChar *key, void *value, UErrorCode &status) {
U_ASSERT(fLazyContents != NULL);
UChar *s = const_cast<UChar *>(key);
- fLazyContents->addElementX(s, status);
+ fLazyContents->addElement(s, status);
if (U_FAILURE(status)) {
if (fValueDeleter) {
fValueDeleter((void*) key);
@@ -241,7 +249,7 @@ TextTrieMap::put(const UChar *key, void *value, UErrorCode &status) {
return;
}
- fLazyContents->addElementX(value, status);
+ fLazyContents->addElement(value, status);
}
void
@@ -854,7 +862,7 @@ class MetaZoneIDsEnumeration : public StringEnumeration {
public:
MetaZoneIDsEnumeration();
MetaZoneIDsEnumeration(const UVector& mzIDs);
- MetaZoneIDsEnumeration(UVector* mzIDs);
+ MetaZoneIDsEnumeration(LocalPointer<UVector> mzIDs);
virtual ~MetaZoneIDsEnumeration();
static UClassID U_EXPORT2 getStaticClassID(void);
virtual UClassID getDynamicClassID(void) const override;
@@ -865,7 +873,7 @@ private:
int32_t fLen;
int32_t fPos;
const UVector* fMetaZoneIDs;
- UVector *fLocalVector;
+ LocalPointer<UVector> fLocalVector;
};
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(MetaZoneIDsEnumeration)
@@ -879,8 +887,9 @@ MetaZoneIDsEnumeration::MetaZoneIDsEnumeration(const UVector& mzIDs)
fLen = fMetaZoneIDs->size();
}
-MetaZoneIDsEnumeration::MetaZoneIDsEnumeration(UVector *mzIDs)
-: fLen(0), fPos(0), fMetaZoneIDs(mzIDs), fLocalVector(mzIDs) {
+MetaZoneIDsEnumeration::MetaZoneIDsEnumeration(LocalPointer<UVector> mzIDs)
+: fLen(0), fPos(0), fMetaZoneIDs(nullptr), fLocalVector(std::move(mzIDs)) {
+ fMetaZoneIDs = fLocalVector.getAlias();
if (fMetaZoneIDs) {
fLen = fMetaZoneIDs->size();
}
@@ -906,9 +915,6 @@ MetaZoneIDsEnumeration::count(UErrorCode& /*status*/) const {
}
MetaZoneIDsEnumeration::~MetaZoneIDsEnumeration() {
- if (fLocalVector) {
- delete fLocalVector;
- }
}
@@ -1153,28 +1159,23 @@ TimeZoneNamesImpl::_getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCod
return new MetaZoneIDsEnumeration();
}
- MetaZoneIDsEnumeration *senum = NULL;
- UVector* mzIDs = new UVector(NULL, uhash_compareUChars, status);
- if (mzIDs == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- }
+ LocalPointer<MetaZoneIDsEnumeration> senum;
+ LocalPointer<UVector> mzIDs(new UVector(NULL, uhash_compareUChars, status), status);
if (U_SUCCESS(status)) {
- U_ASSERT(mzIDs != NULL);
+ U_ASSERT(mzIDs.isValid());
for (int32_t i = 0; U_SUCCESS(status) && i < mappings->size(); i++) {
OlsonToMetaMappingEntry *map = (OlsonToMetaMappingEntry *)mappings->elementAt(i);
const UChar *mzID = map->mzid;
if (!mzIDs->contains((void *)mzID)) {
- mzIDs->addElementX((void *)mzID, status);
+ mzIDs->addElement((void *)mzID, status);
}
}
if (U_SUCCESS(status)) {
- senum = new MetaZoneIDsEnumeration(mzIDs);
- } else {
- delete mzIDs;
+ senum.adoptInsteadAndCheckErrorCode(new MetaZoneIDsEnumeration(std::move(mzIDs)), status);
}
}
- return senum;
+ return U_SUCCESS(status) ? senum.orphan() : nullptr;
}
UnicodeString&
diff --git a/Build/source/libs/icu/icu-src/source/i18n/ucol.cpp b/Build/source/libs/icu/icu-src/source/i18n/ucol.cpp
index f59333ede3c..8e1df8d5577 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/ucol.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/ucol.cpp
@@ -96,12 +96,18 @@ ucol_safeClone(const UCollator *coll, void * /*stackBuffer*/, int32_t * pBufferS
if (newColl == NULL) {
*status = U_MEMORY_ALLOCATION_ERROR;
return nullptr;
- } else {
+ } else if (pBufferSize != NULL) {
*status = U_SAFECLONE_ALLOCATED_WARNING;
}
return newColl->toUCollator();
}
+U_CAPI UCollator* U_EXPORT2
+ucol_clone(const UCollator *coll, UErrorCode *status)
+{
+ return ucol_safeClone(coll, nullptr, nullptr, status);
+}
+
U_CAPI void U_EXPORT2
ucol_close(UCollator *coll)
{
diff --git a/Build/source/libs/icu/icu-src/source/i18n/udatpg.cpp b/Build/source/libs/icu/icu-src/source/i18n/udatpg.cpp
index 332636a9388..9e61a120768 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/udatpg.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/udatpg.cpp
@@ -210,12 +210,47 @@ udatpg_setDateTimeFormat(const UDateTimePatternGenerator *dtpg,
U_CAPI const UChar * U_EXPORT2
udatpg_getDateTimeFormat(const UDateTimePatternGenerator *dtpg,
int32_t *pLength) {
- const UnicodeString &result=((const DateTimePatternGenerator *)dtpg)->getDateTimeFormat();
- if(pLength!=NULL) {
+ UErrorCode status = U_ZERO_ERROR;
+ return udatpg_getDateTimeFormatForStyle(dtpg, UDAT_MEDIUM, pLength, &status);
+}
+
+U_CAPI void U_EXPORT2
+udatpg_setDateTimeFormatForStyle(UDateTimePatternGenerator *udtpg,
+ UDateFormatStyle style,
+ const UChar *dateTimeFormat, int32_t length,
+ UErrorCode *pErrorCode) {
+ if (U_FAILURE(*pErrorCode)) {
+ return;
+ } else if (dateTimeFormat==nullptr) {
+ *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+ return;
+ }
+ DateTimePatternGenerator *dtpg = reinterpret_cast<DateTimePatternGenerator *>(udtpg);
+ UnicodeString dtFormatString((UBool)(length<0), dateTimeFormat, length);
+ dtpg->setDateTimeFormat(style, dtFormatString, *pErrorCode);
+}
+
+U_CAPI const UChar* U_EXPORT2
+udatpg_getDateTimeFormatForStyle(const UDateTimePatternGenerator *udtpg,
+ UDateFormatStyle style, int32_t *pLength,
+ UErrorCode *pErrorCode) {
+ static const UChar emptyString[] = { (UChar)0 };
+ if (U_FAILURE(*pErrorCode)) {
+ if (pLength !=nullptr) {
+ *pLength = 0;
+ }
+ return emptyString;
+ }
+ const DateTimePatternGenerator *dtpg = reinterpret_cast<const DateTimePatternGenerator *>(udtpg);
+ const UnicodeString &result = dtpg->getDateTimeFormat(style, *pErrorCode);
+ if (pLength != nullptr) {
*pLength=result.length();
}
+ // Note: The UnicodeString for the dateTimeFormat string in the DateTimePatternGenerator
+ // was NUL-terminated what it was set, to avoid doing it here which could re-allocate
+ // the buffe and affect and cont references to the string or its buffer.
return result.getBuffer();
-}
+ }
U_CAPI void U_EXPORT2
udatpg_setDecimal(UDateTimePatternGenerator *dtpg,
diff --git a/Build/source/libs/icu/icu-src/source/i18n/unicode/basictz.h b/Build/source/libs/icu/icu-src/source/i18n/unicode/basictz.h
index 250ea309279..d9f85e45eef 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/unicode/basictz.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/unicode/basictz.h
@@ -152,17 +152,15 @@ public:
virtual void getSimpleRulesNear(UDate date, InitialTimeZoneRule*& initial,
AnnualTimeZoneRule*& std, AnnualTimeZoneRule*& dst, UErrorCode& status) const;
-#ifndef U_FORCE_HIDE_DRAFT_API
/**
* Get time zone offsets from local wall time.
- * @draft ICU 69
+ * @stable ICU 69
*/
virtual void getOffsetFromLocal(
UDate date, UTimeZoneLocalOption nonExistingTimeOpt,
UTimeZoneLocalOption duplicatedTimeOpt, int32_t& rawOffset,
int32_t& dstOffset, UErrorCode& status) const;
-#endif /* U_FORCE_HIDE_DRAFT_API */
#ifndef U_HIDE_INTERNAL_API
/**
diff --git a/Build/source/libs/icu/icu-src/source/i18n/unicode/dtptngen.h b/Build/source/libs/icu/icu-src/source/i18n/unicode/dtptngen.h
index 250a0e089fe..6be0e2a571c 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/unicode/dtptngen.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/unicode/dtptngen.h
@@ -311,6 +311,11 @@ public:
* for those two skeletons, so the result is put together with this pattern,
* resulting in "d-MMM h:mm".
*
+ * There are four DateTimeFormats in a DateTimePatternGenerator object,
+ * corresponding to date styles UDAT_FULL..UDAT_SHORT. This method sets
+ * all of them to the specified pattern. To set them individually, see
+ * setDateTimeFormat(UDateFormatStyle style, ...).
+ *
* @param dateTimeFormat
* message format pattern, here {1} will be replaced by the date
* pattern and {0} will be replaced by the time pattern.
@@ -320,11 +325,66 @@ public:
/**
* Getter corresponding to setDateTimeFormat.
+ *
+ * There are four DateTimeFormats in a DateTimePatternGenerator object,
+ * corresponding to date styles UDAT_FULL..UDAT_SHORT. This method gets
+ * the style for UDAT_MEDIUM (the default). To get them individually, see
+ * getDateTimeFormat(UDateFormatStyle style).
+ *
* @return DateTimeFormat.
* @stable ICU 3.8
*/
const UnicodeString& getDateTimeFormat() const;
+#if !UCONFIG_NO_FORMATTING
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * dateTimeFormats are message patterns used to compose combinations of date
+ * and time patterns. There are four length styles, corresponding to the
+ * inferred style of the date pattern; these are UDateFormatStyle values:
+ * - UDAT_FULL (for date pattern with weekday and long month), else
+ * - UDAT_LONG (for a date pattern with long month), else
+ * - UDAT_MEDIUM (for a date pattern with abbreviated month), else
+ * - UDAT_SHORT (for any other date pattern).
+ * For details on dateTimeFormats, see
+ * https://www.unicode.org/reports/tr35/tr35-dates.html#dateTimeFormats.
+ * The default pattern in the root locale for all styles is "{1} {0}".
+ *
+ * @param style
+ * one of DateFormat.FULL..DateFormat.SHORT. Error if out of range.
+ * @param dateTimeFormat
+ * the new dateTimeFormat to set for the the specified style
+ * @param status
+ * in/out parameter; if no failure status is already set,
+ * it will be set according to result of the function (e.g.
+ * U_ILLEGAL_ARGUMENT_ERROR for style out of range).
+ * @draft ICU 71
+ */
+ void setDateTimeFormat(UDateFormatStyle style, const UnicodeString& dateTimeFormat,
+ UErrorCode& status);
+
+ /**
+ * Getter corresponding to setDateTimeFormat.
+ *
+ * @param style
+ * one of UDAT_FULL..UDAT_SHORT. Error if out of range.
+ * @param status
+ * in/out parameter; if no failure status is already set,
+ * it will be set according to result of the function (e.g.
+ * U_ILLEGAL_ARGUMENT_ERROR for style out of range).
+ * @return
+ * the current dateTimeFormat for the the specified style, or
+ * empty string in case of error. The UnicodeString reference,
+ * or the contents of the string, may no longer be valid if
+ * setDateTimeFormat is called, or the DateTimePatternGenerator
+ * object is deleted.
+ * @draft ICU 71
+ */
+ const UnicodeString& getDateTimeFormat(UDateFormatStyle style,
+ UErrorCode& status) const;
+#endif /* U_HIDE_DRAFT_API */
+#endif /* #if !UCONFIG_NO_FORMATTING */
+
/**
* Return the best pattern matching the input skeleton. It is guaranteed to
* have all of the fields in the skeleton.
@@ -545,8 +605,7 @@ private:
*/
DateTimePatternGenerator& operator=(const DateTimePatternGenerator& other);
- // TODO(ticket:13619): re-enable when UDATPG_NARROW no longer in draft mode.
- // static const int32_t UDATPG_WIDTH_COUNT = UDATPG_NARROW + 1;
+ static const int32_t UDATPG_WIDTH_COUNT = UDATPG_NARROW + 1;
Locale pLocale; // pattern locale
FormatParser *fp;
@@ -554,9 +613,8 @@ private:
DistanceInfo *distanceInfo;
PatternMap *patternMap;
UnicodeString appendItemFormats[UDATPG_FIELD_COUNT];
- // TODO(ticket:13619): [3] -> UDATPG_WIDTH_COUNT
- UnicodeString fieldDisplayNames[UDATPG_FIELD_COUNT][3];
- UnicodeString dateTimeFormat;
+ UnicodeString fieldDisplayNames[UDATPG_FIELD_COUNT][UDATPG_WIDTH_COUNT];
+ UnicodeString dateTimeFormat[4];
UnicodeString decimal;
DateTimeMatcher *skipMatcher;
Hashtable *fAvailableFormatKeyHash;
diff --git a/Build/source/libs/icu/icu-src/source/i18n/unicode/measunit.h b/Build/source/libs/icu/icu-src/source/i18n/unicode/measunit.h
index 61da62e71f2..b7e8e1676a4 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/unicode/measunit.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/unicode/measunit.h
@@ -77,14 +77,13 @@ enum UMeasureUnitComplexity {
};
-#ifndef U_HIDE_DRAFT_API
/**
* Enumeration for SI and binary prefixes, e.g. "kilo-", "nano-", "mebi-".
*
* Enum values should be treated as opaque: use umeas_getPrefixPower() and
* umeas_getPrefixBase() to find their corresponding values.
*
- * @draft ICU 69
+ * @stable ICU 69
* @see umeas_getPrefixBase
* @see umeas_getPrefixPower
*/
@@ -96,14 +95,14 @@ typedef enum UMeasurePrefix {
* implementation detail and should not be relied upon: use
* umeas_getPrefixPower() to obtain meaningful values.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_ONE = 30 + 0,
/**
* SI prefix: yotta, 10^24.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_YOTTA = UMEASURE_PREFIX_ONE + 24,
@@ -119,133 +118,133 @@ typedef enum UMeasurePrefix {
/**
* SI prefix: zetta, 10^21.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_ZETTA = UMEASURE_PREFIX_ONE + 21,
/**
* SI prefix: exa, 10^18.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_EXA = UMEASURE_PREFIX_ONE + 18,
/**
* SI prefix: peta, 10^15.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_PETA = UMEASURE_PREFIX_ONE + 15,
/**
* SI prefix: tera, 10^12.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_TERA = UMEASURE_PREFIX_ONE + 12,
/**
* SI prefix: giga, 10^9.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_GIGA = UMEASURE_PREFIX_ONE + 9,
/**
* SI prefix: mega, 10^6.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_MEGA = UMEASURE_PREFIX_ONE + 6,
/**
* SI prefix: kilo, 10^3.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_KILO = UMEASURE_PREFIX_ONE + 3,
/**
* SI prefix: hecto, 10^2.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_HECTO = UMEASURE_PREFIX_ONE + 2,
/**
* SI prefix: deka, 10^1.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_DEKA = UMEASURE_PREFIX_ONE + 1,
/**
* SI prefix: deci, 10^-1.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_DECI = UMEASURE_PREFIX_ONE + -1,
/**
* SI prefix: centi, 10^-2.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_CENTI = UMEASURE_PREFIX_ONE + -2,
/**
* SI prefix: milli, 10^-3.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_MILLI = UMEASURE_PREFIX_ONE + -3,
/**
* SI prefix: micro, 10^-6.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_MICRO = UMEASURE_PREFIX_ONE + -6,
/**
* SI prefix: nano, 10^-9.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_NANO = UMEASURE_PREFIX_ONE + -9,
/**
* SI prefix: pico, 10^-12.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_PICO = UMEASURE_PREFIX_ONE + -12,
/**
* SI prefix: femto, 10^-15.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_FEMTO = UMEASURE_PREFIX_ONE + -15,
/**
* SI prefix: atto, 10^-18.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_ATTO = UMEASURE_PREFIX_ONE + -18,
/**
* SI prefix: zepto, 10^-21.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_ZEPTO = UMEASURE_PREFIX_ONE + -21,
/**
* SI prefix: yocto, 10^-24.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_YOCTO = UMEASURE_PREFIX_ONE + -24,
@@ -270,7 +269,7 @@ typedef enum UMeasurePrefix {
/**
* Binary prefix: kibi, 1024^1.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_KIBI = UMEASURE_PREFIX_INTERNAL_ONE_BIN + 1,
@@ -286,49 +285,49 @@ typedef enum UMeasurePrefix {
/**
* Binary prefix: mebi, 1024^2.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_MEBI = UMEASURE_PREFIX_INTERNAL_ONE_BIN + 2,
/**
* Binary prefix: gibi, 1024^3.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_GIBI = UMEASURE_PREFIX_INTERNAL_ONE_BIN + 3,
/**
* Binary prefix: tebi, 1024^4.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_TEBI = UMEASURE_PREFIX_INTERNAL_ONE_BIN + 4,
/**
* Binary prefix: pebi, 1024^5.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_PEBI = UMEASURE_PREFIX_INTERNAL_ONE_BIN + 5,
/**
* Binary prefix: exbi, 1024^6.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_EXBI = UMEASURE_PREFIX_INTERNAL_ONE_BIN + 6,
/**
* Binary prefix: zebi, 1024^7.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_ZEBI = UMEASURE_PREFIX_INTERNAL_ONE_BIN + 7,
/**
* Binary prefix: yobi, 1024^8.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UMEASURE_PREFIX_YOBI = UMEASURE_PREFIX_INTERNAL_ONE_BIN + 8,
@@ -347,7 +346,7 @@ typedef enum UMeasurePrefix {
* base is 10 for SI prefixes (kilo, micro) and 1024 for binary prefixes (kibi,
* mebi).
*
- * @draft ICU 69
+ * @stable ICU 69
*/
U_CAPI int32_t U_EXPORT2 umeas_getPrefixBase(UMeasurePrefix unitPrefix);
@@ -355,12 +354,10 @@ U_CAPI int32_t U_EXPORT2 umeas_getPrefixBase(UMeasurePrefix unitPrefix);
* Returns the exponent of the factor associated with the given unit prefix, for
* example 3 for kilo, -6 for micro, 1 for kibi, 2 for mebi, 3 for gibi.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
U_CAPI int32_t U_EXPORT2 umeas_getPrefixPower(UMeasurePrefix unitPrefix);
-#endif // U_HIDE_DRAFT_API
-
/**
* A unit such as length, mass, volume, currency, etc. A unit is
* coupled with a numeric amount to produce a Measure.
@@ -481,7 +478,6 @@ class U_I18N_API MeasureUnit: public UObject {
*/
UMeasureUnitComplexity getComplexity(UErrorCode& status) const;
-#ifndef U_HIDE_DRAFT_API
/**
* Creates a MeasureUnit which is this SINGLE unit augmented with the specified prefix.
* For example, UMEASURE_PREFIX_KILO for "kilo", or UMEASURE_PREFIX_KIBI for "kibi".
@@ -494,7 +490,7 @@ class U_I18N_API MeasureUnit: public UObject {
* @param prefix The prefix, from UMeasurePrefix.
* @param status Set if this is not a SINGLE unit or if another error occurs.
* @return A new SINGLE unit.
- * @draft ICU 69
+ * @stable ICU 69
*/
MeasureUnit withPrefix(UMeasurePrefix prefix, UErrorCode& status) const;
@@ -510,10 +506,9 @@ class U_I18N_API MeasureUnit: public UObject {
* @return The prefix of this SINGLE unit, from UMeasurePrefix.
* @see umeas_getPrefixBase
* @see umeas_getPrefixPower
- * @draft ICU 69
+ * @stable ICU 69
*/
UMeasurePrefix getPrefix(UErrorCode& status) const;
-#endif // U_HIDE_DRAFT_API
/**
* Creates a MeasureUnit which is this SINGLE unit augmented with the specified dimensionality
@@ -989,23 +984,21 @@ class U_I18N_API MeasureUnit: public UObject {
*/
static MeasureUnit getKarat();
-#ifndef U_HIDE_DRAFT_API
/**
* Returns by pointer, unit of concentr: milligram-ofglucose-per-deciliter.
* Caller owns returned value and must free it.
* Also see {@link #getMilligramOfglucosePerDeciliter()}.
* @param status ICU error code.
- * @draft ICU 69
+ * @stable ICU 69
*/
static MeasureUnit *createMilligramOfglucosePerDeciliter(UErrorCode &status);
/**
* Returns by value, unit of concentr: milligram-ofglucose-per-deciliter.
* Also see {@link #createMilligramOfglucosePerDeciliter()}.
- * @draft ICU 69
+ * @stable ICU 69
*/
static MeasureUnit getMilligramOfglucosePerDeciliter();
-#endif /* U_HIDE_DRAFT_API */
/**
* Returns by pointer, unit of concentr: milligram-per-deciliter.
diff --git a/Build/source/libs/icu/icu-src/source/i18n/unicode/numberformatter.h b/Build/source/libs/icu/icu-src/source/i18n/unicode/numberformatter.h
index ece433b55f0..711064ece8d 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/unicode/numberformatter.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/unicode/numberformatter.h
@@ -22,6 +22,7 @@
#include "unicode/parseerr.h"
#include "unicode/plurrule.h"
#include "unicode/ucurr.h"
+#include "unicode/unounclass.h"
#include "unicode/unum.h"
#include "unicode/unumberformatter.h"
#include "unicode/uobject.h"
@@ -640,6 +641,33 @@ class U_I18N_API Precision : public UMemory {
*/
static IncrementPrecision increment(double roundingIncrement);
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Version of `Precision::increment()` that takes an integer at a particular power of 10.
+ *
+ * To round to the nearest 0.5 and display 2 fraction digits, with this function, you should write one of the following:
+ *
+ * <pre>
+ * Precision::incrementExact(5, -1).withMinFraction(2)
+ * Precision::incrementExact(50, -2).withMinFraction(2)
+ * Precision::incrementExact(50, -2)
+ * </pre>
+ *
+ * This is analagous to ICU4J `Precision.increment(new BigDecimal("0.50"))`.
+ *
+ * This behavior is modeled after ECMA-402. For more information, see:
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#roundingincrement
+ *
+ * @param mantissa
+ * The increment to which to round numbers.
+ * @param magnitude
+ * The power of 10 of the ones digit of the mantissa.
+ * @return A precision for chaining or passing to the NumberFormatter precision() setter.
+ * @draft ICU 71
+ */
+ static IncrementPrecision incrementExact(uint64_t mantissa, int16_t magnitude);
+#endif // U_HIDE_DRAFT_API
+
/**
* Show numbers rounded and padded according to the rules for the currency unit. The most common
* rounding precision settings for currencies include <code>Precision::fixedFraction(2)</code>,
@@ -659,16 +687,14 @@ class U_I18N_API Precision : public UMemory {
*/
static CurrencyPrecision currency(UCurrencyUsage currencyUsage);
-#ifndef U_HIDE_DRAFT_API
/**
* Configure how trailing zeros are displayed on numbers. For example, to hide trailing zeros
* when the number is an integer, use UNUM_TRAILING_ZERO_HIDE_IF_WHOLE.
*
* @param trailingZeroDisplay Option to configure the display of trailing zeros.
- * @draft ICU 69
+ * @stable ICU 69
*/
Precision trailingZeroDisplay(UNumberTrailingZeroDisplay trailingZeroDisplay) const;
-#endif // U_HIDE_DRAFT_API
private:
enum PrecisionType {
@@ -707,16 +733,23 @@ class U_I18N_API Precision : public UMemory {
impl::digits_t fMaxSig;
/** @internal (private) */
UNumberRoundingPriority fPriority;
+ /**
+ * Whether to retain trailing zeros based on the looser strategy.
+ * @internal (private)
+ */
+ bool fRetain;
} fracSig;
/** @internal (private) */
struct IncrementSettings {
// For RND_INCREMENT, RND_INCREMENT_ONE, and RND_INCREMENT_FIVE
+ // Note: This is a union, so we shouldn't own memory, since
+ // the default destructor would leak it.
/** @internal (private) */
- double fIncrement;
+ uint64_t fIncrement;
/** @internal (private) */
- impl::digits_t fMinFrac;
+ impl::digits_t fIncrementMagnitude;
/** @internal (private) */
- impl::digits_t fMaxFrac;
+ impl::digits_t fMinFrac;
} increment;
UCurrencyUsage currencyUsage; // For RND_CURRENCY
UErrorCode errorCode; // For RND_ERROR
@@ -759,9 +792,10 @@ class U_I18N_API Precision : public UMemory {
const FractionPrecision &base,
int32_t minSig,
int32_t maxSig,
- UNumberRoundingPriority priority);
+ UNumberRoundingPriority priority,
+ bool retain);
- static IncrementPrecision constructIncrement(double increment, int32_t minFrac);
+ static IncrementPrecision constructIncrement(uint64_t increment, impl::digits_t magnitude);
static CurrencyPrecision constructCurrency(UCurrencyUsage usage);
@@ -801,7 +835,6 @@ class U_I18N_API Precision : public UMemory {
*/
class U_I18N_API FractionPrecision : public Precision {
public:
-#ifndef U_HIDE_DRAFT_API
/**
* Override maximum fraction digits with maximum significant digits depending on the magnitude
* of the number. See UNumberRoundingPriority.
@@ -814,13 +847,12 @@ class U_I18N_API FractionPrecision : public Precision {
* How to disambiguate between fraction digits and significant digits.
* @return A precision for chaining or passing to the NumberFormatter precision() setter.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
Precision withSignificantDigits(
int32_t minSignificantDigits,
int32_t maxSignificantDigits,
UNumberRoundingPriority priority) const;
-#endif // U_HIDE_DRAFT_API
/**
* Ensure that no less than this number of significant digits are retained when rounding
@@ -1170,22 +1202,26 @@ class U_I18N_API Scale : public UMemory {
namespace impl {
-// Do not enclose entire StringProp with #ifndef U_HIDE_INTERNAL_API, needed for a protected field
+// Do not enclose entire StringProp with #ifndef U_HIDE_INTERNAL_API, needed for a protected field.
+// And do not enclose its class boilerplate within #ifndef U_HIDE_INTERNAL_API.
/**
* Manages NumberFormatterSettings::usage()'s char* instance on the heap.
* @internal
*/
class U_I18N_API StringProp : public UMemory {
-#ifndef U_HIDE_INTERNAL_API
-
public:
/** @internal */
+ ~StringProp();
+
+ /** @internal */
StringProp(const StringProp &other);
/** @internal */
StringProp &operator=(const StringProp &other);
+#ifndef U_HIDE_INTERNAL_API
+
/** @internal */
StringProp(StringProp &&src) U_NOEXCEPT;
@@ -1193,9 +1229,6 @@ class U_I18N_API StringProp : public UMemory {
StringProp &operator=(StringProp &&src) U_NOEXCEPT;
/** @internal */
- ~StringProp();
-
- /** @internal */
int16_t length() const {
return fLength;
}
@@ -2735,14 +2768,20 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue {
*/
MeasureUnit getOutputUnit(UErrorCode& status) const;
-#ifndef U_HIDE_INTERNAL_API
+#ifndef U_HIDE_DRAFT_API
+
/**
- * Gets the gender of the formatted output. Returns "" when the gender is
- * unknown, or for ungendered languages.
+ * Gets the noun class of the formatted output. Returns `OTHER` when the noun class
+ * is not supported yet.
*
- * @internal ICU 69 technology preview.
+ * @return `NounClass`
+ * @draft ICU 71.
*/
- const char *getGender(UErrorCode& status) const;
+ NounClass getNounClass(UErrorCode &status) const;
+
+#endif // U_HIDE_DRAFT_API
+
+#ifndef U_HIDE_INTERNAL_API
/**
* Gets the raw DecimalQuantity for plural rule selection.
@@ -2758,6 +2797,18 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue {
#endif /* U_HIDE_INTERNAL_API */
+#ifndef U_HIDE_DEPRECATED_API
+
+ /**
+ * Gets the gender of the formatted output. Returns "" when the gender is
+ * unknown, or for ungendered languages.
+ *
+ * @deprecated This API is for ICU internal use only.
+ */
+ const char *getGender(UErrorCode &status) const;
+
+#endif /* U_HIDE_DEPRECATED_API */
+
private:
// Can't use LocalPointer because UFormattedNumberData is forward-declared
const impl::UFormattedNumberData *fData;
diff --git a/Build/source/libs/icu/icu-src/source/i18n/unicode/rbtz.h b/Build/source/libs/icu/icu-src/source/i18n/unicode/rbtz.h
index 1eca70c338b..4fbf330cef1 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/unicode/rbtz.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/unicode/rbtz.h
@@ -303,16 +303,14 @@ public:
virtual void getTimeZoneRules(const InitialTimeZoneRule*& initial,
const TimeZoneRule* trsrules[], int32_t& trscount, UErrorCode& status) const override;
-#ifndef U_FORCE_HIDE_DRAFT_API
/**
* Get time zone offsets from local wall time.
- * @draft ICU 69
+ * @stable ICU 69
*/
virtual void getOffsetFromLocal(
UDate date, UTimeZoneLocalOption nonExistingTimeOpt,
UTimeZoneLocalOption duplicatedTimeOpt,
int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) const override;
-#endif /* U_FORCE_HIDE_DRAFT_API */
private:
void deleteRules(void);
diff --git a/Build/source/libs/icu/icu-src/source/i18n/unicode/simpletz.h b/Build/source/libs/icu/icu-src/source/i18n/unicode/simpletz.h
index f5c155de466..f73d823ee58 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/unicode/simpletz.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/unicode/simpletz.h
@@ -620,16 +620,14 @@ public:
virtual void getOffset(UDate date, UBool local, int32_t& rawOffset,
int32_t& dstOffset, UErrorCode& ec) const override;
-#ifndef U_FORCE_HIDE_DRAFT_API
/**
* Get time zone offsets from local wall time.
- * @draft ICU 69
+ * @stable ICU 69
*/
virtual void getOffsetFromLocal(
UDate date, UTimeZoneLocalOption nonExistingTimeOpt,
UTimeZoneLocalOption duplicatedTimeOpt,
int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) const override;
-#endif /* U_FORCE_HIDE_DRAFT_API */
/**
* Returns the TimeZone's raw GMT offset (i.e., the number of milliseconds to add
diff --git a/Build/source/libs/icu/icu-src/source/i18n/unicode/ucal.h b/Build/source/libs/icu/icu-src/source/i18n/unicode/ucal.h
index 94abae83919..3a4fb69fc3e 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/unicode/ucal.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/unicode/ucal.h
@@ -1617,25 +1617,23 @@ U_CAPI int32_t U_EXPORT2
ucal_getTimeZoneIDForWindowsID(const UChar* winid, int32_t len, const char* region,
UChar* id, int32_t idCapacity, UErrorCode* status);
-#ifndef U_FORCE_HIDE_DRAFT_API
/**
* Options used by ucal_getTimeZoneOffsetFromLocal and BasicTimeZone::getOffsetFromLocal()
* to specify how to interpret an input time when it does not exist, or when it is ambiguous,
* around a time zone transition.
- * @draft ICU 69
+ * @stable ICU 69
*/
enum UTimeZoneLocalOption {
-#ifndef U_HIDE_DRAFT_API
/**
* An input time is always interpreted as local time before
* a time zone transition.
- * @draft ICU 69
+ * @stable ICU 69
*/
UCAL_TZ_LOCAL_FORMER = 0x04,
/**
* An input time is always interpreted as local time after
* a time zone transition.
- * @draft ICU 69
+ * @stable ICU 69
*/
UCAL_TZ_LOCAL_LATTER = 0x0C,
/**
@@ -1644,7 +1642,7 @@ enum UTimeZoneLocalOption {
* sides of a time zone transition are standard time,
* or daylight saving time, the local time before the
* transition is used.
- * @draft ICU 69
+ * @stable ICU 69
*/
UCAL_TZ_LOCAL_STANDARD_FORMER = UCAL_TZ_LOCAL_FORMER | 0x01,
/**
@@ -1653,7 +1651,7 @@ enum UTimeZoneLocalOption {
* sides of a time zone transition are standard time,
* or daylight saving time, the local time after the
* transition is used.
- * @draft ICU 69
+ * @stable ICU 69
*/
UCAL_TZ_LOCAL_STANDARD_LATTER = UCAL_TZ_LOCAL_LATTER | 0x01,
/**
@@ -1662,7 +1660,7 @@ enum UTimeZoneLocalOption {
* sides of a time zone transition are standard time,
* or daylight saving time, the local time before the
* transition is used.
- * @draft ICU 69
+ * @stable ICU 69
*/
UCAL_TZ_LOCAL_DAYLIGHT_FORMER = UCAL_TZ_LOCAL_FORMER | 0x03,
/**
@@ -1671,19 +1669,11 @@ enum UTimeZoneLocalOption {
* sides of a time zone transition are standard time,
* or daylight saving time, the local time after the
* transition is used.
- * @draft ICU 69
+ * @stable ICU 69
*/
UCAL_TZ_LOCAL_DAYLIGHT_LATTER = UCAL_TZ_LOCAL_LATTER | 0x03,
-#else /* U_HIDE_DRAFT_API */
- /**
- * Dummy value to prevent empty enum if U_HIDE_DRAFT_API.
- * This will go away when draft conditionals are removed.
- * @internal
- */
- UCAL_TZ_LOCAL_NONE = 0,
-#endif /* U_HIDE_DRAFT_API */
};
-typedef enum UTimeZoneLocalOption UTimeZoneLocalOption; /**< @draft ICU 69 */
+typedef enum UTimeZoneLocalOption UTimeZoneLocalOption; /**< @stable ICU 69 */
/**
* Returns the time zone raw and GMT offset for the given moment
@@ -1710,7 +1700,7 @@ typedef enum UTimeZoneLocalOption UTimeZoneLocalOption; /**< @draft ICU 69 */
* typically one hour.
* If the status is set to one of the error code, the value set is unspecified.
* @param status A pointer to a UErrorCode to receive any errors.
-* @draft ICU 69
+* @stable ICU 69
*/
U_CAPI void U_EXPORT2
ucal_getTimeZoneOffsetFromLocal(
@@ -1718,7 +1708,6 @@ ucal_getTimeZoneOffsetFromLocal(
UTimeZoneLocalOption nonExistingTimeOpt,
UTimeZoneLocalOption duplicatedTimeOpt,
int32_t* rawOffset, int32_t* dstOffset, UErrorCode* status);
-#endif /* U_FORCE_HIDE_DRAFT_API */
#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/Build/source/libs/icu/icu-src/source/i18n/unicode/ucol.h b/Build/source/libs/icu/icu-src/source/i18n/unicode/ucol.h
index 6d22eb6069e..24963312216 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/unicode/ucol.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/unicode/ucol.h
@@ -397,7 +397,7 @@ typedef enum {
* @param status A pointer to a UErrorCode to receive any errors
* @return A pointer to a UCollator, or 0 if an error occurred.
* @see ucol_openRules
- * @see ucol_safeClone
+ * @see ucol_clone
* @see ucol_close
* @stable ICU 2.0
*/
@@ -425,7 +425,7 @@ ucol_open(const char *loc, UErrorCode *status);
* @return A pointer to a UCollator. It is not guaranteed that NULL be returned in case
* of error - please use status argument to check for errors.
* @see ucol_open
- * @see ucol_safeClone
+ * @see ucol_clone
* @see ucol_close
* @stable ICU 2.0
*/
@@ -521,7 +521,7 @@ ucol_getContractionsAndExpansions( const UCollator *coll,
* @param coll The UCollator to close.
* @see ucol_open
* @see ucol_openRules
- * @see ucol_safeClone
+ * @see ucol_clone
* @stable ICU 2.0
*/
U_CAPI void U_EXPORT2
@@ -985,7 +985,6 @@ ucol_getShortDefinitionString(const UCollator *coll,
*
* @deprecated ICU 54
*/
-
U_DEPRECATED int32_t U_EXPORT2
ucol_normalizeShortDefinitionString(const char *source,
char *destination,
@@ -1313,6 +1312,20 @@ ucol_restoreVariableTop(UCollator *coll, const uint32_t varTop, UErrorCode *stat
/**
* Thread safe cloning operation. The result is a clone of a given collator.
* @param coll collator to be cloned
+ * @param status to indicate whether the operation went on smoothly or there were errors
+ * @return pointer to the new clone
+ * @see ucol_open
+ * @see ucol_openRules
+ * @see ucol_close
+ * @stable ICU 71
+ */
+U_CAPI UCollator* U_EXPORT2 ucol_clone(const UCollator *coll, UErrorCode *status);
+
+#ifndef U_HIDE_DEPRECATED_API
+
+/**
+ * Thread safe cloning operation. The result is a clone of a given collator.
+ * @param coll collator to be cloned
* @param stackBuffer <em>Deprecated functionality as of ICU 52, use NULL.</em><br>
* user allocated space for the new clone.
* If NULL new memory will be allocated.
@@ -1325,21 +1338,20 @@ ucol_restoreVariableTop(UCollator *coll, const uint32_t varTop, UErrorCode *stat
* If *pBufferSize is not enough for a stack-based safe clone,
* new memory will be allocated.
* @param status to indicate whether the operation went on smoothly or there were errors
- * An informational status value, U_SAFECLONE_ALLOCATED_ERROR, is used if any
- * allocations were necessary.
+ * An informational status value, U_SAFECLONE_ALLOCATED_ERROR, is used
+ * if pBufferSize != NULL and any allocations were necessary
* @return pointer to the new clone
* @see ucol_open
* @see ucol_openRules
* @see ucol_close
- * @stable ICU 2.0
+ * @deprecated ICU 71 Use ucol_clone() instead.
*/
-U_CAPI UCollator* U_EXPORT2
+U_DEPRECATED UCollator* U_EXPORT2
ucol_safeClone(const UCollator *coll,
void *stackBuffer,
int32_t *pBufferSize,
UErrorCode *status);
-#ifndef U_HIDE_DEPRECATED_API
/** default memory size for the new clone.
* @deprecated ICU 52. Do not rely on ucol_safeClone() cloning into any provided buffer.
diff --git a/Build/source/libs/icu/icu-src/source/i18n/unicode/udatpg.h b/Build/source/libs/icu/icu-src/source/i18n/unicode/udatpg.h
index efe4357bfee..684a905e426 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/unicode/udatpg.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/unicode/udatpg.h
@@ -492,6 +492,11 @@ udatpg_getFieldDisplayName(const UDateTimePatternGenerator *dtpg,
* for those two skeletons, so the result is put together with this pattern,
* resulting in "d-MMM h:mm".
*
+ * There are four DateTimeFormats in a UDateTimePatternGenerator object,
+ * corresponding to date styles UDAT_FULL..UDAT_SHORT. This method sets
+ * all of them to the specified pattern. To set them individually, see
+ * udatpg_setDateTimeFormatForStyle.
+ *
* @param dtpg a pointer to UDateTimePatternGenerator.
* @param dtFormat
* message format pattern, here {1} will be replaced by the date
@@ -505,6 +510,12 @@ udatpg_setDateTimeFormat(const UDateTimePatternGenerator *dtpg,
/**
* Getter corresponding to setDateTimeFormat.
+ *
+ * There are four DateTimeFormats in a UDateTimePatternGenerator object,
+ * corresponding to date styles UDAT_FULL..UDAT_SHORT. This method gets
+ * the style for UDAT_MEDIUM (the default). To get them individually, see
+ * udatpg_getDateTimeFormatForStyle.
+ *
* @param dtpg a pointer to UDateTimePatternGenerator.
* @param pLength A pointer that will receive the length of the format
* @return dateTimeFormat.
@@ -514,6 +525,70 @@ U_CAPI const UChar * U_EXPORT2
udatpg_getDateTimeFormat(const UDateTimePatternGenerator *dtpg,
int32_t *pLength);
+#if !UCONFIG_NO_FORMATTING
+#ifndef U_HIDE_DRAFT_API
+/**
+ * dateTimeFormats are message patterns used to compose combinations of date
+ * and time patterns. There are four length styles, corresponding to the
+ * inferred style of the date pattern; these are UDateFormatStyle values:
+ * - UDAT_FULL (for date pattern with weekday and long month), else
+ * - UDAT_LONG (for a date pattern with long month), else
+ * - UDAT_MEDIUM (for a date pattern with abbreviated month), else
+ * - UDAT_SHORT (for any other date pattern).
+ * For details on dateTimeFormats, see
+ * https://www.unicode.org/reports/tr35/tr35-dates.html#dateTimeFormats.
+ * The default pattern in the root locale for all styles is "{1} {0}".
+ *
+ * @param udtpg
+ * a pointer to the UDateTimePatternGenerator
+ * @param style
+ * one of UDAT_FULL..UDAT_SHORT. Error if out of range.
+ * @param dateTimeFormat
+ * the new dateTimeFormat to set for the the specified style
+ * @param length
+ * the length of dateTimeFormat, or -1 if unknown and pattern
+ * is null-terminated
+ * @param pErrorCode
+ * a pointer to the UErrorCode (in/out parameter); if no failure
+ * status is already set, it will be set according to result of the
+ * function (e.g. U_ILLEGAL_ARGUMENT_ERROR for style out of range).
+ * @draft ICU 71
+ */
+U_CAPI void U_EXPORT2
+udatpg_setDateTimeFormatForStyle(UDateTimePatternGenerator *udtpg,
+ UDateFormatStyle style,
+ const UChar *dateTimeFormat, int32_t length,
+ UErrorCode *pErrorCode);
+
+/**
+ * Getter corresponding to udatpg_setDateTimeFormatForStyle.
+ *
+ * @param udtpg
+ * a pointer to the UDateTimePatternGenerator
+ * @param style
+ * one of UDAT_FULL..UDAT_SHORT. Error if out of range.
+ * @param pLength
+ * a pointer that will receive the length of the format. May be NULL
+ * if length is not desired.
+ * @param pErrorCode
+ * a pointer to the UErrorCode (in/out parameter); if no failure
+ * status is already set, it will be set according to result of the
+ * function (e.g. U_ILLEGAL_ARGUMENT_ERROR for style out of range).
+ * @return
+ * pointer to the current dateTimeFormat (0 terminated) for the specified
+ * style, or empty string in case of error. The pointer and its contents
+ * may no longer be valid if udatpg_setDateTimeFormat is called, or
+ * udatpg_setDateTimeFormatForStyle for the same style is called, or the
+ * UDateTimePatternGenerator object is closed.
+ * @draft ICU 71
+ */
+U_CAPI const UChar* U_EXPORT2
+udatpg_getDateTimeFormatForStyle(const UDateTimePatternGenerator *udtpg,
+ UDateFormatStyle style, int32_t *pLength,
+ UErrorCode *pErrorCode);
+#endif /* U_HIDE_DRAFT_API */
+#endif /* #if !UCONFIG_NO_FORMATTING */
+
/**
* The decimal value is used in formatting fractions of seconds. If the
* skeleton contains fractional seconds, then this is used with the
diff --git a/Build/source/libs/icu/icu-src/source/i18n/unicode/unounclass.h b/Build/source/libs/icu/icu-src/source/i18n/unicode/unounclass.h
new file mode 100644
index 00000000000..1721dbd584f
--- /dev/null
+++ b/Build/source/libs/icu/icu-src/source/i18n/unicode/unounclass.h
@@ -0,0 +1,43 @@
+// © 2022 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#ifndef __UNOUNCLASS_H__
+#define __UNOUNCLASS_H__
+
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/uversion.h"
+
+U_NAMESPACE_BEGIN
+
+#ifndef U_HIDE_DRAFT_API
+
+/**
+ * Represents all the grammatical noun classes that are supported by CLDR.
+ *
+ * @draft ICU 71.
+ */
+enum NounClass {
+ OTHER = 0,
+ NEUTER = 1,
+ FEMININE = 2,
+ MASCULINE = 3,
+ ANIMATE = 4,
+ INANIMATE = 5,
+ PERSONAL = 6,
+ COMMON = 7,
+};
+
+#endif // U_HIDE_DRAFT_API
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
+#endif // __UNOUNCLASS_H__
diff --git a/Build/source/libs/icu/icu-src/source/i18n/unicode/unum.h b/Build/source/libs/icu/icu-src/source/i18n/unicode/unum.h
index 14f76168b61..863695591ab 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/unicode/unum.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/unicode/unum.h
@@ -303,23 +303,21 @@ typedef enum UNumberFormatRoundingMode {
* @stable ICU 4.8
*/
UNUM_ROUND_UNNECESSARY,
-#ifndef U_HIDE_DRAFT_API
/**
* Rounds ties toward the odd number.
- * @draft ICU 69
+ * @stable ICU 69
*/
UNUM_ROUND_HALF_ODD,
/**
* Rounds ties toward +∞.
- * @draft ICU 69
+ * @stable ICU 69
*/
UNUM_ROUND_HALF_CEILING,
/**
* Rounds ties toward -∞.
- * @draft ICU 69
+ * @stable ICU 69
*/
UNUM_ROUND_HALF_FLOOR,
-#endif // U_HIDE_DRAFT_API
} UNumberFormatRoundingMode;
/** The possible number format pad positions.
@@ -401,13 +399,24 @@ typedef enum UNumberFormatFields {
UNUM_MEASURE_UNIT_FIELD,
/** @stable ICU 64 */
UNUM_COMPACT_FIELD,
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Approximately sign. In ICU 70, this was categorized under the generic SIGN field.
+ * @draft ICU 71
+ */
+ UNUM_APPROXIMATELY_SIGN_FIELD,
+#endif // U_HIDE_DRAFT_API
#ifndef U_HIDE_DEPRECATED_API
/**
* One more than the highest normal UNumberFormatFields value.
* @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
*/
- UNUM_FIELD_COUNT = UNUM_SIGN_FIELD + 3
+#ifndef U_HIDE_DRAFT_API
+ UNUM_FIELD_COUNT = UNUM_COMPACT_FIELD + 2
+#else // U_HIDE_DRAFT_API (for UNUM_APPROXIMATELY_SIGN_FIELD)
+ UNUM_FIELD_COUNT = UNUM_COMPACT_FIELD + 1
+#endif // U_HIDE_DRAFT_API (for UNUM_APPROXIMATELY_SIGN_FIELD)
#endif /* U_HIDE_DEPRECATED_API */
} UNumberFormatFields;
diff --git a/Build/source/libs/icu/icu-src/source/i18n/unicode/unumberformatter.h b/Build/source/libs/icu/icu-src/source/i18n/unicode/unumberformatter.h
index cb980cd94dd..58a75baf073 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/unicode/unumberformatter.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/unicode/unumberformatter.h
@@ -78,7 +78,6 @@
* </pre>
*/
-#ifndef U_FORCE_HIDE_DRAFT_API
/**
* An enum declaring how to resolve conflicts between maximum fraction digits and maximum
* significant digits.
@@ -115,24 +114,23 @@
* Here, RELAXED favors Max-Fraction and STRICT favors Max-Significant. Note that this larger
* number caused the two modes to favor the opposite result.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
typedef enum UNumberRoundingPriority {
/**
* Favor greater precision by relaxing one of the rounding constraints.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UNUM_ROUNDING_PRIORITY_RELAXED,
/**
* Favor adherence to all rounding constraints by producing lower precision.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UNUM_ROUNDING_PRIORITY_STRICT,
} UNumberRoundingPriority;
-#endif // U_FORCE_HIDE_DRAFT_API
/**
* An enum declaring how to render units, including currencies. Example outputs when formatting 123 USD and 123
@@ -435,21 +433,19 @@ typedef enum UNumberSignDisplay {
*/
UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO,
-#ifndef U_HIDE_DRAFT_API
/**
* Same as AUTO, but do not show the sign on negative zero.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UNUM_SIGN_NEGATIVE,
/**
* Same as ACCOUNTING, but do not show the sign on negative zero.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UNUM_SIGN_ACCOUNTING_NEGATIVE,
-#endif // U_HIDE_DRAFT_API
// Do not conditionalize the following with #ifndef U_HIDE_INTERNAL_API,
// needed for unconditionalized struct MacroProps
@@ -498,31 +494,29 @@ typedef enum UNumberDecimalSeparatorDisplay {
UNUM_DECIMAL_SEPARATOR_COUNT
} UNumberDecimalSeparatorDisplay;
-#ifndef U_FORCE_HIDE_DRAFT_API
/**
* An enum declaring how to render trailing zeros.
*
* - UNUM_TRAILING_ZERO_AUTO: 0.90, 1.00, 1.10
* - UNUM_TRAILING_ZERO_HIDE_IF_WHOLE: 0.90, 1, 1.10
*
- * @draft ICU 69
+ * @stable ICU 69
*/
typedef enum UNumberTrailingZeroDisplay {
/**
* Display trailing zeros according to the settings for minimum fraction and significant digits.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UNUM_TRAILING_ZERO_AUTO,
/**
* Same as AUTO, but hide trailing zeros after the decimal separator if they are all zero.
*
- * @draft ICU 69
+ * @stable ICU 69
*/
UNUM_TRAILING_ZERO_HIDE_IF_WHOLE,
} UNumberTrailingZeroDisplay;
-#endif // U_FORCE_HIDE_DRAFT_API
struct UNumberFormatter;
/**
diff --git a/Build/source/libs/icu/icu-src/source/i18n/unicode/vtzone.h b/Build/source/libs/icu/icu-src/source/i18n/unicode/vtzone.h
index e7d2f515410..ecf335bbe34 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/unicode/vtzone.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/unicode/vtzone.h
@@ -264,16 +264,14 @@ public:
virtual void getOffset(UDate date, UBool local, int32_t& rawOffset,
int32_t& dstOffset, UErrorCode& ec) const override;
-#ifndef U_FORCE_HIDE_DRAFT_API
/**
* Get time zone offsets from local wall time.
- * @draft ICU 69
+ * @stable ICU 69
*/
virtual void getOffsetFromLocal(
UDate date, UTimeZoneLocalOption nonExistingTimeOpt,
UTimeZoneLocalOption duplicatedTimeOpt,
int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) const override;
-#endif /* U_FORCE_HIDE_DRAFT_API */
/**
* Sets the TimeZone's raw GMT offset (i.e., the number of milliseconds to add
diff --git a/Build/source/libs/icu/icu-src/source/i18n/units_complexconverter.cpp b/Build/source/libs/icu/icu-src/source/i18n/units_complexconverter.cpp
index 78cefbf7ebb..ecbe3c78794 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/units_complexconverter.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/units_complexconverter.cpp
@@ -183,7 +183,7 @@ MaybeStackVector<Measure> ComplexUnitsConverter::convert(double quantity,
} else {
quantity = remainder;
}
- }
+ }
}
applyRounder(intValues, quantity, rounder, status);
@@ -210,7 +210,6 @@ MaybeStackVector<Measure> ComplexUnitsConverter::convert(double quantity,
}
}
-
// Transfer values into result and return:
for(int32_t i = 0, n = unitsConverters_.length(); i < n; ++i) {
U_ASSERT(tmpResult[i] != nullptr);
@@ -224,6 +223,12 @@ MaybeStackVector<Measure> ComplexUnitsConverter::convert(double quantity,
void ComplexUnitsConverter::applyRounder(MaybeStackArray<int64_t, 5> &intValues, double &quantity,
icu::number::impl::RoundingImpl *rounder,
UErrorCode &status) const {
+ if (uprv_isInfinite(quantity) || uprv_isNaN(quantity)) {
+ // Inf and NaN can't be rounded, and calculating `carry` below is known
+ // to fail on Gentoo on HPPA and OpenSUSE on riscv64. Nothing to do.
+ return;
+ }
+
if (rounder == nullptr) {
// Nothing to do for the quantity.
return;
diff --git a/Build/source/libs/icu/icu-src/source/i18n/units_complexconverter.h b/Build/source/libs/icu/icu-src/source/i18n/units_complexconverter.h
index 5c669b45ddd..d56ce8d4ce3 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/units_complexconverter.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/units_complexconverter.h
@@ -108,13 +108,15 @@ class U_I18N_API ComplexUnitsConverter : public UMemory {
MaybeStackVector<Measure>
convert(double quantity, icu::number::impl::RoundingImpl *rounder, UErrorCode &status) const;
- private:
+ // TODO(ICU-21937): Make it private after submitting the public units conversion API.
MaybeStackVector<UnitsConverter> unitsConverters_;
+ // TODO(ICU-21937): Make it private after submitting the public units conversion API.
// Individual units of mixed units, sorted big to small, with indices
// indicating the requested output mixed unit order.
MaybeStackVector<MeasureUnitImplWithIndex> units_;
+ private:
// Sorts units_, which must be populated before calling this, and populates
// unitsConverters_.
void init(const MeasureUnitImpl &inputUnit, const ConversionRates &ratesInfo, UErrorCode &status);
diff --git a/Build/source/libs/icu/icu-src/source/i18n/units_converter.cpp b/Build/source/libs/icu/icu-src/source/i18n/units_converter.cpp
index 7e946e584bb..82b8eea3d8c 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/units_converter.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/units_converter.cpp
@@ -9,6 +9,7 @@
#include "cmemory.h"
#include "double-conversion-string-to-double.h"
#include "measunit_impl.h"
+#include "putilimp.h"
#include "uassert.h"
#include "unicode/errorcode.h"
#include "unicode/localpointer.h"
@@ -588,10 +589,7 @@ double UnitsConverter::convert(double inputValue) const {
if (conversionRate_.reciprocal) {
if (result == 0) {
- // TODO: demonstrate the resulting behaviour in tests... and figure
- // out desired behaviour. (Theoretical result should be infinity,
- // not 0.)
- return 0.0;
+ return uprv_getInfinity();
}
result = 1.0 / result;
}
@@ -603,10 +601,7 @@ double UnitsConverter::convertInverse(double inputValue) const {
double result = inputValue;
if (conversionRate_.reciprocal) {
if (result == 0) {
- // TODO: demonstrate the resulting behaviour in tests... and figure
- // out desired behaviour. (Theoretical result should be infinity,
- // not 0.)
- return 0.0;
+ return uprv_getInfinity();
}
result = 1.0 / result;
}
diff --git a/Build/source/libs/icu/icu-src/source/i18n/units_router.h b/Build/source/libs/icu/icu-src/source/i18n/units_router.h
index b3300f7e277..d9fcffb2aa9 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/units_router.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/units_router.h
@@ -30,8 +30,6 @@ namespace units {
struct RouteResult : UMemory {
// A list of measures: a single measure for single units, multiple measures
// for mixed units.
- //
- // TODO(icu-units/icu#21): figure out the right mixed unit API.
MaybeStackVector<Measure> measures;
// The output unit for this RouteResult. This may be a MIXED unit - for
diff --git a/Build/source/libs/icu/icu-src/source/i18n/uspoof_conf.cpp b/Build/source/libs/icu/icu-src/source/i18n/uspoof_conf.cpp
index 04081cabfb0..172c0711afb 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/uspoof_conf.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/uspoof_conf.cpp
@@ -63,23 +63,24 @@ U_NAMESPACE_USE
// at the same time
//
-SPUString::SPUString(UnicodeString *s) {
- fStr = s;
+SPUString::SPUString(LocalPointer<UnicodeString> s) {
+ fStr = std::move(s);
fCharOrStrTableIndex = 0;
}
SPUString::~SPUString() {
- delete fStr;
}
-SPUStringPool::SPUStringPool(UErrorCode &status) : fVec(NULL), fHash(NULL) {
- fVec = new UVector(status);
- if (fVec == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
+SPUStringPool::SPUStringPool(UErrorCode &status) : fVec(nullptr), fHash(nullptr) {
+ LocalPointer<UVector> vec(new UVector(status), status);
+ if (U_FAILURE(status)) {
return;
}
+ vec->setDeleter(
+ [](void *obj) {delete (SPUString *)obj;});
+ fVec = vec.orphan();
fHash = uhash_open(uhash_hashUnicodeString, // key hash function
uhash_compareUnicodeString, // Key Comparator
NULL, // Value Comparator
@@ -88,11 +89,6 @@ SPUStringPool::SPUStringPool(UErrorCode &status) : fVec(NULL), fHash(NULL) {
SPUStringPool::~SPUStringPool() {
- int i;
- for (i=fVec->size()-1; i>=0; i--) {
- SPUString *s = static_cast<SPUString *>(fVec->elementAt(i));
- delete s;
- }
delete fVec;
uhash_close(fHash);
}
@@ -135,18 +131,21 @@ void SPUStringPool::sort(UErrorCode &status) {
SPUString *SPUStringPool::addString(UnicodeString *src, UErrorCode &status) {
+ LocalPointer<UnicodeString> lpSrc(src);
+ if (U_FAILURE(status)) {
+ return nullptr;
+ }
SPUString *hashedString = static_cast<SPUString *>(uhash_get(fHash, src));
- if (hashedString != NULL) {
- delete src;
- } else {
- hashedString = new SPUString(src);
- if (hashedString == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
- }
- uhash_put(fHash, src, hashedString, &status);
- fVec->addElementX(hashedString, status);
+ if (hashedString != nullptr) {
+ return hashedString;
+ }
+ LocalPointer<SPUString> spuStr(new SPUString(std::move(lpSrc)), status);
+ hashedString = spuStr.getAlias();
+ fVec->adoptElement(spuStr.orphan(), status);
+ if (U_FAILURE(status)) {
+ return nullptr;
}
+ uhash_put(fHash, src, hashedString, &status);
return hashedString;
}
diff --git a/Build/source/libs/icu/icu-src/source/i18n/uspoof_conf.h b/Build/source/libs/icu/icu-src/source/i18n/uspoof_conf.h
index 600d7ea42a4..1eeecdfd5e4 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/uspoof_conf.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/uspoof_conf.h
@@ -39,11 +39,12 @@ U_NAMESPACE_BEGIN
// Instances of SPUString exist during the compilation process only.
struct SPUString : public UMemory {
- UnicodeString *fStr; // The actual string.
- int32_t fCharOrStrTableIndex; // Index into the final runtime data for this
- // string (or, for length 1, the single string char
- // itself, there being no string table entry for it.)
- SPUString(UnicodeString *s);
+ LocalPointer<UnicodeString> fStr; // The actual string.
+ int32_t fCharOrStrTableIndex; // Index into the final runtime data for this
+ // string (or, for length 1, the single string char
+ // itself, there being no string table entry for it.)
+
+ SPUString(LocalPointer<UnicodeString> s);
~SPUString();
};
diff --git a/Build/source/libs/icu/icu-src/source/i18n/uspoof_impl.cpp b/Build/source/libs/icu/icu-src/source/i18n/uspoof_impl.cpp
index b283d813210..f96826f86cc 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/uspoof_impl.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/uspoof_impl.cpp
@@ -945,7 +945,7 @@ uspoof_swap(const UDataSwapper *ds, const void *inData, int32_t length, void *ou
uint32_t magic = ds->readUInt32(spoofDH->fMagic);
ds->writeUInt32((uint32_t *)&outputDH->fMagic, magic);
- if (outputDH->fFormatVersion != spoofDH->fFormatVersion) {
+ if (inBytes != outBytes) {
uprv_memcpy(outputDH->fFormatVersion, spoofDH->fFormatVersion, sizeof(spoofDH->fFormatVersion));
}
// swap starting at fLength
diff --git a/Build/source/libs/icu/icu-src/source/i18n/vtzone.cpp b/Build/source/libs/icu/icu-src/source/i18n/vtzone.cpp
index 9111e08848f..06f0b84c0f5 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/vtzone.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/vtzone.cpp
@@ -24,14 +24,6 @@
U_NAMESPACE_BEGIN
-// This is the deleter that will be use to remove TimeZoneRule
-U_CDECL_BEGIN
-static void U_CALLCONV
-deleteTimeZoneRule(void* obj) {
- delete (TimeZoneRule*) obj;
-}
-U_CDECL_END
-
// Smybol characters used by RFC2445 VTIMEZONE
static const UChar COLON = 0x3A; /* : */
static const UChar SEMICOLON = 0x3B; /* ; */
@@ -976,22 +968,19 @@ VTimeZone::VTimeZone(const VTimeZone& source)
if (source.vtzlines != nullptr) {
UErrorCode status = U_ZERO_ERROR;
int32_t size = source.vtzlines->size();
- vtzlines = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, size, status);
- if (vtzlines == nullptr) {
+ LocalPointer<UVector> lpVtzLines(
+ new UVector(uprv_deleteUObject, uhash_compareUnicodeString, size, status), status);
+ if (U_FAILURE(status)) {
return;
}
- if (U_SUCCESS(status)) {
- for (int32_t i = 0; i < size; i++) {
- UnicodeString *line = (UnicodeString*)source.vtzlines->elementAt(i);
- vtzlines->addElementX(line->clone(), status);
- if (U_FAILURE(status)) {
- break;
- }
+ for (int32_t i = 0; i < size; i++) {
+ UnicodeString *line = ((UnicodeString*)source.vtzlines->elementAt(i))->clone();
+ lpVtzLines->adoptElement(line, status);
+ if (U_FAILURE(status) || line == nullptr) {
+ return;
}
}
- if (U_FAILURE(status) && vtzlines != nullptr) {
- delete vtzlines;
- }
+ vtzlines = lpVtzLines.orphan();
}
}
@@ -1020,23 +1009,25 @@ VTimeZone::operator=(const VTimeZone& right) {
}
if (vtzlines != nullptr) {
delete vtzlines;
+ vtzlines = nullptr;
}
if (right.vtzlines != nullptr) {
UErrorCode status = U_ZERO_ERROR;
int32_t size = right.vtzlines->size();
- vtzlines = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, size, status);
- if (vtzlines != nullptr && U_SUCCESS(status)) {
+ LocalPointer<UVector> lpVtzLines(
+ new UVector(uprv_deleteUObject, uhash_compareUnicodeString, size, status), status);
+ if (U_SUCCESS(status)) {
for (int32_t i = 0; i < size; i++) {
- UnicodeString *line = (UnicodeString*)right.vtzlines->elementAt(i);
- vtzlines->addElementX(line->clone(), status);
+ LocalPointer<UnicodeString> line(
+ ((UnicodeString*)right.vtzlines->elementAt(i))->clone(), status);
+ lpVtzLines->adoptElement(line.orphan(), status);
if (U_FAILURE(status)) {
break;
}
}
- }
- if (U_FAILURE(status) && vtzlines != nullptr) {
- delete vtzlines;
- vtzlines = nullptr;
+ if (U_SUCCESS(status)) {
+ vtzlines = lpVtzLines.orphan();
+ }
}
}
tzurl = right.tzurl;
@@ -1272,10 +1263,9 @@ VTimeZone::getTimeZoneRules(const InitialTimeZoneRule*& initial,
void
VTimeZone::load(VTZReader& reader, UErrorCode& status) {
- vtzlines = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, DEFAULT_VTIMEZONE_LINES, status);
- if (vtzlines == nullptr) {
- status = U_MEMORY_ALLOCATION_ERROR;
- }
+ U_ASSERT(vtzlines == nullptr);
+ LocalPointer<UVector> lpVtzLines(
+ new UVector(uprv_deleteUObject, uhash_compareUnicodeString, DEFAULT_VTIMEZONE_LINES, status), status);
if (U_FAILURE(status)) {
return;
}
@@ -1290,14 +1280,10 @@ VTimeZone::load(VTZReader& reader, UErrorCode& status) {
// end of file
if (start && line.startsWith(ICAL_END_VTIMEZONE, -1)) {
LocalPointer<UnicodeString> element(new UnicodeString(line), status);
+ lpVtzLines->adoptElement(element.orphan(), status);
if (U_FAILURE(status)) {
- goto cleanupVtzlines;
- }
- vtzlines->addElementX(element.getAlias(), status);
- if (U_FAILURE(status)) {
- goto cleanupVtzlines;
+ return;
}
- element.orphan(); // on success, vtzlines owns the object.
success = TRUE;
}
break;
@@ -1312,14 +1298,10 @@ VTimeZone::load(VTZReader& reader, UErrorCode& status) {
if (start) {
if (line.length() > 0) {
LocalPointer<UnicodeString> element(new UnicodeString(line), status);
+ lpVtzLines->adoptElement(element.orphan(), status);
if (U_FAILURE(status)) {
- goto cleanupVtzlines;
+ return;
}
- vtzlines->addElementX(element.getAlias(), status);
- if (U_FAILURE(status)) {
- goto cleanupVtzlines;
- }
- element.orphan(); // on success, vtzlines owns the object.
}
}
line.remove();
@@ -1335,28 +1317,20 @@ VTimeZone::load(VTZReader& reader, UErrorCode& status) {
if (start) {
if (line.startsWith(ICAL_END_VTIMEZONE, -1)) {
LocalPointer<UnicodeString> element(new UnicodeString(line), status);
+ lpVtzLines->adoptElement(element.orphan(), status);
if (U_FAILURE(status)) {
- goto cleanupVtzlines;
- }
- vtzlines->addElementX(element.getAlias(), status);
- if (U_FAILURE(status)) {
- goto cleanupVtzlines;
+ return;
}
- element.orphan(); // on success, vtzlines owns the object.
success = TRUE;
break;
}
} else {
if (line.startsWith(ICAL_BEGIN_VTIMEZONE, -1)) {
LocalPointer<UnicodeString> element(new UnicodeString(line), status);
+ lpVtzLines->adoptElement(element.orphan(), status);
if (U_FAILURE(status)) {
- goto cleanupVtzlines;
- }
- vtzlines->addElementX(element.getAlias(), status);
- if (U_FAILURE(status)) {
- goto cleanupVtzlines;
+ return;
}
- element.orphan(); // on success, vtzlines owns the object.
line.remove();
start = TRUE;
eol = FALSE;
@@ -1371,14 +1345,10 @@ VTimeZone::load(VTZReader& reader, UErrorCode& status) {
if (U_SUCCESS(status)) {
status = U_INVALID_STATE_ERROR;
}
- goto cleanupVtzlines;
+ return;
}
+ vtzlines = lpVtzLines.orphan();
parse(status);
- return;
-
-cleanupVtzlines:
- delete vtzlines;
- vtzlines = nullptr;
}
// parser state
@@ -1398,8 +1368,6 @@ VTimeZone::parse(UErrorCode& status) {
status = U_INVALID_STATE_ERROR;
return;
}
- InitialTimeZoneRule *initialRule = nullptr;
- RuleBasedTimeZone *rbtz = nullptr;
// timezone ID
UnicodeString tzid;
@@ -1418,28 +1386,16 @@ VTimeZone::parse(UErrorCode& status) {
UnicodeString name; // RFC2445 prop name
UnicodeString value; // RFC2445 prop value
- UVector *dates = nullptr; // list of RDATE or RRULE strings
- UVector *rules = nullptr; // list of TimeZoneRule instances
-
int32_t finalRuleIdx = -1;
int32_t finalRuleCount = 0;
- rules = new UVector(status);
- if (rules == nullptr) {
- status = U_MEMORY_ALLOCATION_ERROR;
- }
- if (U_FAILURE(status)) {
- goto cleanupParse;
- }
- // Set the deleter to remove TimeZoneRule vectors to avoid memory leaks due to unowned TimeZoneRules.
- rules->setDeleter(deleteTimeZoneRule);
+ // Set the deleter on rules to remove TimeZoneRule vectors to avoid memory leaks due to unowned TimeZoneRules.
+ UVector rules(uprv_deleteUObject, nullptr, status);
- dates = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status);
- if (dates == nullptr) {
- status = U_MEMORY_ALLOCATION_ERROR;
- }
+ // list of RDATE or RRULE strings
+ UVector dates(uprv_deleteUObject, uhash_compareUnicodeString, status);
if (U_FAILURE(status)) {
- goto cleanupParse;
+ return;
}
for (n = 0; n < vtzlines->size(); n++) {
@@ -1469,18 +1425,18 @@ VTimeZone::parse(UErrorCode& status) {
// can be any value.
lastmod = parseDateTimeString(value, 0, status);
if (U_FAILURE(status)) {
- goto cleanupParse;
+ return;
}
} else if (name.compare(ICAL_BEGIN, -1) == 0) {
UBool isDST = (value.compare(ICAL_DAYLIGHT, -1) == 0);
if (value.compare(ICAL_STANDARD, -1) == 0 || isDST) {
// tzid must be ready at this point
if (tzid.length() == 0) {
- goto cleanupParse;
+ return;
}
// initialize current zone properties
- if (dates->size() != 0) {
- dates->removeAllElements();
+ if (dates.size() != 0) {
+ dates.removeAllElements();
}
isRRULE = FALSE;
from.remove();
@@ -1491,7 +1447,7 @@ VTimeZone::parse(UErrorCode& status) {
} else {
// BEGIN property other than STANDARD/DAYLIGHT
// must not be there.
- goto cleanupParse;
+ return;
}
} else if (name.compare(ICAL_END, -1) == 0) {
break;
@@ -1509,50 +1465,42 @@ VTimeZone::parse(UErrorCode& status) {
} else if (name.compare(ICAL_RDATE, -1) == 0) {
// RDATE mixed with RRULE is not supported
if (isRRULE) {
- goto cleanupParse;
+ return;
}
// RDATE value may contain multiple date delimited
// by comma
UBool nextDate = TRUE;
int32_t dstart = 0;
- UnicodeString *dstr = nullptr;
+ LocalPointer<UnicodeString> dstr;
while (nextDate) {
int32_t dend = value.indexOf(COMMA, dstart);
if (dend == -1) {
- dstr = new UnicodeString(value, dstart);
+ dstr.adoptInsteadAndCheckErrorCode(new UnicodeString(value, dstart), status);
nextDate = FALSE;
} else {
- dstr = new UnicodeString(value, dstart, dend - dstart);
- }
- if (dstr == nullptr) {
- status = U_MEMORY_ALLOCATION_ERROR;
- } else {
- dates->addElementX(dstr, status);
+ dstr.adoptInsteadAndCheckErrorCode(new UnicodeString(value, dstart, dend - dstart), status);
}
+ dates.adoptElement(dstr.orphan(), status);
if (U_FAILURE(status)) {
- goto cleanupParse;
+ return;
}
dstart = dend + 1;
}
} else if (name.compare(ICAL_RRULE, -1) == 0) {
// RRULE mixed with RDATE is not supported
- if (!isRRULE && dates->size() != 0) {
- goto cleanupParse;
+ if (!isRRULE && dates.size() != 0) {
+ return;
}
isRRULE = true;
LocalPointer<UnicodeString> element(new UnicodeString(value), status);
+ dates.adoptElement(element.orphan(), status);
if (U_FAILURE(status)) {
- goto cleanupParse;
- }
- dates->addElementX(element.getAlias(), status);
- if (U_FAILURE(status)) {
- goto cleanupParse;
+ return;
}
- element.orphan(); // on success, dates owns the object.
} else if (name.compare(ICAL_END, -1) == 0) {
// Mandatory properties
if (dtstart.length() == 0 || from.length() == 0 || to.length() == 0) {
- goto cleanupParse;
+ return;
}
// if zonename is not available, create one from tzid
if (zonename.length() == 0) {
@@ -1560,7 +1508,7 @@ VTimeZone::parse(UErrorCode& status) {
}
// create a time zone rule
- TimeZoneRule *rule = nullptr;
+ LocalPointer<TimeZoneRule> rule;
int32_t fromOffset = 0;
int32_t toOffset = 0;
int32_t rawOffset = 0;
@@ -1571,7 +1519,7 @@ VTimeZone::parse(UErrorCode& status) {
fromOffset = offsetStrToMillis(from, status);
toOffset = offsetStrToMillis(to, status);
if (U_FAILURE(status)) {
- goto cleanupParse;
+ return;
}
if (dst) {
@@ -1592,18 +1540,20 @@ VTimeZone::parse(UErrorCode& status) {
// start time
start = parseDateTimeString(dtstart, fromOffset, status);
if (U_FAILURE(status)) {
- goto cleanupParse;
+ return;
}
// Create the rule
UDate actualStart = MAX_MILLIS;
if (isRRULE) {
- rule = createRuleByRRULE(zonename, rawOffset, dstSavings, start, dates, fromOffset, status);
+ rule.adoptInsteadAndCheckErrorCode(
+ createRuleByRRULE(zonename, rawOffset, dstSavings, start, &dates, fromOffset, status), status);
} else {
- rule = createRuleByRDATE(zonename, rawOffset, dstSavings, start, dates, fromOffset, status);
+ rule.adoptInsteadAndCheckErrorCode(
+ createRuleByRDATE(zonename, rawOffset, dstSavings, start, &dates, fromOffset, status), status);
}
- if (U_FAILURE(status) || rule == nullptr) {
- goto cleanupParse;
+ if (U_FAILURE(status)) {
+ return;
} else {
UBool startAvail = rule->getFirstStart(fromOffset, 0, actualStart);
if (startAvail && actualStart < firstStart) {
@@ -1626,9 +1576,9 @@ VTimeZone::parse(UErrorCode& status) {
}
}
}
- rules->addElementX(rule, status);
+ rules.adoptElement(rule.orphan(), status);
if (U_FAILURE(status)) {
- goto cleanupParse;
+ return;
}
state = VTZ;
}
@@ -1636,28 +1586,31 @@ VTimeZone::parse(UErrorCode& status) {
}
}
// Must have at least one rule
- if (rules->size() == 0) {
- goto cleanupParse;
+ if (rules.size() == 0) {
+ return;
}
// Create a initial rule
getDefaultTZName(tzid, FALSE, zonename);
- initialRule = new InitialTimeZoneRule(zonename, initialRawOffset, initialDSTSavings);
- if (initialRule == nullptr) {
- status = U_MEMORY_ALLOCATION_ERROR;
- goto cleanupParse;
+ LocalPointer<InitialTimeZoneRule> initialRule(
+ new InitialTimeZoneRule(zonename, initialRawOffset, initialDSTSavings), status);
+ if (U_FAILURE(status)) {
+ return;
}
// Finally, create the RuleBasedTimeZone
- rbtz = new RuleBasedTimeZone(tzid, initialRule);
- if (rbtz == nullptr) {
- status = U_MEMORY_ALLOCATION_ERROR;
- goto cleanupParse;
+ // C++ awkwardness on memory allocation failure: the constructor wont be run, meaning
+ // that initialRule wont be adopted/deleted, as it normally would be.
+ LocalPointer<RuleBasedTimeZone> rbtz(
+ new RuleBasedTimeZone(tzid, initialRule.getAlias()), status);
+ if (U_SUCCESS(status)) {
+ initialRule.orphan();
+ } else {
+ return;
}
- initialRule = nullptr; // already adopted by RBTZ, no need to delete
- for (n = 0; n < rules->size(); n++) {
- TimeZoneRule *r = (TimeZoneRule*)rules->elementAt(n);
+ for (n = 0; n < rules.size(); n++) {
+ TimeZoneRule *r = (TimeZoneRule*)rules.elementAt(n);
AnnualTimeZoneRule *atzrule = dynamic_cast<AnnualTimeZoneRule *>(r);
if (atzrule != nullptr) {
if (atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR) {
@@ -1669,18 +1622,18 @@ VTimeZone::parse(UErrorCode& status) {
if (finalRuleCount > 2) {
// Too many final rules
status = U_ILLEGAL_ARGUMENT_ERROR;
- goto cleanupParse;
+ return;
}
if (finalRuleCount == 1) {
- if (rules->size() == 1) {
+ if (rules.size() == 1) {
// Only one final rule, only governs the initial rule,
// which is already initialized, thus, we do not need to
// add this transition rule
- rules->removeAllElements();
+ rules.removeAllElements();
} else {
// Normalize the final rule
- AnnualTimeZoneRule *finalRule = (AnnualTimeZoneRule*)rules->elementAt(finalRuleIdx);
+ AnnualTimeZoneRule *finalRule = (AnnualTimeZoneRule*)rules.elementAt(finalRuleIdx);
int32_t tmpRaw = finalRule->getRawOffset();
int32_t tmpDST = finalRule->getDSTSavings();
@@ -1688,11 +1641,11 @@ VTimeZone::parse(UErrorCode& status) {
UDate finalStart, start;
finalRule->getFirstStart(initialRawOffset, initialDSTSavings, finalStart);
start = finalStart;
- for (n = 0; n < rules->size(); n++) {
+ for (n = 0; n < rules.size(); n++) {
if (finalRuleIdx == n) {
continue;
}
- TimeZoneRule *r = (TimeZoneRule*)rules->elementAt(n);
+ TimeZoneRule *r = (TimeZoneRule*)rules.elementAt(n);
UDate lastStart;
r->getFinalStart(tmpRaw, tmpDST, lastStart);
if (lastStart > start) {
@@ -1704,78 +1657,58 @@ VTimeZone::parse(UErrorCode& status) {
}
}
- TimeZoneRule *newRule = nullptr;
+ LocalPointer<TimeZoneRule> newRule;
UnicodeString tznam;
if (start == finalStart) {
// Transform this into a single transition
- newRule = new TimeArrayTimeZoneRule(
- finalRule->getName(tznam),
- finalRule->getRawOffset(),
- finalRule->getDSTSavings(),
- &finalStart,
- 1,
- DateTimeRule::UTC_TIME);
+ newRule.adoptInsteadAndCheckErrorCode(
+ new TimeArrayTimeZoneRule(
+ finalRule->getName(tznam),
+ finalRule->getRawOffset(),
+ finalRule->getDSTSavings(),
+ &finalStart,
+ 1,
+ DateTimeRule::UTC_TIME),
+ status);
} else {
// Update the end year
int32_t y, m, d, dow, doy, mid;
Grego::timeToFields(start, y, m, d, dow, doy, mid);
- newRule = new AnnualTimeZoneRule(
- finalRule->getName(tznam),
- finalRule->getRawOffset(),
- finalRule->getDSTSavings(),
- *(finalRule->getRule()),
- finalRule->getStartYear(),
- y);
+ newRule.adoptInsteadAndCheckErrorCode(
+ new AnnualTimeZoneRule(
+ finalRule->getName(tznam),
+ finalRule->getRawOffset(),
+ finalRule->getDSTSavings(),
+ *(finalRule->getRule()),
+ finalRule->getStartYear(),
+ y),
+ status);
}
- if (newRule == nullptr) {
- status = U_MEMORY_ALLOCATION_ERROR;
- goto cleanupParse;
+ if (U_FAILURE(status)) {
+ return;
}
- rules->removeElementAt(finalRuleIdx);
- rules->addElementX(newRule, status);
+ rules.removeElementAt(finalRuleIdx);
+ rules.adoptElement(newRule.orphan(), status);
if (U_FAILURE(status)) {
- delete newRule;
- goto cleanupParse;
+ return;
}
}
}
- while (!rules->isEmpty()) {
- TimeZoneRule *tzr = (TimeZoneRule*)rules->orphanElementAt(0);
+ while (!rules.isEmpty()) {
+ TimeZoneRule *tzr = (TimeZoneRule*)rules.orphanElementAt(0);
rbtz->addTransitionRule(tzr, status);
if (U_FAILURE(status)) {
- goto cleanupParse;
+ return;
}
}
rbtz->complete(status);
if (U_FAILURE(status)) {
- goto cleanupParse;
+ return;
}
- delete rules;
- delete dates;
- tz = rbtz;
+ tz = rbtz.orphan();
setID(tzid);
- return;
-
-cleanupParse:
- if (rules != nullptr) {
- while (!rules->isEmpty()) {
- TimeZoneRule *r = (TimeZoneRule*)rules->orphanElementAt(0);
- delete r;
- }
- delete rules;
- }
- if (dates != nullptr) {
- delete dates;
- }
- if (initialRule != nullptr) {
- delete initialRule;
- }
- if (rbtz != nullptr) {
- delete rbtz;
- }
- return;
}
void
@@ -1809,7 +1742,7 @@ VTimeZone::write(VTZWriter& writer, UErrorCode& status) const {
icutzprop.append(u'[');
icutzprop.append(icutzver);
icutzprop.append(u']');
- customProps.addElementX(&icutzprop, status);
+ customProps.addElement(&icutzprop, status);
}
writeZone(writer, *tz, &customProps, status);
}
@@ -1827,34 +1760,35 @@ VTimeZone::write(UDate start, VTZWriter& writer, UErrorCode& status) const {
// Extract rules applicable to dates after the start time
getTimeZoneRulesAfter(start, initial, transitionRules, status);
+ LocalPointer<InitialTimeZoneRule> lpInitial(initial);
+ LocalPointer<UVector> lpTransitionRules(transitionRules);
if (U_FAILURE(status)) {
return;
}
// Create a RuleBasedTimeZone with the subset rule
getID(tzid);
- RuleBasedTimeZone rbtz(tzid, initial);
- if (transitionRules != nullptr) {
- while (!transitionRules->isEmpty()) {
- TimeZoneRule *tr = (TimeZoneRule*)transitionRules->orphanElementAt(0);
+ RuleBasedTimeZone rbtz(tzid, lpInitial.orphan());
+ if (lpTransitionRules.isValid()) {
+ U_ASSERT(transitionRules->hasDeleter()); // Assumed for U_FAILURE early return, below.
+ while (!lpTransitionRules->isEmpty()) {
+ TimeZoneRule *tr = (TimeZoneRule*)lpTransitionRules->orphanElementAt(0);
rbtz.addTransitionRule(tr, status);
if (U_FAILURE(status)) {
- goto cleanupWritePartial;
+ return;
}
}
- delete transitionRules;
- transitionRules = nullptr;
}
rbtz.complete(status);
if (U_FAILURE(status)) {
- goto cleanupWritePartial;
+ return;
}
if (olsonzid.length() > 0 && icutzver.length() > 0) {
UnicodeString *icutzprop = new UnicodeString(ICU_TZINFO_PROP);
if (icutzprop == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR;
- goto cleanupWritePartial;
+ return;
}
icutzprop->append(olsonzid);
icutzprop->append((UChar)0x005B/*'['*/);
@@ -1862,23 +1796,12 @@ VTimeZone::write(UDate start, VTZWriter& writer, UErrorCode& status) const {
icutzprop->append(ICU_TZINFO_PARTIAL, -1);
appendMillis(start, *icutzprop);
icutzprop->append((UChar)0x005D/*']'*/);
- customProps.addElementX(icutzprop, status);
+ customProps.adoptElement(icutzprop, status);
if (U_FAILURE(status)) {
- delete icutzprop;
- goto cleanupWritePartial;
+ return;
}
}
writeZone(writer, rbtz, &customProps, status);
- return;
-
-cleanupWritePartial:
- if (initial != nullptr) {
- delete initial;
- }
- if (transitionRules != nullptr) {
- U_ASSERT(transitionRules->hasDeleter());
- delete transitionRules;
- }
}
void
diff --git a/Build/source/libs/icu/icu-src/source/i18n/zonemeta.cpp b/Build/source/libs/icu/icu-src/source/i18n/zonemeta.cpp
index b8afa4760f1..e60215c9988 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/zonemeta.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/zonemeta.cpp
@@ -98,20 +98,12 @@ deleteUCharString(void *obj) {
}
/**
- * Deleter for UVector
- */
-static void U_CALLCONV
-deleteUVector(void *obj) {
- delete (icu::UVector*) obj;
-}
-
-/**
* Deleter for OlsonToMetaMappingEntry
*/
static void U_CALLCONV
deleteOlsonToMetaMappingEntry(void *obj) {
icu::OlsonToMetaMappingEntry *entry = (icu::OlsonToMetaMappingEntry*)obj;
- uprv_free(entry);
+ delete entry;
}
U_CDECL_END
@@ -477,11 +469,11 @@ ZoneMeta::getCanonicalCountry(const UnicodeString &tzid, UnicodeString &country,
UErrorCode ec = U_ZERO_ERROR;
if (singleZone) {
if (!gSingleZoneCountries->contains((void*)region)) {
- gSingleZoneCountries->addElementX((void*)region, ec);
+ gSingleZoneCountries->addElement((void*)region, ec);
}
} else {
if (!gMultiZonesCountries->contains((void*)region)) {
- gMultiZonesCountries->addElementX((void*)region, ec);
+ gMultiZonesCountries->addElement((void*)region, ec);
}
}
}
@@ -550,7 +542,7 @@ static void U_CALLCONV olsonToMetaInit(UErrorCode &status) {
gOlsonToMeta = NULL;
} else {
uhash_setKeyDeleter(gOlsonToMeta, deleteUCharString);
- uhash_setValueDeleter(gOlsonToMeta, deleteUVector);
+ uhash_setValueDeleter(gOlsonToMeta, uprv_deleteUObject);
}
}
@@ -625,7 +617,7 @@ ZoneMeta::getMetazoneMappings(const UnicodeString &tzid) {
UVector*
ZoneMeta::createMetazoneMappings(const UnicodeString &tzid) {
- UVector *mzMappings = NULL;
+ LocalPointer <UVector> mzMappings;
UErrorCode status = U_ZERO_ERROR;
UnicodeString canonicalID;
@@ -677,41 +669,32 @@ ZoneMeta::createMetazoneMappings(const UnicodeString &tzid) {
continue;
}
- OlsonToMetaMappingEntry *entry = (OlsonToMetaMappingEntry*)uprv_malloc(sizeof(OlsonToMetaMappingEntry));
- if (entry == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
+ LocalPointer<OlsonToMetaMappingEntry> entry(new OlsonToMetaMappingEntry, status);
+ if (U_FAILURE(status)) {
break;
}
entry->mzid = mz_name;
entry->from = from;
entry->to = to;
- if (mzMappings == NULL) {
- mzMappings = new UVector(deleteOlsonToMetaMappingEntry, NULL, status);
+ if (mzMappings.isNull()) {
+ mzMappings.adoptInsteadAndCheckErrorCode(
+ new UVector(deleteOlsonToMetaMappingEntry, nullptr, status), status);
if (U_FAILURE(status)) {
- delete mzMappings;
- mzMappings = NULL;
- uprv_free(entry);
break;
}
}
- mzMappings->addElementX(entry, status);
+ mzMappings->adoptElement(entry.orphan(), status);
if (U_FAILURE(status)) {
break;
}
}
ures_close(mz);
- if (U_FAILURE(status)) {
- if (mzMappings != NULL) {
- delete mzMappings;
- mzMappings = NULL;
- }
- }
}
}
ures_close(rb);
- return mzMappings;
+ return U_SUCCESS(status) ? mzMappings.orphan() : nullptr;
}
UnicodeString& U_EXPORT2
@@ -775,6 +758,7 @@ static void U_CALLCONV initAvailableMetaZoneIDs () {
// No valueDeleter, because the vector maintain the value objects
gMetaZoneIDs = new UVector(NULL, uhash_compareUChars, status);
if (U_FAILURE(status) || gMetaZoneIDs == NULL) {
+ delete gMetaZoneIDs;
gMetaZoneIDs = NULL;
uhash_close(gMetaZoneIDTable);
gMetaZoneIDTable = NULL;
@@ -792,20 +776,22 @@ static void U_CALLCONV initAvailableMetaZoneIDs () {
}
const char *mzID = ures_getKey(res.getAlias());
int32_t len = static_cast<int32_t>(uprv_strlen(mzID));
- UChar *uMzID = (UChar*)uprv_malloc(sizeof(UChar) * (len + 1));
- if (uMzID == NULL) {
+ LocalMemory<UChar> uMzID((UChar*)uprv_malloc(sizeof(UChar) * (len + 1)));
+ if (uMzID.isNull()) {
status = U_MEMORY_ALLOCATION_ERROR;
break;
}
- u_charsToUChars(mzID, uMzID, len);
+ u_charsToUChars(mzID, uMzID.getAlias(), len);
uMzID[len] = 0;
- UnicodeString *usMzID = new UnicodeString(uMzID);
- if (uhash_get(gMetaZoneIDTable, usMzID) == NULL) {
- gMetaZoneIDs->addElementX((void *)uMzID, status);
- uhash_put(gMetaZoneIDTable, (void *)usMzID, (void *)uMzID, &status);
- } else {
- uprv_free(uMzID);
- delete usMzID;
+ LocalPointer<UnicodeString> usMzID(new UnicodeString(uMzID.getAlias()), status);
+ if (U_FAILURE(status)) {
+ break;
+ }
+ if (uhash_get(gMetaZoneIDTable, usMzID.getAlias()) == NULL) {
+ // Note: gMetaZoneIDTable adopts its keys, but not its values.
+ // gMetaZoneIDs adopts its values.
+ uhash_put(gMetaZoneIDTable, usMzID.orphan(), uMzID.getAlias(), &status);
+ gMetaZoneIDs->adoptElement(uMzID.orphan(), status);
}
}
ures_close(bundle);
diff --git a/Build/source/libs/icu/icu-src/source/i18n/zonemeta.h b/Build/source/libs/icu/icu-src/source/i18n/zonemeta.h
index f21399342b9..dd4fec957fe 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/zonemeta.h
+++ b/Build/source/libs/icu/icu-src/source/i18n/zonemeta.h
@@ -18,11 +18,11 @@
U_NAMESPACE_BEGIN
-typedef struct OlsonToMetaMappingEntry {
+struct OlsonToMetaMappingEntry : public UMemory {
const UChar *mzid; // const because it's a reference to a resource bundle string.
UDate from;
UDate to;
-} OlsonToMetaMappingEntry;
+};
class UVector;
class TimeZone;
diff --git a/Build/source/libs/icu/icu-src/source/io/io.vcxproj b/Build/source/libs/icu/icu-src/source/io/io.vcxproj
index 56957edc8b9..34af85f6d93 100644
--- a/Build/source/libs/icu/icu-src/source/io/io.vcxproj
+++ b/Build/source/libs/icu/icu-src/source/io/io.vcxproj
@@ -60,7 +60,7 @@
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <OutputFile>..\..\$(IcuBinOutputDir)\icuio70d.dll</OutputFile>
+ <OutputFile>..\..\$(IcuBinOutputDir)\icuio71d.dll</OutputFile>
<ProgramDatabaseFile>..\..\$(IcuLibOutputDir)\icuiod.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\$(IcuLibOutputDir)\icuiod.lib</ImportLibrary>
<AdditionalDependencies>icuucd.lib;icuind.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -73,7 +73,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
</ClCompile>
<Link>
- <OutputFile>..\..\$(IcuBinOutputDir)\icuio70.dll</OutputFile>
+ <OutputFile>..\..\$(IcuBinOutputDir)\icuio71.dll</OutputFile>
<ProgramDatabaseFile>..\..\$(IcuLibOutputDir)\icuio.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\$(IcuLibOutputDir)\icuio.lib</ImportLibrary>
<AdditionalDependencies>icuuc.lib;icuin.lib;%(AdditionalDependencies)</AdditionalDependencies>
diff --git a/Build/source/libs/icu/icu-src/source/io/sprintf.cpp b/Build/source/libs/icu/icu-src/source/io/sprintf.cpp
index 3a593abb480..ede31e91517 100644
--- a/Build/source/libs/icu/icu-src/source/io/sprintf.cpp
+++ b/Build/source/libs/icu/icu-src/source/io/sprintf.cpp
@@ -41,6 +41,12 @@ u_sprintf_write(void *context,
int32_t count)
{
u_localized_print_string *output = (u_localized_print_string *)context;
+
+ /* just calculating buffer size */
+ if (output->str == 0) {
+ return count;
+ }
+
int32_t size = ufmt_min(count, output->available);
u_strncpy(output->str + (output->len - output->available), str, size);
@@ -58,6 +64,12 @@ u_sprintf_pad_and_justify(void *context,
int32_t written = 0;
int32_t lengthOfResult = resultLen;
+ /* just calculating buffer size */
+ if (output->str == 0 &&
+ info->fWidth != -1 && resultLen < info->fWidth) {
+ return info->fWidth;
+ }
+
resultLen = ufmt_min(resultLen, output->available);
/* pad and justify, if needed */
diff --git a/Build/source/libs/icu/icu-src/source/io/ustdio.cpp b/Build/source/libs/icu/icu-src/source/io/ustdio.cpp
index d6eb5cf9ec9..a3cb2a5d9cb 100644
--- a/Build/source/libs/icu/icu-src/source/io/ustdio.cpp
+++ b/Build/source/libs/icu/icu-src/source/io/ustdio.cpp
@@ -628,7 +628,7 @@ ufile_getch32(UFILE *f, UChar32 *c32)
/* Fill the buffer if it is empty */
str = &f->str;
- if (f && str->fPos + 1 >= str->fLimit) {
+ if (str->fPos + 1 >= str->fLimit) {
ufile_fill_uchar_buffer(f);
}
diff --git a/Build/source/libs/icu/icu-src/source/layoutex/layoutex.vcxproj b/Build/source/libs/icu/icu-src/source/layoutex/layoutex.vcxproj
index 810bbba913c..c9cbce51e79 100644
--- a/Build/source/libs/icu/icu-src/source/layoutex/layoutex.vcxproj
+++ b/Build/source/libs/icu/icu-src/source/layoutex/layoutex.vcxproj
@@ -54,7 +54,7 @@
<CompileAs>Default</CompileAs>
</ClCompile>
<Link>
- <OutputFile>..\..\bin\iculx70.dll</OutputFile>
+ <OutputFile>..\..\bin\iculx71.dll</OutputFile>
<AdditionalDependencies>icuuc.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>.\..\..\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>.\..\..\lib\iculx.pdb</ProgramDatabaseFile>
@@ -79,7 +79,7 @@
<CompileAs>Default</CompileAs>
</ClCompile>
<Link>
- <OutputFile>..\..\bin\iculx70d.dll</OutputFile>
+ <OutputFile>..\..\bin\iculx71d.dll</OutputFile>
<AdditionalDependencies>icuucd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>.\..\..\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -104,7 +104,7 @@
<CompileAs>Default</CompileAs>
</ClCompile>
<Link>
- <OutputFile>..\..\bin64\iculx70.dll</OutputFile>
+ <OutputFile>..\..\bin64\iculx71.dll</OutputFile>
<AdditionalDependencies>icuuc.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>.\..\..\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>.\..\..\lib64\iculx.pdb</ProgramDatabaseFile>
@@ -127,7 +127,7 @@
<CompileAs>Default</CompileAs>
</ClCompile>
<Link>
- <OutputFile>..\..\bin64\iculx70d.dll</OutputFile>
+ <OutputFile>..\..\bin64\iculx71d.dll</OutputFile>
<AdditionalDependencies>icuucd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>.\..\..\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
diff --git a/Build/source/libs/icu/icu-src/source/samples/Makefile.in b/Build/source/libs/icu/icu-src/source/samples/Makefile.in
index 374a70f3525..8f2514bfd00 100644
--- a/Build/source/libs/icu/icu-src/source/samples/Makefile.in
+++ b/Build/source/libs/icu/icu-src/source/samples/Makefile.in
@@ -23,7 +23,7 @@ include @platform_make_fragment@
CLEANFILES = *~
SUBDIRS = date cal
-ALLSUBDIRS = break case csdet datefmt msgfmt numfmt props translit ucnv udata ufortune uresb ustring citer uciter8 ugrep
+ALLSUBDIRS = cal citer coll csdet date datecal ufortune uresb datefmt msgfmt numfmt props strsrch translit uciter8 ucnv udata ustring dtitvfmtsample dtptngsample plurfmtsample
## List of phony targets
.PHONY : all all-local all-recursive install install-local \
diff --git a/Build/source/libs/icu/icu-src/source/samples/case/ucase.c b/Build/source/libs/icu/icu-src/source/samples/case/ucase.c
index 439c3c5b684..3cabe22d606 100644
--- a/Build/source/libs/icu/icu-src/source/samples/case/ucase.c
+++ b/Build/source/libs/icu/icu-src/source/samples/case/ucase.c
@@ -17,6 +17,9 @@
*******************************************************************************
*/
+#include <stdio.h>
+#include <stdlib.h>
+
#include "unicode/uchar.h"
#include "unicode/ustring.h"
#include "unicode/utypes.h"
diff --git a/Build/source/libs/icu/icu-src/source/samples/citer/citer.cpp b/Build/source/libs/icu/icu-src/source/samples/citer/citer.cpp
index 958fe42587e..f8193707144 100644
--- a/Build/source/libs/icu/icu-src/source/samples/citer/citer.cpp
+++ b/Build/source/libs/icu/icu-src/source/samples/citer/citer.cpp
@@ -73,7 +73,7 @@ void Test::TestUChariter() {
test2->getText(result2);
if (result1 != result2) {
u_fprintf(out, "iter.getText() != clone.getText()\n");
- }
+ }
u_fprintf(out, "\n");
@@ -95,7 +95,7 @@ void Test::TestUChariter() {
u_fprintf(out, "Iterator reached end prematurely");
}
else if (c != testText[i]) {
- u_fprintf(out, "Character mismatch at position %d\n" + i);
+ u_fprintf(out, "Character mismatch at position %d\n", i);
}
if (iter.current() != c) {
u_fprintf(out, "current() isn't working right");
@@ -111,7 +111,7 @@ void Test::TestUChariter() {
u_fprintf(out, "|");
printUChar(c);
- } while (c != CharacterIterator::DONE);
+ } while (c != CharacterIterator::DONE);
delete test2;
u_fprintf(out, "\n");
@@ -146,7 +146,7 @@ void Test::TestStringiter() {
int32_t i = iter.endIndex();
printUChar(c);
- i--; // already printed out the last char
+ i--; // already printed out the last char
if (iter.startIndex() != 0 || iter.endIndex() != u_strlen(testText)) {
u_fprintf(out, "startIndex() or endIndex() failed\n");
diff --git a/Build/source/libs/icu/icu-src/source/samples/coll/coll.cpp b/Build/source/libs/icu/icu-src/source/samples/coll/coll.cpp
index d8d067a8520..909412f5b67 100644
--- a/Build/source/libs/icu/icu-src/source/samples/coll/coll.cpp
+++ b/Build/source/libs/icu/icu-src/source/samples/coll/coll.cpp
@@ -45,8 +45,8 @@ const char gHelpString[] =
* These global variables are set according to the options specified
* on the command line by the user.
*/
-char * opt_locale = "en_US";
-char * opt_rules = 0;
+char const *opt_locale = "en_US";
+char *opt_rules = 0;
UBool opt_help = false;
UBool opt_norm = false;
UBool opt_french = false;
@@ -55,8 +55,8 @@ UBool opt_lower = false;
UBool opt_upper = false;
UBool opt_case = false;
int opt_level = 0;
-char * opt_source = "abc";
-char * opt_target = "abd";
+char const *opt_source = "abc";
+char const *opt_target = "abd";
UCollator * collator = 0;
/**
diff --git a/Build/source/libs/icu/icu-src/source/samples/datecal/cal.cpp b/Build/source/libs/icu/icu-src/source/samples/datecal/cal.cpp
index ba581b88d80..f8c0ef500bc 100644
--- a/Build/source/libs/icu/icu-src/source/samples/datecal/cal.cpp
+++ b/Build/source/libs/icu/icu-src/source/samples/datecal/cal.cpp
@@ -17,6 +17,8 @@
#include "unicode/gregocal.h"
#include <stdio.h>
+using namespace icu;
+
extern "C" void c_main();
void cpp_main()
diff --git a/Build/source/libs/icu/icu-src/source/samples/dtitvfmtsample/Makefile b/Build/source/libs/icu/icu-src/source/samples/dtitvfmtsample/Makefile
new file mode 100644
index 00000000000..404c9603c74
--- /dev/null
+++ b/Build/source/libs/icu/icu-src/source/samples/dtitvfmtsample/Makefile
@@ -0,0 +1,27 @@
+# Copyright (C) 2016 and later: Unicode, Inc. and others.
+# License & terms of use: http://www.unicode.org/copyright.html
+#
+# Copyright (c) 2000-2006 IBM, Inc. and others
+# sample code makefile
+
+# Usage:
+# - configure, build, install ICU (make install)
+# - make sure "icu-config" (in the ICU installed bin directory) is on
+# the path
+# - do 'make' in this directory
+
+#### definitions
+# Name of your target
+TARGET=dtitvfmtsample
+
+# All object files (C or C++)
+OBJECTS=dtitvfmtsample.o
+
+#### rules
+# Load in standard makefile definitions
+include ../defs.mk
+
+LDFLAGS += $(LDFLAGS_USTDIO)
+
+# the actual rules (this is a simple sample)
+include ../rules.mk
diff --git a/Build/source/libs/icu/icu-src/source/samples/dtitvfmtsample/dtitvfmtsample.cpp b/Build/source/libs/icu/icu-src/source/samples/dtitvfmtsample/dtitvfmtsample.cpp
index c4f7b18c89e..3644fe01687 100644
--- a/Build/source/libs/icu/icu-src/source/samples/dtitvfmtsample/dtitvfmtsample.cpp
+++ b/Build/source/libs/icu/icu-src/source/samples/dtitvfmtsample/dtitvfmtsample.cpp
@@ -15,130 +15,130 @@ using namespace std;
using namespace icu;
static void dtitvfmtPreDefined() {
-
- u_printf("===============================================================================\n");
- u_printf(" dtitvfmtPreDefined()\n");
+
+ u_printf("===============================================================================\n");
+ u_printf(" dtitvfmtPreDefined()\n");
u_printf("\n");
u_printf(" Use DateIntervalFormat to get date interval format for pre-defined skeletons:\n");
u_printf(" yMMMd, MMMMd, jm per locale\n");
u_printf("===============================================================================\n");
-
- //! [dtitvfmtPreDefined]
- UFILE *out = u_finit(stdout, NULL, "UTF-8");
- UErrorCode status =U_ZERO_ERROR;
- // create 3 Date Intervals
- UnicodeString data[] = {
- UnicodeString("2007-10-10 10:10:10"),
- UnicodeString("2008-10-10 10:10:10"),
- UnicodeString("2008-11-10 10:10:10"),
- UnicodeString("2008-11-10 15:10:10")
- };
- Calendar *cal = Calendar::createInstance(status);
- cal->set(2007,10,10,10,10,10);
- UDate date1 = cal->getTime(status);
- cal->set(2008,10,10,10,10,10);
- UDate date2 = cal->getTime(status);
- cal->set(2008,11,10,10,10,10);
- UDate date3 = cal->getTime(status);
- cal->set(2008,11,10,15,10,10);
- UDate date4 = cal->getTime(status);
+
+ //! [dtitvfmtPreDefined]
+ UFILE *out = u_finit(stdout, NULL, "UTF-8");
+ UErrorCode status =U_ZERO_ERROR;
+ // create 3 Date Intervals
+ UnicodeString data[] = {
+ UnicodeString("2007-10-10 10:10:10"),
+ UnicodeString("2008-10-10 10:10:10"),
+ UnicodeString("2008-11-10 10:10:10"),
+ UnicodeString("2008-11-10 15:10:10")
+ };
+ Calendar *cal = Calendar::createInstance(status);
+ cal->set(2007,10,10,10,10,10);
+ UDate date1 = cal->getTime(status);
+ cal->set(2008,10,10,10,10,10);
+ UDate date2 = cal->getTime(status);
+ cal->set(2008,11,10,10,10,10);
+ UDate date3 = cal->getTime(status);
+ cal->set(2008,11,10,15,10,10);
+ UDate date4 = cal->getTime(status);
DateInterval* dtitvsample[] = {
- new DateInterval(date1,date2),
+ new DateInterval(date1,date2),
new DateInterval(date2,date3),
- new DateInterval(date3,date4),
+ new DateInterval(date3,date4),
};
- UnicodeString skeletons[] = {
+ UnicodeString skeletons[] = {
UnicodeString("yMMMd"),
UnicodeString("MMMMd"),
UnicodeString("jm"),
- 0,
- };
+ UnicodeString("")
+ };
u_fprintf(out,"%-10s%-22s%-22s%-35s%-35s\n", "Skeleton","from","to","Date Interval in en_US","Date Interval in Ja");
- int i=0;
- UnicodeString formatEn,formatJa;
- FieldPosition pos=0;
- for (int j=0;skeletons[j]!=NULL ;j++) {
- u_fprintf(out,"%-10S%-22S%-22S",skeletons[j].getTerminatedBuffer(),data[i].getTerminatedBuffer(),data[i+1].getTerminatedBuffer());
+ int i=0;
+ UnicodeString formatEn,formatJa;
+ FieldPosition pos=0;
+ for (int j=0; !skeletons[j].isEmpty() ;j++) {
+ u_fprintf(out,"%-10S%-22S%-22S",skeletons[j].getTerminatedBuffer(),data[i].getTerminatedBuffer(),data[i+1].getTerminatedBuffer());
//create a DateIntervalFormat instance for given skeleton, locale
- DateIntervalFormat* dtitvfmtEn = DateIntervalFormat::createInstance(skeletons[j], Locale::getEnglish(),status);
+ DateIntervalFormat* dtitvfmtEn = DateIntervalFormat::createInstance(skeletons[j], Locale::getEnglish(),status);
DateIntervalFormat* dtitvfmtJa = DateIntervalFormat::createInstance(skeletons[j], Locale::getJapanese(),status);
- formatEn.remove();
- formatJa.remove();
- //get the DateIntervalFormat
- dtitvfmtEn->format(dtitvsample[i],formatEn,pos,status);
- dtitvfmtJa->format(dtitvsample[i],formatJa,pos,status);
- u_fprintf(out,"%-35S%-35S\n", formatEn.getTerminatedBuffer(),formatJa.getTerminatedBuffer());
- delete dtitvfmtEn;
- delete dtitvfmtJa;
+ formatEn.remove();
+ formatJa.remove();
+ //get the DateIntervalFormat
+ dtitvfmtEn->format(dtitvsample[i],formatEn,pos,status);
+ dtitvfmtJa->format(dtitvsample[i],formatJa,pos,status);
+ u_fprintf(out,"%-35S%-35S\n", formatEn.getTerminatedBuffer(),formatJa.getTerminatedBuffer());
+ delete dtitvfmtEn;
+ delete dtitvfmtJa;
i++;
}
- u_fclose(out);
- //! [dtitvfmtPreDefined]
+ u_fclose(out);
+ //! [dtitvfmtPreDefined]
}
static void dtitvfmtCustomized() {
-
- u_printf("===============================================================================\n");
- u_printf("\n");
- u_printf(" dtitvfmtCustomized()\n");
- u_printf("\n");
+
+ u_printf("===============================================================================\n");
+ u_printf("\n");
+ u_printf(" dtitvfmtCustomized()\n");
+ u_printf("\n");
u_printf(" Use DateIntervalFormat to create customized date interval format for yMMMd, Hm");
- u_printf("\n");
+ u_printf("\n");
u_printf("================================================================================\n");
- //! [dtitvfmtCustomized]
- UFILE *out = u_finit(stdout, NULL, "UTF-8");
- UErrorCode status =U_ZERO_ERROR;
- UnicodeString data[] = {
- UnicodeString("2007-9-10 10:10:10"),
- UnicodeString("2007-10-10 10:10:10"),
- UnicodeString("2007-10-10 22:10:10")
- };
- // to create 2 Date Intervals
+ //! [dtitvfmtCustomized]
+ UFILE *out = u_finit(stdout, NULL, "UTF-8");
+ UErrorCode status =U_ZERO_ERROR;
+ UnicodeString data[] = {
+ UnicodeString("2007-9-10 10:10:10"),
+ UnicodeString("2007-10-10 10:10:10"),
+ UnicodeString("2007-10-10 22:10:10")
+ };
+ // to create 2 Date Intervals
Calendar *cal1 = Calendar::createInstance(status);
- cal1->set(2007,9,10,10,10,10);
- Calendar *cal2 = Calendar::createInstance(status);
- cal2->set(2007,10,10,10,10,10);
- Calendar *cal3 = Calendar::createInstance(status);
- cal3->set(2007,10,10,22,10,10);
- DateInterval* dtitvsample[] = {
- new DateInterval(cal1->getTime(status),cal2->getTime(status)),
+ cal1->set(2007,9,10,10,10,10);
+ Calendar *cal2 = Calendar::createInstance(status);
+ cal2->set(2007,10,10,10,10,10);
+ Calendar *cal3 = Calendar::createInstance(status);
+ cal3->set(2007,10,10,22,10,10);
+ DateInterval* dtitvsample[] = {
+ new DateInterval(cal1->getTime(status),cal2->getTime(status)),
new DateInterval(cal2->getTime(status),cal3->getTime(status))
- };
- UnicodeString skeletons[] = {
+ };
+ UnicodeString skeletons[] = {
UnicodeString("yMMMd"),
UnicodeString("Hm"),
- 0,
+ UnicodeString("")
};
- u_printf("%-10s%-22s%-22s%-45s%-35s\n", "Skeleton", "from","to", "Date Interval in en_US","Date Interval in Ja");
- // Create an empty DateIntervalInfo object
+ u_printf("%-10s%-22s%-22s%-45s%-35s\n", "Skeleton", "from","to", "Date Interval in en_US","Date Interval in Ja");
+ // Create an empty DateIntervalInfo object
DateIntervalInfo dtitvinf = DateIntervalInfo(status);
- // Set Date Time internal pattern for MONTH, HOUR_OF_DAY
+ // Set Date Time internal pattern for MONTH, HOUR_OF_DAY
dtitvinf.setIntervalPattern("yMMMd", UCAL_MONTH, "y 'Diff' MMM d --- MMM d",status);
dtitvinf.setIntervalPattern("Hm", UCAL_HOUR_OF_DAY, "yyyy MMM d HH:mm ~ HH:mm",status);
- // Set fallback interval pattern
+ // Set fallback interval pattern
dtitvinf.setFallbackIntervalPattern("{0} ~~~ {1}",status);
- // Get the DateIntervalFormat with the custom pattern
+ // Get the DateIntervalFormat with the custom pattern
UnicodeString formatEn,formatJa;
- FieldPosition pos=0;
- for (int i=0;i<2;i++){
- for (int j=0;skeletons[j]!=NULL;j++) {
- u_fprintf(out,"%-10S%-22S%-22S", skeletons[i].getTerminatedBuffer(),data[j].getTerminatedBuffer(), data[j+1].getTerminatedBuffer());
+ FieldPosition pos=0;
+ for (int i=0;i<2;i++){
+ for (int j=0;!skeletons[j].isEmpty();j++) {
+ u_fprintf(out,"%-10S%-22S%-22S", skeletons[i].getTerminatedBuffer(),data[j].getTerminatedBuffer(), data[j+1].getTerminatedBuffer());
DateIntervalFormat* dtitvfmtEn = DateIntervalFormat::createInstance(skeletons[i],Locale::getEnglish(),dtitvinf,status);
DateIntervalFormat* dtitvfmtJa = DateIntervalFormat::createInstance(skeletons[i],Locale::getJapanese(),dtitvinf,status);
- formatEn.remove();
- formatJa.remove();
- dtitvfmtEn->format(dtitvsample[j],formatEn,pos,status);
- dtitvfmtJa->format(dtitvsample[j],formatJa,pos,status);
- u_fprintf(out,"%-45S%-35S\n", formatEn.getTerminatedBuffer(),formatJa.getTerminatedBuffer());
+ formatEn.remove();
+ formatJa.remove();
+ dtitvfmtEn->format(dtitvsample[j],formatEn,pos,status);
+ dtitvfmtJa->format(dtitvsample[j],formatJa,pos,status);
+ u_fprintf(out,"%-45S%-35S\n", formatEn.getTerminatedBuffer(),formatJa.getTerminatedBuffer());
}
}
- u_fclose(out);
- //! [dtitvfmtCustomized]
+ u_fclose(out);
+ //! [dtitvfmtCustomized]
}
int main (int argc, char* argv[])
{
- dtitvfmtPreDefined();
- dtitvfmtCustomized();
- return 0;
+ dtitvfmtPreDefined();
+ dtitvfmtCustomized();
+ return 0;
}
diff --git a/Build/source/libs/icu/icu-src/source/samples/dtptngsample/Makefile b/Build/source/libs/icu/icu-src/source/samples/dtptngsample/Makefile
new file mode 100644
index 00000000000..95393190014
--- /dev/null
+++ b/Build/source/libs/icu/icu-src/source/samples/dtptngsample/Makefile
@@ -0,0 +1,27 @@
+# Copyright (C) 2016 and later: Unicode, Inc. and others.
+# License & terms of use: http://www.unicode.org/copyright.html
+#
+# Copyright (c) 2000-2006 IBM, Inc. and others
+# sample code makefile
+
+# Usage:
+# - configure, build, install ICU (make install)
+# - make sure "icu-config" (in the ICU installed bin directory) is on
+# the path
+# - do 'make' in this directory
+
+#### definitions
+# Name of your target
+TARGET=dtptngsample
+
+# All object files (C or C++)
+OBJECTS=dtptngsample.o
+
+#### rules
+# Load in standard makefile definitions
+include ../defs.mk
+
+LDFLAGS += $(LDFLAGS_USTDIO)
+
+# the actual rules (this is a simple sample)
+include ../rules.mk
diff --git a/Build/source/libs/icu/icu-src/source/samples/dtptngsample/dtptngsample.cpp b/Build/source/libs/icu/icu-src/source/samples/dtptngsample/dtptngsample.cpp
index 58d394d57df..1c39f9794f9 100644
--- a/Build/source/libs/icu/icu-src/source/samples/dtptngsample/dtptngsample.cpp
+++ b/Build/source/libs/icu/icu-src/source/samples/dtptngsample/dtptngsample.cpp
@@ -1,7 +1,7 @@
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/********************************************************************
- * COPYRIGHT:
+ * COPYRIGHT:
* Copyright (c) 2008-2014, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
@@ -16,151 +16,151 @@ using namespace std;
using namespace icu;
static void getBestPatternExample() {
-
- u_printf("========================================================================\n");
- u_printf(" getBestPatternExample()\n");
+
+ u_printf("========================================================================\n");
+ u_printf(" getBestPatternExample()\n");
u_printf("\n");
u_printf(" Use DateTimePatternGenerator to create customized date/time pattern:\n");
u_printf(" yQQQQ,yMMMM, MMMMd, hhmm, jjmm per locale\n");
u_printf("========================================================================\n");
- //! [getBestPatternExample]
- UnicodeString skeletons [] = {
- UnicodeString("yQQQQ"), // year + full name of quarter, i.e., 4th quarter 1999
+ //! [getBestPatternExample]
+ UnicodeString skeletons [] = {
+ UnicodeString("yQQQQ"), // year + full name of quarter, i.e., 4th quarter 1999
UnicodeString("yMMMM"), // year + full name of month, i.e., October 1999
UnicodeString("MMMMd"), // full name of month + day of the month, i.e., October 25
UnicodeString("hhmm"), // 12-hour-cycle format, i.e., 1:32 PM
UnicodeString("jjmm"), // preferred hour format for the given locale, i.e., 24-hour-cycle format for fr_FR
- 0,
- };
+ 0,
+ };
+
+ Locale locales[] = {
+ Locale ("en_US"),
+ Locale ("fr_FR"),
+ Locale ("zh_CN"),
+ };
- Locale locales[] = {
- Locale ("en_US"),
- Locale ("fr_FR"),
- Locale ("zh_CN"),
- };
-
- const char* filename = "sample.txt";
- /* open a UTF-8 file for writing */
- UFILE* f = u_fopen(filename, "w", NULL,"UTF-8");
- UnicodeString dateReturned;
- UErrorCode status =U_ZERO_ERROR;
- Calendar *cal = Calendar::createInstance(status);
- cal->set (1999,9,13,23,58,59);
- UDate date = cal->getTime(status);
- u_fprintf(f, "%-20S%-20S%-20S%-20S\n", UnicodeString("Skeleton").getTerminatedBuffer(),UnicodeString("en_US").getTerminatedBuffer(),UnicodeString("fr_FR").getTerminatedBuffer(),UnicodeString("zh_CN").getTerminatedBuffer());
- for (int i=0;skeletons[i]!=NULL;i++) {
- u_fprintf(f, "%-20S",skeletons[i].getTerminatedBuffer());
- for (int j=0;j<sizeof(locales)/sizeof(locales[0]);j++) {
- // create a DateTimePatternGenerator instance for given locale
- DateTimePatternGenerator *dtfg= DateTimePatternGenerator::createInstance(locales[j],status);
- // use getBestPattern method to get the best pattern for the given skeleton
- UnicodeString pattern = dtfg->getBestPattern(skeletons[i],status);
- // Constructs a SimpleDateFormat with the best pattern generated above and the given locale
- SimpleDateFormat *sdf = new SimpleDateFormat(pattern,locales[j],status);
- dateReturned.remove();
- // Get the format of the given date
- sdf->format(date,dateReturned,status);
- /* write Unicode string to file */
- u_fprintf(f, "%-20S", dateReturned.getTerminatedBuffer());
- delete dtfg;
- delete sdf;
- }
- u_fprintf(f,"\n");
- }
- /* close the file resource */
- u_fclose(f);
- delete cal;
- //! [getBestPatternExample]
+ const char* filename = "sample.txt";
+ /* open a UTF-8 file for writing */
+ UFILE* f = u_fopen(filename, "w", NULL,"UTF-8");
+ UnicodeString dateReturned;
+ UErrorCode status =U_ZERO_ERROR;
+ Calendar *cal = Calendar::createInstance(status);
+ cal->set (1999,9,13,23,58,59);
+ UDate date = cal->getTime(status);
+ u_fprintf(f, "%-20S%-20S%-20S%-20S\n", UnicodeString("Skeleton").getTerminatedBuffer(),UnicodeString("en_US").getTerminatedBuffer(),UnicodeString("fr_FR").getTerminatedBuffer(),UnicodeString("zh_CN").getTerminatedBuffer());
+ for (int i=0;!skeletons[i].isEmpty();i++) {
+ u_fprintf(f, "%-20S",skeletons[i].getTerminatedBuffer());
+ for (int j=0;j<sizeof(locales)/sizeof(locales[0]);j++) {
+ // create a DateTimePatternGenerator instance for given locale
+ DateTimePatternGenerator *dtfg= DateTimePatternGenerator::createInstance(locales[j],status);
+ // use getBestPattern method to get the best pattern for the given skeleton
+ UnicodeString pattern = dtfg->getBestPattern(skeletons[i],status);
+ // Constructs a SimpleDateFormat with the best pattern generated above and the given locale
+ SimpleDateFormat *sdf = new SimpleDateFormat(pattern,locales[j],status);
+ dateReturned.remove();
+ // Get the format of the given date
+ sdf->format(date,dateReturned,status);
+ /* write Unicode string to file */
+ u_fprintf(f, "%-20S", dateReturned.getTerminatedBuffer());
+ delete dtfg;
+ delete sdf;
+ }
+ u_fprintf(f,"\n");
+ }
+ /* close the file resource */
+ u_fclose(f);
+ delete cal;
+ //! [getBestPatternExample]
}
static void addPatternExample() {
-
- u_printf("========================================================================\n");
+
+ u_printf("========================================================================\n");
u_printf(" addPatternExample()\n");
- u_printf("\n");
+ u_printf("\n");
u_printf(" Use addPattern API to add new '. von' to existing pattern\n");
u_printf("========================================================================\n");
- //! [addPatternExample]
- UErrorCode status =U_ZERO_ERROR;
- UnicodeString conflictingPattern,dateReturned, pattern;
- Locale locale=Locale::getFrance();
- Calendar *cal = Calendar::createInstance(status);
- cal->set (1999,9,13,23,58,59);
- UDate date = cal->getTime(status);
+ //! [addPatternExample]
+ UErrorCode status =U_ZERO_ERROR;
+ UnicodeString conflictingPattern,dateReturned, pattern;
+ Locale locale=Locale::getFrance();
+ Calendar *cal = Calendar::createInstance(status);
+ cal->set (1999,9,13,23,58,59);
+ UDate date = cal->getTime(status);
// Create an DateTimePatternGenerator instance for the given locale
- DateTimePatternGenerator *dtfg= DateTimePatternGenerator::createInstance(locale,status);
- SimpleDateFormat *sdf = new SimpleDateFormat(dtfg->getBestPattern("MMMMddHmm",status),locale,status);
+ DateTimePatternGenerator *dtfg= DateTimePatternGenerator::createInstance(locale,status);
+ SimpleDateFormat *sdf = new SimpleDateFormat(dtfg->getBestPattern("MMMMddHmm",status),locale,status);
// Add '. von' to the existing pattern
dtfg->addPattern("dd'. von' MMMM", true, conflictingPattern,status);
// Apply the new pattern
sdf->applyPattern(dtfg->getBestPattern("MMMMddHmm",status));
- dateReturned = sdf->format(date, dateReturned, status);
- pattern =sdf->toPattern(pattern);
- u_printf("%s\n", "New Pattern for FRENCH: ");
- u_printf("%S\n", pattern.getTerminatedBuffer());
- u_printf("%s\n", "Date Time in new Pattern: ");
- u_printf("%S\n", dateReturned.getTerminatedBuffer());
- delete dtfg;
- delete sdf;
- delete cal;
+ dateReturned = sdf->format(date, dateReturned, status);
+ pattern =sdf->toPattern(pattern);
+ u_printf("%s\n", "New Pattern for FRENCH: ");
+ u_printf("%S\n", pattern.getTerminatedBuffer());
+ u_printf("%s\n", "Date Time in new Pattern: ");
+ u_printf("%S\n", dateReturned.getTerminatedBuffer());
+ delete dtfg;
+ delete sdf;
+ delete cal;
- //! [addPatternExample]
+ //! [addPatternExample]
/* output of the sample code:
************************************************************************************************
New Pattern for FRENCH: dd. 'von' MMMM HH:mm
Date Time in new Pattern: 13. von octobre 23:58
-
+
*************************************************************************************************/
- }
+ }
static void replaceFieldTypesExample() {
- // Use repalceFieldTypes API to replace zone 'zzzz' with 'vvvv'
+ // Use repalceFieldTypes API to replace zone 'zzzz' with 'vvvv'
u_printf("========================================================================\n");
u_printf(" replaceFieldTypeExample()\n");
u_printf("\n");
u_printf(" Use replaceFieldTypes API to replace zone 'zzzz' with 'vvvv'\n");
u_printf("========================================================================\n");
- //! [replaceFieldTypesExample]
- UFILE *out = u_finit(stdout, NULL, "UTF-8");
- UErrorCode status =U_ZERO_ERROR;
- UnicodeString pattern,dateReturned;
- Locale locale =Locale::getFrance();
- Calendar *cal = Calendar::createInstance(status);
- cal->set (1999,9,13,23,58,59);
- UDate date = cal->getTime(status);
- TimeZone *zone = TimeZone::createTimeZone(UnicodeString("Europe/Paris"));
- DateTimePatternGenerator *dtfg = DateTimePatternGenerator::createInstance(locale,status);
- SimpleDateFormat *sdf = new SimpleDateFormat("EEEE d MMMM y HH:mm:ss zzzz",locale,status);
- sdf->setTimeZone(*zone);
- pattern = sdf->toPattern(pattern);
- u_fprintf(out, "%S\n", UnicodeString("Pattern before replacement:").getTerminatedBuffer());
- u_fprintf(out, "%S\n", pattern.getTerminatedBuffer());
- dateReturned.remove();
- dateReturned = sdf->format(date, dateReturned, status);
- u_fprintf(out, "%S\n", UnicodeString("Date/Time format in fr_FR:").getTerminatedBuffer());
- u_fprintf(out, "%S\n", dateReturned.getTerminatedBuffer());
+ //! [replaceFieldTypesExample]
+ UFILE *out = u_finit(stdout, NULL, "UTF-8");
+ UErrorCode status =U_ZERO_ERROR;
+ UnicodeString pattern,dateReturned;
+ Locale locale =Locale::getFrance();
+ Calendar *cal = Calendar::createInstance(status);
+ cal->set (1999,9,13,23,58,59);
+ UDate date = cal->getTime(status);
+ TimeZone *zone = TimeZone::createTimeZone(UnicodeString("Europe/Paris"));
+ DateTimePatternGenerator *dtfg = DateTimePatternGenerator::createInstance(locale,status);
+ SimpleDateFormat *sdf = new SimpleDateFormat("EEEE d MMMM y HH:mm:ss zzzz",locale,status);
+ sdf->setTimeZone(*zone);
+ pattern = sdf->toPattern(pattern);
+ u_fprintf(out, "%S\n", UnicodeString("Pattern before replacement:").getTerminatedBuffer());
+ u_fprintf(out, "%S\n", pattern.getTerminatedBuffer());
+ dateReturned.remove();
+ dateReturned = sdf->format(date, dateReturned, status);
+ u_fprintf(out, "%S\n", UnicodeString("Date/Time format in fr_FR:").getTerminatedBuffer());
+ u_fprintf(out, "%S\n", dateReturned.getTerminatedBuffer());
// Replace zone "zzzz" in the pattern with "vvvv"
- UnicodeString newPattern = dtfg->replaceFieldTypes(pattern, "vvvv", status);
- // Apply the new pattern
- sdf->applyPattern(newPattern);
- dateReturned.remove();
- dateReturned = sdf->format(date, dateReturned, status);
- u_fprintf(out, "%S\n", UnicodeString("Pattern after replacement:").getTerminatedBuffer());
- u_fprintf(out, "%S\n", newPattern.getTerminatedBuffer());
- u_fprintf(out, "%S\n", UnicodeString("Date/Time format in fr_FR:").getTerminatedBuffer());
- u_fprintf(out, "%S\n", dateReturned.getTerminatedBuffer());
- delete sdf;
- delete dtfg;
- delete zone;
- delete cal;
- u_fclose(out);
- //! [replaceFieldTypesExample]
+ UnicodeString newPattern = dtfg->replaceFieldTypes(pattern, "vvvv", status);
+ // Apply the new pattern
+ sdf->applyPattern(newPattern);
+ dateReturned.remove();
+ dateReturned = sdf->format(date, dateReturned, status);
+ u_fprintf(out, "%S\n", UnicodeString("Pattern after replacement:").getTerminatedBuffer());
+ u_fprintf(out, "%S\n", newPattern.getTerminatedBuffer());
+ u_fprintf(out, "%S\n", UnicodeString("Date/Time format in fr_FR:").getTerminatedBuffer());
+ u_fprintf(out, "%S\n", dateReturned.getTerminatedBuffer());
+ delete sdf;
+ delete dtfg;
+ delete zone;
+ delete cal;
+ u_fclose(out);
+ //! [replaceFieldTypesExample]
}
int main (int argc, char* argv[])
{
- getBestPatternExample();
- addPatternExample();
- replaceFieldTypesExample();
- return 0;
+ getBestPatternExample();
+ addPatternExample();
+ replaceFieldTypesExample();
+ return 0;
}
diff --git a/Build/source/libs/icu/icu-src/source/samples/plurfmtsample/Makefile b/Build/source/libs/icu/icu-src/source/samples/plurfmtsample/Makefile
new file mode 100644
index 00000000000..ef7d7d4ace8
--- /dev/null
+++ b/Build/source/libs/icu/icu-src/source/samples/plurfmtsample/Makefile
@@ -0,0 +1,27 @@
+# Copyright (C) 2016 and later: Unicode, Inc. and others.
+# License & terms of use: http://www.unicode.org/copyright.html
+#
+# Copyright (c) 2000-2006 IBM, Inc. and others
+# sample code makefile
+
+# Usage:
+# - configure, build, install ICU (make install)
+# - make sure "icu-config" (in the ICU installed bin directory) is on
+# the path
+# - do 'make' in this directory
+
+#### definitions
+# Name of your target
+TARGET=plurfmtsample
+
+# All object files (C or C++)
+OBJECTS=plurfmtsample.o
+
+#### rules
+# Load in standard makefile definitions
+include ../defs.mk
+
+LDFLAGS += $(LDFLAGS_USTDIO)
+
+# the actual rules (this is a simple sample)
+include ../rules.mk
diff --git a/Build/source/libs/icu/icu-src/source/samples/plurfmtsample/plurfmtsample.cpp b/Build/source/libs/icu/icu-src/source/samples/plurfmtsample/plurfmtsample.cpp
index f910c4f56e1..b03e63541d4 100644
--- a/Build/source/libs/icu/icu-src/source/samples/plurfmtsample/plurfmtsample.cpp
+++ b/Build/source/libs/icu/icu-src/source/samples/plurfmtsample/plurfmtsample.cpp
@@ -19,17 +19,17 @@ using namespace std;
using namespace icu;
static void PluralFormatExample() {
-
- u_printf("=============================================================================\n");
- u_printf(" PluralFormatExample()\n");
+
+ u_printf("=============================================================================\n");
+ u_printf(" PluralFormatExample()\n");
u_printf("\n");
u_printf(" Use PluralFormat and Messageformat to get Plural Form for languages below:\n");
u_printf(" English, Slovenian\n");
u_printf("=============================================================================\n");
-
- //! [PluralFormatExample]
- UErrorCode status =U_ZERO_ERROR;
- Locale locEn = Locale("en");
+
+ //! [PluralFormatExample]
+ UErrorCode status =U_ZERO_ERROR;
+ Locale locEn = Locale("en");
Locale locSl = Locale("sl");
UnicodeString patEn = UnicodeString("one{dog} other{dogs}"); // English 'dog'
@@ -42,19 +42,19 @@ static void PluralFormatExample() {
MessageFormat* msgfmtEn = new MessageFormat("{0,number} {1}", locEn,status);
MessageFormat* msgfmtSl = new MessageFormat("{0,number} {1}", locSl,status);
- int numbers[] = {0, 1, 2, 3, 4, 5, 10, 100, 101, 102};
- u_printf("Output by using PluralFormat and MessageFormat API\n");
+ int numbers[] = {0, 1, 2, 3, 4, 5, 10, 100, 101, 102};
+ u_printf("Output by using PluralFormat and MessageFormat API\n");
u_printf("%-16s%-16s%-16s\n","Number", "English","Slovenian");
-
+
// Use MessageFormat.format () to format the objects and append to the given StringBuffer
for (int i=0;i<sizeof(numbers)/sizeof(int);i++) {
- UnicodeString msgEn,msgSl;
- FieldPosition fpos = 0;
- Formattable argEn[]={Formattable(numbers[i]), Formattable(plfmtEn.format(numbers[i],status))};
- Formattable argSl[]={Formattable(numbers[i]), Formattable(plfmtSl.format(numbers[i],status))};
- msgfmtEn->format(argEn,2,msgEn,fpos,status);
- msgfmtSl->format(argSl,2,msgSl,fpos,status);
- u_printf("%-16d%-16S%-16S\n", numbers[i], msgEn.getTerminatedBuffer(),msgSl.getTerminatedBuffer());
+ UnicodeString msgEn,msgSl;
+ FieldPosition fpos = 0;
+ Formattable argEn[]={Formattable(numbers[i]), Formattable(plfmtEn.format(numbers[i],status))};
+ Formattable argSl[]={Formattable(numbers[i]), Formattable(plfmtSl.format(numbers[i],status))};
+ msgfmtEn->format(argEn,2,msgEn,fpos,status);
+ msgfmtSl->format(argSl,2,msgSl,fpos,status);
+ u_printf("%-16d%-16S%-16S\n", numbers[i], msgEn.getTerminatedBuffer(),msgSl.getTerminatedBuffer());
}
u_printf("\n");
@@ -62,27 +62,27 @@ static void PluralFormatExample() {
// Equivalent code with message format pattern
UnicodeString msgPatEn = "{0,plural, one{# dog} other{# dogs}}";
UnicodeString msgPatSl = "{0,plural, one{# pes} two{# psa} few{# psi} other{# psov}}";
-
- MessageFormat* altMsgfmtEn = new MessageFormat(msgPatEn, locEn,status);
+
+ MessageFormat* altMsgfmtEn = new MessageFormat(msgPatEn, locEn,status);
MessageFormat* altMsgfmtSl = new MessageFormat(msgPatSl, locSl,status);
u_printf("Same Output by using MessageFormat API only\n");
u_printf("%-16s%-16s%-16s\n","Number", "English","Slovenian");
for (int i=0;i<sizeof(numbers)/sizeof(int);i++) {
UnicodeString msgEn,msgSl;
- Formattable arg[] = {numbers[i]};
- FieldPosition fPos =0;
- altMsgfmtEn->format(arg, 1, msgEn, fPos, status);
+ Formattable arg[] = {numbers[i]};
+ FieldPosition fPos =0;
+ altMsgfmtEn->format(arg, 1, msgEn, fPos, status);
altMsgfmtSl->format(arg, 1, msgSl, fPos,status);
u_printf("%-16d%-16S%-16S\n", numbers[i], msgEn.getTerminatedBuffer(), msgSl.getTerminatedBuffer());
}
- delete msgfmtEn;
- delete msgfmtSl;
- delete altMsgfmtEn;
- delete altMsgfmtSl;
- //! [PluralFormatExample]
+ delete msgfmtEn;
+ delete msgfmtSl;
+ delete altMsgfmtEn;
+ delete altMsgfmtSl;
+ //! [PluralFormatExample]
- /* output of the sample code:
+ /* output of the sample code:
********************************************************************
Number English Slovenian
0 0 dogs 0 psov
@@ -100,6 +100,6 @@ static void PluralFormatExample() {
}
int main (int argc, char* argv[])
{
- PluralFormatExample();
- return 0;
+ PluralFormatExample();
+ return 0;
}
diff --git a/Build/source/libs/icu/icu-src/source/samples/readme.txt b/Build/source/libs/icu/icu-src/source/samples/readme.txt
index 0ef21771da8..1dfef216d96 100644
--- a/Build/source/libs/icu/icu-src/source/samples/readme.txt
+++ b/Build/source/libs/icu/icu-src/source/samples/readme.txt
@@ -4,36 +4,46 @@
## Copyright (c) 2002-2010, International Business Machines Corporation
## and others. All Rights Reserved.
-This directory contains sample code
-Below is a short description of the contents of this directory.
+This directory contains sample code using ICU4C routines. Below is a
+short description of the contents of this directory.
-break - demonstrates how to use BreakIterators in C and C++.
+break - demonstrates how to use BreakIterators in C and C++.
-cal - prints out a calendar.
+cal - prints out a calendar.
case - demonstrates how to do Unicode case conversion in C and C++.
+coll - shows how collation compares strings
+
csdet - demonstrates using ICU's CharSet Detection API
-date - prints out the current date, localized.
+date - prints out the current date, localized.
+
+datecal - demonstrates how a calendar object provides information
+
+datefmt - an exercise using the date formatting API
-datefmt - an exercise using the date formatting API
+dtitvfmtsample - shows how date interval format uses predefined skeletons
-layout - demonstrates the ICU LayoutEngine
+dtptngsample - uses DateTimePatternGenerator to create customized date/time pattern
+
+layout - demonstrates the ICU LayoutEngine (obsolete)
-legacy - demonstrates using two versions of ICU in one application
+legacy - demonstrates using two versions of ICU in one application (obsolete)
msgfmt - demonstrates the use of the Message Format
numfmt - demonstrates the use of the number format
+plurfmtsample - uses PluralFormat and Messageformat to get Plural Form
+
props - demonstrates the use of Unicode properties
strsrch - demonstrates how to search for patterns in Unicode text using the usearch interface.
translit - demonstrates the use of ICU transliteration
-uciter8.c - demonstrates how to leniently read 8-bit Unicode text.
+uciter8 - demonstrates how to leniently read 8-bit Unicode text.
ucnv - demonstrates the use of ICU codepage conversion
@@ -41,7 +51,7 @@ udata - demonstrates the use of ICU low level data routines (reader/writer in
ufortune - demonstrates packaging and use of resources in an application
-ugrep - demonstrates ICU Regular Expressions.
+ugrep - demonstrates ICU Regular Expressions.
uresb - demonstrates building and loading resource bundles
@@ -52,12 +62,11 @@ ustring - demonstrates ICU string manipulation functions
* Where can I find more sample code?
- The "uconv" utility is a full-featured command line application.
- It is normally built with ICU, and is located in icu/source/extra/uconv
+ It is normally built with ICU, and is located in icu/source/extra/uconv
- - The "icuapps" CVS module contains other applications and libraries not
- included with ICU. You can check it out from the CVS command line
- by using for example, "cvs co icuapps" instead of "cvs co icu",
- or through WebCVS at http://dev.icu-project.org/cgi-bin/viewcvs.cgi/icuapps/
+ - The "icu-demos" contains other applications and libraries not
+ included with ICU. You can check it out from https://github.com/unicode-org/icu-demos
+ using github clone. See the README file for additional information.
==
* How do I build the samples?
@@ -76,7 +85,7 @@ ustring - demonstrates ICU string manipulation functions
- be sure 'icu-config' is accessible from the PATH
- type 'make all-samples' from this directory
(other targets: clean-samples, check-samples)
- Note: 'make all-samples' won't work correctly in out of source builds.
+ Note: 'make all-samples' won't work correctly in out of source builds.
- - legacy and layout are not included in these lists,
- please see their individual readmes.
+ Note that legacy and layout are obsolete samples that may not compile or run without
+ adjustments to their makefiles.
diff --git a/Build/source/libs/icu/icu-src/source/samples/strsrch/strsrch.cpp b/Build/source/libs/icu/icu-src/source/samples/strsrch/strsrch.cpp
index c5fff0c40ba..c275fef66f9 100644
--- a/Build/source/libs/icu/icu-src/source/samples/strsrch/strsrch.cpp
+++ b/Build/source/libs/icu/icu-src/source/samples/strsrch/strsrch.cpp
@@ -47,7 +47,7 @@ const char gHelpString[] =
* These global variables are set according to the options specified
* on the command line by the user.
*/
-char * opt_locale = "en_US";
+char const *opt_locale = "en_US";
char * opt_rules = 0;
UBool opt_help = false;
UBool opt_norm = false;
@@ -59,8 +59,8 @@ UBool opt_case = false;
UBool opt_overlap = false;
UBool opt_canonical = false;
int opt_level = 0;
-char * opt_source = "International Components for Unicode";
-char * opt_pattern = "Unicode";
+char const *opt_source = "International Components for Unicode";
+char const *opt_pattern = "Unicode";
UCollator * collator = 0;
UStringSearch * search = 0;
UChar rules[100];
diff --git a/Build/source/libs/icu/icu-src/source/stubdata/BUILD b/Build/source/libs/icu/icu-src/source/stubdata/BUILD.bazel
index abb73519ec4..abb73519ec4 100644
--- a/Build/source/libs/icu/icu-src/source/stubdata/BUILD
+++ b/Build/source/libs/icu/icu-src/source/stubdata/BUILD.bazel
diff --git a/Build/source/libs/icu/icu-src/source/stubdata/stubdata.vcxproj b/Build/source/libs/icu/icu-src/source/stubdata/stubdata.vcxproj
index 64a6ef1a03a..5607dead597 100644
--- a/Build/source/libs/icu/icu-src/source/stubdata/stubdata.vcxproj
+++ b/Build/source/libs/icu/icu-src/source/stubdata/stubdata.vcxproj
@@ -56,7 +56,7 @@
<SetChecksum>true</SetChecksum>
<TurnOffAssemblyGeneration>true</TurnOffAssemblyGeneration>
<!-- Note: stubdata is somewhat odd in that it doesn't suffix the Debug output DLL/LIB with a "d" like common/i18n/etc. -->
- <OutputFile>..\..\$(IcuBinOutputDir)\icudt70.dll</OutputFile>
+ <OutputFile>..\..\$(IcuBinOutputDir)\icudt71.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\$(IcuLibOutputDir)\icudt.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\$(IcuLibOutputDir)\icudt.lib</ImportLibrary>
</Link>
diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/capitst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/capitst.c
index 831236d9dd7..bb49f4d674c 100644
--- a/Build/source/libs/icu/icu-src/source/test/cintltst/capitst.c
+++ b/Build/source/libs/icu/icu-src/source/test/cintltst/capitst.c
@@ -73,6 +73,7 @@ void addCollAPITest(TestNode** root)
/*addTest(root, &TestGetDefaultRules, "tscoll/capitst/TestGetDefaultRules");*/
addTest(root, &TestDecomposition, "tscoll/capitst/TestDecomposition");
addTest(root, &TestSafeClone, "tscoll/capitst/TestSafeClone");
+ addTest(root, &TestClone, "tscoll/capitst/TestClone");
addTest(root, &TestCloneBinary, "tscoll/capitst/TestCloneBinary");
addTest(root, &TestGetSetAttr, "tscoll/capitst/TestGetSetAttr");
addTest(root, &TestBounds, "tscoll/capitst/TestBounds");
@@ -806,6 +807,124 @@ void TestSafeClone() {
}
}
+void TestClone() {
+ UChar test1[6];
+ UChar test2[6];
+ static const UChar umlautUStr[] = {0x00DC, 0};
+ static const UChar oeStr[] = {0x0055, 0x0045, 0};
+ UCollator * someCollators [CLONETEST_COLLATOR_COUNT];
+ UCollator * someClonedCollators [CLONETEST_COLLATOR_COUNT];
+ UCollator * col = NULL;
+ UErrorCode err = U_ZERO_ERROR;
+ int8_t idx = 6; /* Leave this here to test buffer alignment in memory*/
+ const char sampleRuleChars[] = "&Z < CH";
+ UChar sampleRule[sizeof(sampleRuleChars)];
+
+ u_uastrcpy(test1, "abCda");
+ u_uastrcpy(test2, "abcda");
+ u_uastrcpy(sampleRule, sampleRuleChars);
+
+ /* one default collator & two complex ones */
+ someCollators[0] = ucol_open("en_US", &err);
+ someCollators[1] = ucol_open("ko", &err);
+ someCollators[2] = ucol_open("ja_JP", &err);
+ someCollators[3] = ucol_openRules(sampleRule, -1, UCOL_ON, UCOL_TERTIARY, NULL, &err);
+ if(U_FAILURE(err)) {
+ for (idx = 0; idx < CLONETEST_COLLATOR_COUNT; idx++) {
+ ucol_close(someCollators[idx]);
+ }
+ log_data_err("Couldn't open one or more collators\n");
+ return;
+ }
+
+ /* Check the various error & informational states: */
+
+ /* Null status - just returns NULL */
+ if (NULL != ucol_clone(someCollators[0], NULL))
+ {
+ log_err("FAIL: Cloned Collator failed to deal correctly with null status\n");
+ }
+ /* error status - should return 0 & keep error the same */
+ err = U_MEMORY_ALLOCATION_ERROR;
+ if (NULL != ucol_clone(someCollators[0], &err) || err != U_MEMORY_ALLOCATION_ERROR)
+ {
+ log_err("FAIL: Cloned Collator failed to deal correctly with incoming error status\n");
+ }
+ err = U_ZERO_ERROR;
+
+ /* Verify we can use this run-time calculated size */
+ if (NULL == (col = ucol_clone(someCollators[0], &err)) || U_FAILURE(err))
+ {
+ log_err("FAIL: Collator can't be cloned.\n");
+ }
+ if (col) ucol_close(col);
+
+ if (NULL == (col = ucol_clone(someCollators[0], &err)) || err != U_ZERO_ERROR)
+ {
+ log_err("FAIL: Cloned Collator failed to deal correctly\n");
+ }
+ if (col) ucol_close(col);
+ err = U_ZERO_ERROR;
+
+ /* Null Collator - return NULL & set U_ILLEGAL_ARGUMENT_ERROR */
+ if (NULL != ucol_clone(NULL, &err) || err != U_ILLEGAL_ARGUMENT_ERROR)
+ {
+ log_err("FAIL: Cloned Collator failed to deal correctly with null Collator pointer\n");
+ }
+ err = U_ZERO_ERROR;
+
+ /* Test that a cloned collator doesn't accidentally use UCA. */
+ col=ucol_open("de@collation=phonebook", &err);
+ someClonedCollators[0] = ucol_clone(col, &err);
+ doAssert( (ucol_greater(col, umlautUStr, u_strlen(umlautUStr), oeStr, u_strlen(oeStr))), "Original German phonebook collation sorts differently than expected");
+ doAssert( (ucol_greater(someClonedCollators[0], umlautUStr, u_strlen(umlautUStr), oeStr, u_strlen(oeStr))), "Cloned German phonebook collation sorts differently than expected");
+ if (!ucol_equals(someClonedCollators[0], col)) {
+ log_err("FAIL: Cloned German phonebook collator is not equal to original.\n");
+ }
+ ucol_close(col);
+ ucol_close(someClonedCollators[0]);
+
+ err = U_ZERO_ERROR;
+
+ /* change orig & clone & make sure they are independent */
+
+ for (idx = 0; idx < CLONETEST_COLLATOR_COUNT; idx++)
+ {
+ ucol_setStrength(someCollators[idx], UCOL_IDENTICAL);
+ err = U_ZERO_ERROR;
+ ucol_close(ucol_clone(someCollators[idx], &err));
+ if (err != U_ZERO_ERROR) {
+ log_err("FAIL: collator number %d was not allocated.\n", idx);
+ log_err("FAIL: status of Collator[%d] is %d (hex: %x).\n", idx, err, err);
+ }
+
+ err = U_ZERO_ERROR;
+ someClonedCollators[idx] = ucol_clone(someCollators[idx], &err);
+ if (U_FAILURE(err)) {
+ log_err("FAIL: Unable to clone collator %d - %s\n", idx, u_errorName(err));
+ continue;
+ }
+ if (!ucol_equals(someClonedCollators[idx], someCollators[idx])) {
+ log_err("FAIL: Cloned collator is not equal to original at index = %d.\n", idx);
+ }
+
+ /* Check the usability */
+ ucol_setStrength(someCollators[idx], UCOL_PRIMARY);
+ ucol_setAttribute(someCollators[idx], UCOL_CASE_LEVEL, UCOL_OFF, &err);
+
+ doAssert( (ucol_equal(someCollators[idx], test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"abcda\" == \"abCda\"");
+
+ /* Close the original to make sure that the clone is usable. */
+ ucol_close(someCollators[idx]);
+
+ ucol_setStrength(someClonedCollators[idx], UCOL_TERTIARY);
+ ucol_setAttribute(someClonedCollators[idx], UCOL_CASE_LEVEL, UCOL_OFF, &err);
+ doAssert( (ucol_greater(someClonedCollators[idx], test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"abCda\" >>> \"abcda\" ");
+
+ ucol_close(someClonedCollators[idx]);
+ }
+}
+
void TestCloneBinary(){
UErrorCode err = U_ZERO_ERROR;
UCollator * col = ucol_open("en_US", &err);
diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/capitst.h b/Build/source/libs/icu/icu-src/source/test/cintltst/capitst.h
index 7f6f558b0d3..5c761fad895 100644
--- a/Build/source/libs/icu/icu-src/source/test/cintltst/capitst.h
+++ b/Build/source/libs/icu/icu-src/source/test/cintltst/capitst.h
@@ -75,6 +75,11 @@
void TestSafeClone(void);
/**
+ * Test ucol_clone ()
+ **/
+ void TestClone(void);
+
+ /**
* Test ucol_cloneBinary(), ucol_openBinary()
**/
void TestCloneBinary(void);
diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/cbiditst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/cbiditst.c
index 6d233130fe0..38be9c50564 100644
--- a/Build/source/libs/icu/icu-src/source/test/cintltst/cbiditst.c
+++ b/Build/source/libs/icu/icu-src/source/test/cintltst/cbiditst.c
@@ -4591,6 +4591,15 @@ testClassOverride(void) {
ubidi_close(pBiDi);
return;
}
+ // Quick callback test (API coverage).
+ if (ubidi_getCustomizedClass(pBiDi, u'A')!=AL ||
+ ubidi_getCustomizedClass(pBiDi, u'H')!=R ||
+ ubidi_getCustomizedClass(pBiDi, u'^')!=PDF ||
+ ubidi_getCustomizedClass(pBiDi, u'~')!=BN) {
+ log_err("ubidi_getCustomizedClass() returns different values than "
+ "expected from overrideBidiClass() customClasses[]\n");
+ }
+
verifyCallbackParams(oldFn, oldContext, NULL, NULL, 0);
ubidi_getClassCallback(pBiDi, &oldFn, &oldContext);
diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/ccapitst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/ccapitst.c
index 50750137908..aee75e6dd9d 100644
--- a/Build/source/libs/icu/icu-src/source/test/cintltst/ccapitst.c
+++ b/Build/source/libs/icu/icu-src/source/test/cintltst/ccapitst.c
@@ -64,6 +64,7 @@ static void TestJ1968(void);
static void TestLMBCSMaxChar(void);
#endif
+static void TestConvertClone(void);
#if !UCONFIG_NO_LEGACY_CONVERSION
static void TestConvertSafeCloneCallback(void);
#endif
@@ -94,6 +95,7 @@ void addTestConvert(TestNode** root)
addTest(root, &TestAlias, "tsconv/ccapitst/TestAlias");
addTest(root, &TestDuplicateAlias, "tsconv/ccapitst/TestDuplicateAlias");
addTest(root, &TestConvertSafeClone, "tsconv/ccapitst/TestConvertSafeClone");
+ addTest(root, &TestConvertClone, "tsconv/ccapitst/TestConvertClone");
#if !UCONFIG_NO_LEGACY_CONVERSION
addTest(root, &TestConvertSafeCloneCallback,"tsconv/ccapitst/TestConvertSafeCloneCallback");
#endif
@@ -1901,6 +1903,138 @@ static void TestConvertSafeClone()
}
}
+
+static void TestConvertClone()
+{
+ /* one 'regular' & all the 'private stateful' converters */
+ static const char *const names[] = {
+#if !UCONFIG_NO_LEGACY_CONVERSION
+ "ibm-1047",
+ "ISO_2022,locale=zh,version=1",
+#endif
+ "SCSU",
+#if !UCONFIG_NO_LEGACY_CONVERSION
+ "HZ",
+ "lmbcs",
+ "ISCII,version=0",
+ "ISO_2022,locale=kr,version=1",
+ "ISO_2022,locale=jp,version=2",
+#endif
+ "BOCU-1",
+ "UTF-7",
+#if !UCONFIG_NO_LEGACY_CONVERSION
+ "IMAP-mailbox-name",
+ "ibm-1047-s390"
+#else
+ "IMAP=mailbox-name"
+#endif
+ };
+
+ char charBuffer[21]; /* Leave at an odd number for alignment testing */
+ UConverter * cnv, *cnv2;
+ UErrorCode err;
+
+ char *pCharBuffer;
+ const char *pConstCharBuffer;
+ const char *charBufferLimit = charBuffer + UPRV_LENGTHOF(charBuffer);
+ UChar uniBuffer[] = {0x0058, 0x0059, 0x005A}; /* "XYZ" */
+ UChar uniCharBuffer[20];
+ char charSourceBuffer[] = { 0x1b, 0x24, 0x42 };
+ const char *pCharSource = charSourceBuffer;
+ const char *pCharSourceLimit = charSourceBuffer + sizeof(charSourceBuffer);
+ UChar *pUCharTarget = uniCharBuffer;
+ UChar *pUCharTargetLimit = uniCharBuffer + UPRV_LENGTHOF(uniCharBuffer);
+ const UChar * pUniBuffer;
+ const UChar *uniBufferLimit = uniBuffer + UPRV_LENGTHOF(uniBuffer);
+ int32_t idx;
+
+ err = U_ZERO_ERROR;
+ cnv = ucnv_open(names[0], &err);
+ if(U_SUCCESS(err)) {
+ /* Check the various error & informational states: */
+
+ /* Null status - just returns NULL */
+ if (NULL != ucnv_clone(cnv, NULL))
+ {
+ log_err("FAIL: Cloned converter failed to deal correctly with null status\n");
+ }
+ /* error status - should return 0 & keep error the same */
+ err = U_MEMORY_ALLOCATION_ERROR;
+ if (NULL != ucnv_clone(cnv, &err) || err != U_MEMORY_ALLOCATION_ERROR)
+ {
+ log_err("FAIL: Cloned converter failed to deal correctly with incoming error status\n");
+ }
+ err = U_ZERO_ERROR;
+
+ /* Null buffer size pointer is ok */
+ if (NULL == (cnv2 = ucnv_clone(cnv, &err)) || U_FAILURE(err))
+ {
+ log_err("FAIL: Failed to clone.\n");
+ }
+ ucnv_close(cnv2);
+ err = U_ZERO_ERROR;
+
+ /* Null converter - return NULL & set U_ILLEGAL_ARGUMENT_ERROR */
+ if (NULL != ucnv_clone(NULL, &err) || err != U_ILLEGAL_ARGUMENT_ERROR)
+ {
+ log_err("FAIL: Cloned converter failed to deal correctly with null converter pointer\n");
+ }
+
+ ucnv_close(cnv);
+ }
+
+ /* Do these cloned converters work at all - shuffle UChars to chars & back again..*/
+ for (idx = 0; idx < UPRV_LENGTHOF(names); idx++)
+ {
+ err = U_ZERO_ERROR;
+ cnv = ucnv_open(names[idx], &err);
+ if(U_FAILURE(err)) {
+ log_data_err("ucnv_open(\"%s\") failed - %s\n", names[idx], u_errorName(err));
+ continue;
+ }
+
+ cnv2 = ucnv_clone(cnv, &err);
+
+ /* close the original immediately to make sure that the clone works by itself */
+ ucnv_close(cnv);
+
+ pCharBuffer = charBuffer;
+ pUniBuffer = uniBuffer;
+
+ ucnv_fromUnicode(cnv2,
+ &pCharBuffer,
+ charBufferLimit,
+ &pUniBuffer,
+ uniBufferLimit,
+ NULL,
+ TRUE,
+ &err);
+ if(U_FAILURE(err)){
+ log_err("FAIL: cloned converter failed to do fromU conversion. Error: %s\n",u_errorName(err));
+ }
+ ucnv_toUnicode(cnv2,
+ &pUCharTarget,
+ pUCharTargetLimit,
+ &pCharSource,
+ pCharSourceLimit,
+ NULL,
+ TRUE,
+ &err
+ );
+
+ if(U_FAILURE(err)){
+ log_err("FAIL: cloned converter failed to do toU conversion. Error: %s\n",u_errorName(err));
+ }
+
+ pConstCharBuffer = charBuffer;
+ if (uniBuffer [0] != ucnv_getNextUChar(cnv2, &pConstCharBuffer, pCharBuffer, &err))
+ {
+ log_err("FAIL: Cloned converter failed to do conversion. Error: %s\n",u_errorName(err));
+ }
+ ucnv_close(cnv2);
+ }
+}
+
static void TestCCSID() {
#if !UCONFIG_NO_LEGACY_CONVERSION
UConverter *cnv;
diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/cdateintervalformattest.c b/Build/source/libs/icu/icu-src/source/test/cintltst/cdateintervalformattest.c
index 513989ac6bb..8f157d2f5d4 100644
--- a/Build/source/libs/icu/icu-src/source/test/cintltst/cdateintervalformattest.c
+++ b/Build/source/libs/icu/icu-src/source/test/cintltst/cdateintervalformattest.c
@@ -368,23 +368,23 @@ static void TestFormatToResult() {
{
const char* message = "Field position test 1";
- const UChar* expectedString = u"27. September 2010, 15:00 – 2. März 2011, 18:30";
+ const UChar* expectedString = u"27. September 2010 um 15:00 – 2. März 2011 um 18:30";
udtitvfmt_formatToResult(fmt, Date201009270800, Date201103021030, fdi, &ec);
assertSuccess("Formatting", &ec);
static const UFieldPositionWithCategory expectedFieldPositions[] = {
// category, field, begin index, end index
- {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 0, 25},
+ {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 0, 27},
{UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 0, 2},
{UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 4, 13},
{UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 14, 18},
- {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 20, 22},
- {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 23, 25},
- {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 28, 47},
- {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 28, 29},
- {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 31, 35},
- {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 36, 40},
- {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 42, 44},
- {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 45, 47}};
+ {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 22, 24},
+ {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 25, 27},
+ {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 30, 51},
+ {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 30, 31},
+ {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 33, 37},
+ {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 38, 42},
+ {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 46, 48},
+ {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 49, 51}};
checkMixedFormattedValue(
message,
udtitvfmt_resultAsValue(fdi, &ec),
@@ -438,23 +438,23 @@ static void TestFormatCalendarToResult() {
{
const char* message = "Field position test 1";
- const UChar* expectedString = u"27. September 2010, 15:00 – 2. März 2011, 18:30";
+ const UChar* expectedString = u"27. September 2010 um 15:00 – 2. März 2011 um 18:30";
udtitvfmt_formatCalendarToResult(fmt, ucal1, ucal2, fdi, &ec);
assertSuccess("Formatting", &ec);
static const UFieldPositionWithCategory expectedFieldPositions[] = {
// category, field, begin index, end index
- {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 0, 25},
+ {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 0, 27},
{UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 0, 2},
{UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 4, 13},
{UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 14, 18},
- {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 20, 22},
- {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 23, 25},
- {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 28, 47},
- {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 28, 29},
- {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 31, 35},
- {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 36, 40},
- {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 42, 44},
- {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 45, 47}};
+ {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 22, 24},
+ {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 25, 27},
+ {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 30, 51},
+ {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 30, 31},
+ {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 33, 37},
+ {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 38, 42},
+ {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 46, 48},
+ {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 49, 51}};
checkMixedFormattedValue(
message,
udtitvfmt_resultAsValue(fdi, &ec),
@@ -493,23 +493,23 @@ static void TestFormatCalendarToResult() {
ucal_setMillis(ucal5, Date158210160000, &ec);
// 1 2 3 4
// 012345678901234567890123456789012345678901234567890
- const UChar* expectedString = u"4. Oktober 1582, 00:00 – 16. Oktober 1582, 00:00";
+ const UChar* expectedString = u"4. Oktober 1582 um 00:00 – 16. Oktober 1582 um 00:00";
udtitvfmt_formatCalendarToResult(fmt, ucal4, ucal5, fdi, &ec);
assertSuccess("Formatting", &ec);
static const UFieldPositionWithCategory expectedFieldPositions[] = {
// category, field, begin index, end index
- {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 0, 22},
+ {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 0, 24},
{UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 0, 1},
{UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 3, 10},
{UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 11, 15},
- {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 17, 19},
- {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 20, 22},
- {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 25, 48},
- {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 25, 27},
- {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 29, 36},
- {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 37, 41},
- {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 43, 45},
- {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 46, 48}};
+ {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 19, 21},
+ {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 22, 24},
+ {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 27, 52},
+ {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 27, 29},
+ {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 31, 38},
+ {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 39, 43},
+ {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 47, 49},
+ {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 50, 52}};
checkMixedFormattedValue(
message,
udtitvfmt_resultAsValue(fdi, &ec),
@@ -527,23 +527,23 @@ static void TestFormatCalendarToResult() {
const char* message = "Field position test 4";
// 1 2 3 4
// 012345678901234567890123456789012345678901234567890
- const UChar* expectedString = u"14. Oktober 1582, 00:00 – 16. Oktober 1582, 00:00";
+ const UChar* expectedString = u"14. Oktober 1582 um 00:00 – 16. Oktober 1582 um 00:00";
udtitvfmt_formatCalendarToResult(fmt, ucal4, ucal5, fdi, &ec);
assertSuccess("Formatting", &ec);
static const UFieldPositionWithCategory expectedFieldPositions[] = {
// category, field, begin index, end index
- {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 0, 23},
+ {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 0, 25},
{UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 0, 2},
{UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 4, 11},
{UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 12, 16},
- {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 18, 20},
- {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 21, 23},
- {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 26, 49},
- {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 26, 28},
- {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 30, 37},
- {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 38, 42},
- {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 44, 46},
- {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 47, 49}};
+ {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 20, 22},
+ {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 23, 25},
+ {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 28, 53},
+ {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 28, 30},
+ {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 32, 39},
+ {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 40, 44},
+ {UFIELD_CATEGORY_DATE, UDAT_HOUR_OF_DAY0_FIELD, 48, 50},
+ {UFIELD_CATEGORY_DATE, UDAT_MINUTE_FIELD, 51, 53}};
checkMixedFormattedValue(
message,
udtitvfmt_resultAsValue(fdi, &ec),
diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/cdattst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/cdattst.c
index 00b2d6a01a1..2c5d51c64b2 100644
--- a/Build/source/libs/icu/icu-src/source/test/cintltst/cdattst.c
+++ b/Build/source/libs/icu/icu-src/source/test/cintltst/cdattst.c
@@ -45,6 +45,7 @@ static void TestFormatForFields(void);
static void TestForceGannenNumbering(void);
static void TestMapDateToCalFields(void);
static void TestNarrowQuarters(void);
+static void TestExtraneousCharacters(void);
void addDateForTest(TestNode** root);
@@ -67,6 +68,7 @@ void addDateForTest(TestNode** root)
TESTCASE(TestForceGannenNumbering);
TESTCASE(TestMapDateToCalFields);
TESTCASE(TestNarrowQuarters);
+ TESTCASE(TestExtraneousCharacters);
}
/* Testing the DateFormat API */
static void TestDateFormat()
@@ -2017,4 +2019,24 @@ static void TestNarrowQuarters(void) {
}
}
+static void TestExtraneousCharacters(void) {
+ // regression test for ICU-21802
+ UErrorCode err = U_ZERO_ERROR;
+ UCalendar* cal = ucal_open(u"UTC", -1, "en_US", UCAL_GREGORIAN, &err);
+ UDateFormat* df = udat_open(UDAT_PATTERN, UDAT_PATTERN, "en_US", u"UTC", -1, u"yyyyMMdd", -1, &err);
+
+ if (assertSuccess("Failed to create date formatter and calendar", &err)) {
+ udat_setLenient(df, false);
+
+ udat_parseCalendar(df, cal, u"2021", -1, NULL, &err);
+ assertTrue("Success parsing '2021'", err == U_PARSE_ERROR);
+
+ err = U_ZERO_ERROR;
+ udat_parseCalendar(df, cal, u"2021-", -1, NULL, &err);
+ assertTrue("Success parsing '2021-'", err == U_PARSE_ERROR);
+ }
+ udat_close(df);
+ ucal_close(cal);
+}
+
#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/cldrtest.c b/Build/source/libs/icu/icu-src/source/test/cintltst/cldrtest.c
index 7767cf9f097..f83a6f142d8 100644
--- a/Build/source/libs/icu/icu-src/source/test/cintltst/cldrtest.c
+++ b/Build/source/libs/icu/icu-src/source/test/cintltst/cldrtest.c
@@ -1002,6 +1002,10 @@ static void VerifyTranslation(void) {
log_knownIssue("cldrbug:14995", "mai/sd_Deva day names use chars not in exemplars")) {
end = 0;
}
+ if (uprv_strncmp(currLoc,"ks_Deva",7) == 0 &&
+ log_knownIssue("cldrbug:15355", "ks_Deva day names use chars not in exemplars")) {
+ end = 0;
+ }
for (idx = 0; idx < end; idx++) {
const UChar *fromBundleStr = ures_getStringByIndex(resArray, idx, &langSize, &errorCode);
@@ -1035,6 +1039,10 @@ static void VerifyTranslation(void) {
log_knownIssue("cldrbug:14995", "sd_Deva month names use chars not in exemplars")) {
end = 0;
}
+ if (uprv_strncmp(currLoc,"ks_Deva",7) == 0 &&
+ log_knownIssue("cldrbug:15355", "ks_Deva month names use chars not in exemplars")) {
+ end = 0;
+ }
for (idx = 0; idx < end; idx++) {
const UChar *fromBundleStr = ures_getStringByIndex(resArray, idx, &langSize, &errorCode);
diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/cloctst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/cloctst.c
index 8707babbbee..606e0a2794b 100644
--- a/Build/source/libs/icu/icu-src/source/test/cintltst/cloctst.c
+++ b/Build/source/libs/icu/icu-src/source/test/cintltst/cloctst.c
@@ -1552,18 +1552,18 @@ static void TestSimpleDisplayNames()
static void TestUninstalledISO3Names()
{
/* This test checks to make sure getISO3Language and getISO3Country work right
- even for locales that are not installed. */
+ even for locales that are not installed (and some installed ones). */
static const char iso2Languages [][4] = { "am", "ba", "fy", "mr", "rn",
- "ss", "tw", "zu" };
+ "ss", "tw", "zu", "sr" };
static const char iso3Languages [][5] = { "amh", "bak", "fry", "mar", "run",
- "ssw", "twi", "zul" };
+ "ssw", "twi", "zul", "srp" };
static const char iso2Countries [][6] = { "am_AF", "ba_BW", "fy_KZ", "mr_MO", "rn_MN",
- "ss_SB", "tw_TC", "zu_ZW" };
+ "ss_SB", "tw_TC", "zu_ZW", "sr_XK" };
static const char iso3Countries [][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG",
- "SLB", "TCA", "ZWE" };
+ "SLB", "TCA", "ZWE", "XKK" };
int32_t i;
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < 9; i++) {
UErrorCode err = U_ZERO_ERROR;
const char *test;
test = uloc_getISO3Language(iso2Languages[i]);
@@ -1571,7 +1571,7 @@ static void TestUninstalledISO3Names()
log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
iso2Languages[i], iso3Languages[i], test, myErrorName(err));
}
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < 9; i++) {
UErrorCode err = U_ZERO_ERROR;
const char *test;
test = uloc_getISO3Country(iso2Countries[i]);
@@ -3207,6 +3207,18 @@ static void TestAcceptLanguage(void) {
}
}
}
+
+ // API coverage
+ status = U_ZERO_ERROR;
+ static const char *const supported[] = { "en-US", "en-GB", "de-DE", "ja-JP" };
+ const char * desired[] = { "de-LI", "en-IN", "zu", "fr" };
+ available = uenum_openCharStringsEnumeration(supported, UPRV_LENGTHOF(supported), &status);
+ tmp[0]=0;
+ rc = uloc_acceptLanguage(tmp, 199, &outResult, desired, UPRV_LENGTHOF(desired), available, &status);
+ if (U_FAILURE(status) || rc != 5 || uprv_strcmp(tmp, "de_DE") != 0 || outResult == ULOC_ACCEPT_FAILED) {
+ log_err("uloc_acceptLanguage() failed to do a simple match\n");
+ }
+ uenum_close(available);
}
static const char* LOCALE_ALIAS[][2] = {
@@ -7053,6 +7065,14 @@ static void TestUldnNameVariants() {
u_errorName(status) );
continue;
}
+ // API coverage: Expect to get back the dialect handling which is
+ // the first item in the displayOptions test data.
+ UDialectHandling dh = uldn_getDialectHandling(uldn);
+ UDisplayContext dhContext = (UDisplayContext)dh; // same numeric values
+ if (dhContext != uloPtr->displayOptions[0]) {
+ log_err("uldn_getDialectHandling()=%03X != expected UDisplayContext %03X\n",
+ dhContext, uloPtr->displayOptions[0]);
+ }
const UldnItem * itemPtr = uloPtr->testItems;
int32_t itemCount = uloPtr->countItems;
for (; itemCount-- > 0; itemPtr++) {
diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/cnormtst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/cnormtst.c
index c16f8a62846..c7830073b23 100644
--- a/Build/source/libs/icu/icu-src/source/test/cintltst/cnormtst.c
+++ b/Build/source/libs/icu/icu-src/source/test/cintltst/cnormtst.c
@@ -65,6 +65,7 @@ TestGetRawDecomposition(void);
static void TestAppendRestoreMiddle(void);
static void TestGetEasyToUseInstance(void);
+static void TestAPICoverage(void);
static const char* const canonTests[][3] = {
/* Input*/ /*Decomposed*/ /*Composed*/
@@ -156,6 +157,7 @@ void addNormTest(TestNode** root)
addTest(root, &TestGetRawDecomposition, "tsnorm/cnormtst/TestGetRawDecomposition");
addTest(root, &TestAppendRestoreMiddle, "tsnorm/cnormtst/TestAppendRestoreMiddle");
addTest(root, &TestGetEasyToUseInstance, "tsnorm/cnormtst/TestGetEasyToUseInstance");
+ addTest(root, &TestAPICoverage, "tsnorm/cnormtst/TestAPICoverage");
}
static const char* const modeStrings[]={
@@ -1698,4 +1700,55 @@ TestGetEasyToUseInstance() {
}
}
+static void
+TestAPICoverage() {
+ UErrorCode errorCode = U_ZERO_ERROR;
+ const UNormalizer2 *n2 = unorm2_getNFDInstance(&errorCode);
+ if (U_FAILURE(errorCode)) {
+ log_err_status(errorCode, "unorm2_getNFDInstance() failed: %s\n", u_errorName(errorCode));
+ return;
+ }
+
+ if (!unorm2_hasBoundaryBefore(n2, u'C') || unorm2_hasBoundaryBefore(n2, 0x300)) {
+ log_err("unorm2_hasBoundaryBefore() returns unexpected results\n");
+ }
+
+ if (!unorm2_hasBoundaryAfter(n2, u'C') || unorm2_hasBoundaryAfter(n2, 0x300)) {
+ log_err("unorm2_hasBoundaryAfter() returns unexpected results\n");
+ }
+
+ if (!unorm2_isInert(n2, 0x50005) || unorm2_isInert(n2, 0x300)) {
+ log_err("unorm2_isInert() returns unexpected results\n");
+ }
+
+ errorCode = U_ZERO_ERROR;
+ if (!unorm2_isNormalized(n2, u"c\u0327\u0300", 3, &errorCode) ||
+ unorm2_isNormalized(n2, u"c\u0300\u0327", 3, &errorCode) ||
+ U_FAILURE(errorCode)) {
+ log_err("unorm2_isNormalized() returns unexpected results\n");
+ }
+
+ errorCode = U_ZERO_ERROR;
+ if (unorm2_quickCheck(n2, u"c\u0327\u0300", 3, &errorCode) == UNORM_NO ||
+ unorm2_quickCheck(n2, u"c\u0300\u0327", 3, &errorCode) == UNORM_YES ||
+ U_FAILURE(errorCode)) {
+ log_err("unorm2_quickCheck() returns unexpected results\n");
+ }
+
+ errorCode = U_ZERO_ERROR;
+ if (unorm2_spanQuickCheckYes(n2, u"c\u0327\u0300", 3, &errorCode) != 3 ||
+ unorm2_spanQuickCheckYes(n2, u"c\u0300\u0327", 3, &errorCode) != 1 ||
+ U_FAILURE(errorCode)) {
+ log_err("unorm2_spanQuickCheckYes() returns unexpected results\n");
+ }
+
+ errorCode = U_ZERO_ERROR;
+ UChar first[10] = { u'c', 0x300, 0, 0, 0, 0, 0, 0, 0, 0 };
+ int32_t length = unorm2_normalizeSecondAndAppend(
+ n2, first, 2, UPRV_LENGTHOF(first), u"\u0327d", 2, &errorCode);
+ if (U_FAILURE(errorCode) || length != 4 || u_strcmp(first, u"c\u0327\u0300d") != 0) {
+ log_err("unorm2_normalizeSecondAndAppend() returns unexpected results\n");
+ }
+}
+
#endif /* #if !UCONFIG_NO_NORMALIZATION */
diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/creststn.c b/Build/source/libs/icu/icu-src/source/test/cintltst/creststn.c
index f8c50cb1a82..c61f063a950 100644
--- a/Build/source/libs/icu/icu-src/source/test/cintltst/creststn.c
+++ b/Build/source/libs/icu/icu-src/source/test/cintltst/creststn.c
@@ -2180,7 +2180,7 @@ static void TestFallback()
UResourceBundle* myResB = ures_open(NULL,"no_NO_NY",&err);
UResourceBundle* resLocID = ures_getByKey(myResB, "Version", NULL, &err);
const UChar* version = NULL;
- static const UChar versionStr[] = u"40"; // 40 in nn_NO or in a parent bundle/root
+ static const UChar versionStr[] = u"41"; // 41 in nn_NO or in a parent bundle/root
if(U_FAILURE(err)) {
log_data_err("Expected success when trying to test no_NO_NY aliased to nn_NO for Version "
diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/ucsdetst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/ucsdetst.c
index f65f8d79aa4..b8d3b5f20b8 100644
--- a/Build/source/libs/icu/icu-src/source/test/cintltst/ucsdetst.c
+++ b/Build/source/libs/icu/icu-src/source/test/cintltst/ucsdetst.c
@@ -402,6 +402,7 @@ static void TestBufferOverflow(void) {
}
for (idx = 0; idx < UPRV_LENGTHOF(testStrings); idx++) {
+ status = U_ZERO_ERROR;
ucsdet_setText(csd, testStrings[idx], -1, &status);
match = ucsdet_detect(csd, &status);
diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/udatpg_test.c b/Build/source/libs/icu/icu-src/source/test/cintltst/udatpg_test.c
index 5f15577b264..66cfb41d47f 100644
--- a/Build/source/libs/icu/icu-src/source/test/cintltst/udatpg_test.c
+++ b/Build/source/libs/icu/icu-src/source/test/cintltst/udatpg_test.c
@@ -46,6 +46,7 @@ static void TestGetFieldDisplayNames(void);
static void TestGetDefaultHourCycle(void);
static void TestGetDefaultHourCycleOnEmptyInstance(void);
static void TestEras(void);
+static void TestDateTimePatterns(void);
void addDateTimePatternGeneratorTest(TestNode** root) {
TESTCASE(TestOpenClose);
@@ -56,6 +57,7 @@ void addDateTimePatternGeneratorTest(TestNode** root) {
TESTCASE(TestGetDefaultHourCycle);
TESTCASE(TestGetDefaultHourCycleOnEmptyInstance);
TESTCASE(TestEras);
+ TESTCASE(TestDateTimePatterns);
}
/*
@@ -614,4 +616,178 @@ static void TestEras(void) {
}
}
+enum { kNumDateTimePatterns = 4 };
+
+typedef struct {
+ const char* localeID;
+ const UChar* expectPat[kNumDateTimePatterns];
+} DTPLocaleAndResults;
+
+static void doDTPatternTest(UDateTimePatternGenerator* udtpg,
+ const UChar** skeletons,
+ DTPLocaleAndResults* localeAndResultsPtr);
+
+static void TestDateTimePatterns(void) {
+ const UChar* skeletons[kNumDateTimePatterns] = {
+ u"yMMMMEEEEdjmm", // full date, short time
+ u"yMMMMdjmm", // long date, short time
+ u"yMMMdjmm", // medium date, short time
+ u"yMdjmm" // short date, short time
+ };
+ // The following tests some locales in which there are differences between the
+ // DateTimePatterns of various length styles.
+ DTPLocaleAndResults localeAndResults[] = {
+ { "en", { u"EEEE, MMMM d, y 'at' h:mm a", // long != medium
+ u"MMMM d, y 'at' h:mm a",
+ u"MMM d, y, h:mm a",
+ u"M/d/y, h:mm a" } },
+ { "fr", { u"EEEE d MMMM y 'à' HH:mm", // medium != short
+ u"d MMMM y 'à' HH:mm",
+ u"d MMM y, HH:mm",
+ u"dd/MM/y HH:mm" } },
+ { "ha", { u"EEEE d MMMM, y HH:mm", // full != long
+ u"d MMMM, y 'da' HH:mm",
+ u"d MMM, y, HH:mm",
+ u"y-MM-dd, HH:mm" } },
+ { NULL, { NULL, NULL, NULL, NULL } } // terminator
+ };
+
+ const UChar* enDTPatterns[kNumDateTimePatterns] = {
+ u"{1} 'at' {0}",
+ u"{1} 'at' {0}",
+ u"{1}, {0}",
+ u"{1}, {0}"
+ };
+ const UChar* modDTPatterns[kNumDateTimePatterns] = {
+ u"{1} _0_ {0}",
+ u"{1} _1_ {0}",
+ u"{1} _2_ {0}",
+ u"{1} _3_ {0}"
+ };
+ DTPLocaleAndResults enModResults = { "en", { u"EEEE, MMMM d, y _0_ h:mm a",
+ u"MMMM d, y _1_ h:mm a",
+ u"MMM d, y _2_ h:mm a",
+ u"M/d/y _3_ h:mm a" }
+ };
+
+ // Test various locales with standard data
+ UErrorCode status;
+ UDateTimePatternGenerator* udtpg;
+ DTPLocaleAndResults* localeAndResultsPtr = localeAndResults;
+ for (; localeAndResultsPtr->localeID != NULL; localeAndResultsPtr++) {
+ status = U_ZERO_ERROR;
+ udtpg = udatpg_open(localeAndResultsPtr->localeID, &status);
+ if (U_FAILURE(status)) {
+ log_data_err("FAIL: udatpg_open for locale %s: %s", localeAndResultsPtr->localeID, myErrorName(status));
+ } else {
+ doDTPatternTest(udtpg, skeletons, localeAndResultsPtr);
+ udatpg_close(udtpg);
+ }
+ }
+ // Test getting and modifying date-time combining patterns
+ status = U_ZERO_ERROR;
+ udtpg = udatpg_open("en", &status);
+ if (U_FAILURE(status)) {
+ log_data_err("FAIL: udatpg_open #2 for locale en: %s", myErrorName(status));
+ } else {
+ char bExpect[64];
+ char bGet[64];
+ const UChar* uGet;
+ int32_t uGetLen, uExpectLen;
+
+ // Test error: style out of range
+ status = U_ZERO_ERROR;
+ uGet = udatpg_getDateTimeFormatForStyle(udtpg, UDAT_NONE, &uGetLen, &status);
+ if (status != U_ILLEGAL_ARGUMENT_ERROR || uGetLen != 0 || uGet==NULL || *uGet!= 0) {
+ if (uGet==NULL) {
+ log_err("FAIL: udatpg_getDateTimeFormatForStyle with invalid style, expected U_ILLEGAL_ARGUMENT_ERROR "
+ "and ptr to empty string but got %s, len %d, ptr = NULL\n", myErrorName(status), uGetLen);
+ } else {
+ log_err("FAIL: udatpg_getDateTimeFormatForStyle with invalid style, expected U_ILLEGAL_ARGUMENT_ERROR "
+ "and ptr to empty string but got %s, len %d, *ptr = %04X\n", myErrorName(status), uGetLen, *uGet);
+ }
+ }
+
+ // Test normal getting and setting
+ for (int32_t patStyle = 0; patStyle < kNumDateTimePatterns; patStyle++) {
+ status = U_ZERO_ERROR;
+ uExpectLen = u_strlen(enDTPatterns[patStyle]);
+ uGet = udatpg_getDateTimeFormatForStyle(udtpg, patStyle, &uGetLen, &status);
+ if (U_FAILURE(status)) {
+ log_err("FAIL udatpg_getDateTimeFormatForStyle %d (en before mod), get %s\n", patStyle, myErrorName(status));
+ } else if (uGetLen != uExpectLen || u_strncmp(uGet, enDTPatterns[patStyle], uExpectLen) != 0) {
+ u_austrcpy(bExpect, enDTPatterns[patStyle]);
+ u_austrcpy(bGet, uGet);
+ log_err("ERROR udatpg_getDateTimeFormatForStyle %d (en before mod), expect %d:\"%s\", get %d:\"%s\"\n",
+ patStyle, uExpectLen, bExpect, uGetLen, bGet);
+ }
+ status = U_ZERO_ERROR;
+ udatpg_setDateTimeFormatForStyle(udtpg, patStyle, modDTPatterns[patStyle], -1, &status);
+ if (U_FAILURE(status)) {
+ log_err("FAIL udatpg_setDateTimeFormatForStyle %d (en), get %s\n", patStyle, myErrorName(status));
+ } else {
+ uExpectLen = u_strlen(modDTPatterns[patStyle]);
+ uGet = udatpg_getDateTimeFormatForStyle(udtpg, patStyle, &uGetLen, &status);
+ if (U_FAILURE(status)) {
+ log_err("FAIL udatpg_getDateTimeFormatForStyle %d (en after mod), get %s\n", patStyle, myErrorName(status));
+ } else if (uGetLen != uExpectLen || u_strncmp(uGet, modDTPatterns[patStyle], uExpectLen) != 0) {
+ u_austrcpy(bExpect, modDTPatterns[patStyle]);
+ u_austrcpy(bGet, uGet);
+ log_err("ERROR udatpg_getDateTimeFormatForStyle %d (en after mod), expect %d:\"%s\", get %d:\"%s\"\n",
+ patStyle, uExpectLen, bExpect, uGetLen, bGet);
+ }
+ }
+ }
+ // Test result of setting
+ doDTPatternTest(udtpg, skeletons, &enModResults);
+ // Test old get/set functions
+ uExpectLen = u_strlen(modDTPatterns[UDAT_MEDIUM]);
+ uGet = udatpg_getDateTimeFormat(udtpg, &uGetLen);
+ if (uGetLen != uExpectLen || u_strncmp(uGet, modDTPatterns[UDAT_MEDIUM], uExpectLen) != 0) {
+ u_austrcpy(bExpect, modDTPatterns[UDAT_MEDIUM]);
+ u_austrcpy(bGet, uGet);
+ log_err("ERROR udatpg_getDateTimeFormat (en after mod), expect %d:\"%s\", get %d:\"%s\"\n",
+ uExpectLen, bExpect, uGetLen, bGet);
+ }
+ udatpg_setDateTimeFormat(udtpg, modDTPatterns[UDAT_SHORT], -1); // set all dateTimePatterns to the short format
+ uExpectLen = u_strlen(modDTPatterns[UDAT_SHORT]);
+ u_austrcpy(bExpect, modDTPatterns[UDAT_SHORT]);
+ for (int32_t patStyle = 0; patStyle < kNumDateTimePatterns; patStyle++) {
+ status = U_ZERO_ERROR;
+ uGet = udatpg_getDateTimeFormatForStyle(udtpg, patStyle, &uGetLen, &status);
+ if (U_FAILURE(status)) {
+ log_err("FAIL udatpg_getDateTimeFormatForStyle %d (en after second mod), get %s\n", patStyle, myErrorName(status));
+ } else if (uGetLen != uExpectLen || u_strncmp(uGet, modDTPatterns[UDAT_SHORT], uExpectLen) != 0) {
+ u_austrcpy(bGet, uGet);
+ log_err("ERROR udatpg_getDateTimeFormatForStyle %d (en after second mod), expect %d:\"%s\", get %d:\"%s\"\n",
+ patStyle, uExpectLen, bExpect, uGetLen, bGet);
+ }
+ }
+
+ udatpg_close(udtpg);
+ }
+}
+
+static void doDTPatternTest(UDateTimePatternGenerator* udtpg,
+ const UChar** skeletons,
+ DTPLocaleAndResults* localeAndResultsPtr) {
+ for (int32_t patStyle = 0; patStyle < kNumDateTimePatterns; patStyle++) {
+ UChar uGet[64];
+ int32_t uGetLen, uExpectLen;
+ UErrorCode status = U_ZERO_ERROR;
+ uExpectLen = u_strlen(localeAndResultsPtr->expectPat[patStyle]);
+ uGetLen = udatpg_getBestPattern(udtpg, skeletons[patStyle], -1, uGet, 64, &status);
+ if (U_FAILURE(status)) {
+ log_err("FAIL udatpg_getBestPattern locale %s style %d: %s\n", localeAndResultsPtr->localeID, patStyle, myErrorName(status));
+ } else if (uGetLen != uExpectLen || u_strncmp(uGet, localeAndResultsPtr->expectPat[patStyle], uExpectLen) != 0) {
+ char bExpect[64];
+ char bGet[64];
+ u_austrcpy(bExpect, localeAndResultsPtr->expectPat[patStyle]);
+ u_austrcpy(bGet, uGet);
+ log_err("ERROR udatpg_getBestPattern locale %s style %d, expect %d:\"%s\", get %d:\"%s\"\n",
+ localeAndResultsPtr->localeID, patStyle, uExpectLen, bExpect, uGetLen, bGet);
+ }
+ }
+}
+
#endif
diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/ulistfmttest.c b/Build/source/libs/icu/icu-src/source/test/cintltst/ulistfmttest.c
index 7fe549f43ba..b0a1f6bc349 100644
--- a/Build/source/libs/icu/icu-src/source/test/cintltst/ulistfmttest.c
+++ b/Build/source/libs/icu/icu-src/source/test/cintltst/ulistfmttest.c
@@ -20,6 +20,8 @@
static void TestUListFmt(void);
static void TestUListFmtToValue(void);
static void TestUListOpenStyled(void);
+static void TestUList21871_A(void);
+static void TestUList21871_B(void);
void addUListFmtTest(TestNode** root);
@@ -30,6 +32,8 @@ void addUListFmtTest(TestNode** root)
TESTCASE(TestUListFmt);
TESTCASE(TestUListFmtToValue);
TESTCASE(TestUListOpenStyled);
+ TESTCASE(TestUList21871_A);
+ TESTCASE(TestUList21871_B);
}
static const UChar str0[] = { 0x41,0 }; /* "A" */
@@ -250,5 +254,103 @@ static void TestUListOpenStyled() {
ulistfmt_closeResult(fl);
}
+#include <stdio.h>
+
+static void TestUList21871_A() {
+ UErrorCode status = U_ZERO_ERROR;
+ UListFormatter *fmt = ulistfmt_openForType("en", ULISTFMT_TYPE_AND, ULISTFMT_WIDTH_WIDE, &status);
+ assertSuccess("ulistfmt_openForType", &status);
+
+ const UChar *strs[] = {u"A", u""};
+ const int32_t lens[] = {1, 0};
+
+ UFormattedList *fl = ulistfmt_openResult(&status);
+ assertSuccess("ulistfmt_openResult", &status);
+
+ ulistfmt_formatStringsToResult(fmt, strs, lens, 2, fl, &status);
+ assertSuccess("ulistfmt_formatStringsToResult", &status);
+
+ const UFormattedValue *value = ulistfmt_resultAsValue(fl, &status);
+ assertSuccess("ulistfmt_resultAsValue", &status);
+
+ {
+ int32_t len;
+ const UChar *str = ufmtval_getString(value, &len, &status);
+ assertUEquals("TEST ufmtval_getString", u"A and ", str);
+ }
+
+ UConstrainedFieldPosition *fpos = ucfpos_open(&status);
+ assertSuccess("ucfpos_open", &status);
+
+ ucfpos_constrainField(fpos, UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, &status);
+ assertSuccess("ucfpos_constrainField", &status);
+
+ bool hasMore = ufmtval_nextPosition(value, fpos, &status);
+ assertSuccess("ufmtval_nextPosition", &status);
+ assertTrue("hasMore 1", hasMore);
+
+ int32_t beginIndex, endIndex;
+ ucfpos_getIndexes(fpos, &beginIndex, &endIndex, &status);
+ assertSuccess("ufmtval_nextPosition", &status);
+ assertIntEquals("TEST beginIndex", 0, beginIndex);
+ assertIntEquals("TEST endIndex", 1, endIndex);
+
+ hasMore = ufmtval_nextPosition(value, fpos, &status);
+ assertSuccess("ufmtval_nextPosition", &status);
+ assertTrue("hasMore 2", !hasMore);
+
+ ucfpos_close(fpos);
+ ulistfmt_closeResult(fl);
+ ulistfmt_close(fmt);
+}
+
+static void TestUList21871_B() {
+ UErrorCode status = U_ZERO_ERROR;
+ UListFormatter *fmt = ulistfmt_openForType("en", ULISTFMT_TYPE_AND, ULISTFMT_WIDTH_WIDE, &status);
+ assertSuccess("ulistfmt_openForType", &status);
+
+ const UChar *strs[] = {u"", u"B"};
+ const int32_t lens[] = {0, 1};
+
+ UFormattedList *fl = ulistfmt_openResult(&status);
+ assertSuccess("ulistfmt_openResult", &status);
+
+ ulistfmt_formatStringsToResult(fmt, strs, lens, 2, fl, &status);
+ assertSuccess("ulistfmt_formatStringsToResult", &status);
+
+ const UFormattedValue *value = ulistfmt_resultAsValue(fl, &status);
+ assertSuccess("ulistfmt_resultAsValue", &status);
+
+ {
+ int32_t len;
+ const UChar *str = ufmtval_getString(value, &len, &status);
+ assertUEquals("TEST ufmtval_getString", u" and B", str);
+ }
+
+ UConstrainedFieldPosition *fpos = ucfpos_open(&status);
+ assertSuccess("ucfpos_open", &status);
+
+ ucfpos_constrainField(fpos, UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, &status);
+ assertSuccess("ucfpos_constrainField", &status);
+
+ bool hasMore = ufmtval_nextPosition(value, fpos, &status);
+ assertSuccess("ufmtval_nextPosition", &status);
+ assertTrue("hasMore 1", hasMore);
+
+ int32_t beginIndex, endIndex;
+ ucfpos_getIndexes(fpos, &beginIndex, &endIndex, &status);
+ assertSuccess("ucfpos_getIndexes", &status);
+ assertIntEquals("TEST beginIndex", 5, beginIndex);
+ assertIntEquals("TEST endIndex", 6, endIndex);
+
+ hasMore = ufmtval_nextPosition(value, fpos, &status);
+ assertSuccess("ufmtval_nextPosition", &status);
+ assertTrue("hasMore 2", !hasMore);
+
+ ucfpos_close(fpos);
+ ulistfmt_closeResult(fl);
+ ulistfmt_close(fmt);
+}
+
#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/Build/source/libs/icu/icu-src/source/test/cintltst/utexttst.c b/Build/source/libs/icu/icu-src/source/test/cintltst/utexttst.c
index 8f3974c9041..6ee85c7057d 100644
--- a/Build/source/libs/icu/icu-src/source/test/cintltst/utexttst.c
+++ b/Build/source/libs/icu/icu-src/source/test/cintltst/utexttst.c
@@ -292,6 +292,22 @@ static void TestAPI(void) {
utext_close(uta);
}
-
+ {
+ // utext_equals() checks for the same type of text provider,
+ // same string pointer(!), and same index.
+ status = U_ZERO_ERROR;
+ const UChar *s = u"aßカ🚲";
+ UText *ut1 = utext_openUChars(NULL, s, -1, &status);
+ UText *ut2 = utext_openUChars(NULL, s, 5, &status);
+ TEST_SUCCESS(status);
+ TEST_ASSERT(utext_equals(ut1, ut2));
+ UChar32 c = utext_next32(ut1);
+ TEST_ASSERT(c == u'a');
+ TEST_ASSERT(!utext_equals(ut1, ut2)); // indexes out of sync
+ c = utext_next32(ut2);
+ TEST_ASSERT(c == u'a');
+ TEST_ASSERT(utext_equals(ut1, ut2)); // back in sync
+ utext_close(ut1);
+ utext_close(ut2);
+ }
}
-
diff --git a/Build/source/libs/icu/icu-src/source/test/depstest/dependencies.txt b/Build/source/libs/icu/icu-src/source/test/depstest/dependencies.txt
index d15fbe0b399..4653afc1c3f 100644
--- a/Build/source/libs/icu/icu-src/source/test/depstest/dependencies.txt
+++ b/Build/source/libs/icu/icu-src/source/test/depstest/dependencies.txt
@@ -224,6 +224,7 @@ group: breakiterator
normlzr # for dictbe.o, should switch to Normalizer2
uvector32 # for dictbe.o
exp_and_tanhf # for lstmbe.o
+ usetiter # for dictbe.o
group: unormcmp # unorm_compare()
unormcmp.o
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/csdetest.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/csdetest.cpp
index 66f9340b83a..95f19d43d1a 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/csdetest.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/csdetest.cpp
@@ -109,6 +109,10 @@ void CharsetDetectionTest::runIndexedTest( int32_t index, UBool exec, const char
if (exec) Ticket6954Test();
break;
+ case 10: name = "Ticket21823Test";
+ if (exec) Ticket21823Test();
+ break;
+
default: name = "";
break; //needed to end loop
}
@@ -839,3 +843,22 @@ void CharsetDetectionTest::Ticket6954Test() {
TEST_ASSERT(strcmp(name1, "windows-1252")==0);
#endif
}
+
+
+// Ticket 21823 - Issue with Charset Detector for ill-formed input strings.
+// Its fix involves returning a failure based error code
+// (U_INVALID_CHAR_FOUND) incase no charsets appear to match the input data.
+void CharsetDetectionTest::Ticket21823Test() {
+ UErrorCode status = U_ZERO_ERROR;
+ std::string str = "\x80";
+ UCharsetDetector* csd = ucsdet_open(&status);
+
+ ucsdet_setText(csd, str.data(), str.length(), &status);
+ const UCharsetMatch* match = ucsdet_detect(csd, &status);
+
+ if (match == NULL) {
+ TEST_ASSERT(U_FAILURE(status));
+ }
+
+ ucsdet_close(csd);
+}
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/csdetest.h b/Build/source/libs/icu/icu-src/source/test/intltest/csdetest.h
index 72d1ca92aea..8893b88e591 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/csdetest.h
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/csdetest.h
@@ -33,6 +33,7 @@ public:
virtual void IBM420Test();
virtual void Ticket6394Test();
virtual void Ticket6954Test();
+ virtual void Ticket21823Test();
private:
void checkEncoding(const UnicodeString &testString,
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/dtfmttst.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/dtfmttst.cpp
index 16f3002a95e..920ec75c8b9 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/dtfmttst.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/dtfmttst.cpp
@@ -190,7 +190,7 @@ void DateFormatTest::TestPatterns() {
{UDAT_ABBR_UTC_TZ, "ZZZZ", "en", "ZZZZ"},
{UDAT_YEAR_NUM_MONTH_DAY UDAT_ABBR_UTC_TZ, "yMdZZZZ", "en", "M/d/y, ZZZZ"},
- {UDAT_MONTH_DAY UDAT_LOCATION_TZ, "MMMMdVVVV", "en", "MMMM d, VVVV"}
+ {UDAT_MONTH_DAY UDAT_LOCATION_TZ, "MMMMdVVVV", "en", "MMMM d 'at' VVVV"}
};
IcuTestErrorCode errorCode(*this, "TestPatterns()");
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/dtifmtts.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/dtifmtts.cpp
index dc9a78dbe16..605eae43614 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/dtifmtts.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/dtifmtts.cpp
@@ -1107,8 +1107,23 @@ void DateIntervalFormatTest::testHourMetacharacters() {
"de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "HH", "00\\u201301 Uhr",
// k and K (ICU-21154 and ICU-21156)
- "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "KK", "0 \\u2013 1 AM",
- "de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "kk", "24\\u201301 Uhr",
+ // (should behave the same as h and H if not overridden in locale ID)
+ "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "KK", "12 \\u2013 1 AM",
+ "de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "kk", "00\\u201301 Uhr",
+ // (overriding hour cycle in locale ID should affect both h and K [or both H and k])
+ "en-u-hc-h11", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "hh", "0 \\u2013 1 AM",
+ "en-u-hc-h11", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "KK", "0 \\u2013 1 AM",
+ "de-u-hc-h24", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "HH", "24\\u201301 Uhr",
+ "de-u-hc-h24", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "kk", "24\\u201301 Uhr",
+ // (overriding hour cycle to h11 should NOT affect H and k; overriding to h24 should NOT affect h and K)
+ "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "HH", "00 \\u2013 01",
+ "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "kk", "00 \\u2013 01",
+ "en-u-hc-h11", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "HH", "00 \\u2013 01",
+ "en-u-hc-h11", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "kk", "00 \\u2013 01",
+ "de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "hh", "12 \\u2013 1 Uhr AM",
+ "de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "KK", "12 \\u2013 1 Uhr AM",
+ "de-u-hc-h24", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "hh", "12 \\u2013 1 Uhr AM",
+ "de-u-hc-h24", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "KK", "12 \\u2013 1 Uhr AM",
// different lengths of the 'a' field
"en", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "ha", "10 AM \\u2013 1 PM",
@@ -1163,14 +1178,22 @@ void DateIntervalFormatTest::testHourMetacharacters() {
"hi_IN", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "CC", "\\u0938\\u0941\\u092C\\u0939 10 \\u2013 \\u0926\\u094B\\u092A\\u0939\\u0930 1",
"hi_IN", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "CC", "\\u0930\\u093E\\u0924 12\\u20131",
- // regression test for ICU-21342
- "en_GB", "CE 2010 09 27 00:00:00", "CE 2010 09 27 10:00:00", "kk", "24\\u201310",
- "en_GB", "CE 2010 09 27 00:00:00", "CE 2010 09 27 11:00:00", "kk", "24\\u201311",
- "en_GB", "CE 2010 09 27 00:00:00", "CE 2010 09 27 12:00:00", "kk", "24\\u201312",
- "en_GB", "CE 2010 09 27 00:00:00", "CE 2010 09 27 13:00:00", "kk", "24\\u201313",
+ // regression test for ICU-21342
+ "en-gb-u-hc-h24", "CE 2010 09 27 00:00:00", "CE 2010 09 27 10:00:00", "kk", "24\\u201310",
+ "en-gb-u-hc-h24", "CE 2010 09 27 00:00:00", "CE 2010 09 27 11:00:00", "kk", "24\\u201311",
+ "en-gb-u-hc-h24", "CE 2010 09 27 00:00:00", "CE 2010 09 27 12:00:00", "kk", "24\\u201312",
+ "en-gb-u-hc-h24", "CE 2010 09 27 00:00:00", "CE 2010 09 27 13:00:00", "kk", "24\\u201313",
- // regression test for ICU-21343
- "de", "CE 2010 09 27 01:00:00", "CE 2010 09 27 10:00:00", "KK", "1 \\u2013 10 Uhr AM",
+ // regression test for ICU-21343
+ "de", "CE 2010 09 27 01:00:00", "CE 2010 09 27 10:00:00", "KK", "1 \\u2013 10 Uhr AM",
+
+ // regression test for ICU-21154 (single-date ranges should use the same hour cycle as multi-date ranges)
+ "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 00:00:00", "hh", "12 AM",
+ "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "hh", "12 \\u2013 1 AM",
+ "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 00:00:00", "KK", "12 AM",
+ "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "KK", "12 \\u2013 1 AM", // (this was producing "0 - 1 AM" before)
+ "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 00:00:00", "jj", "12 AM",
+ "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "jj", "12 \\u2013 1 AM",
};
expect(DATA, UPRV_LENGTHOF(DATA));
}
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/dtptngts.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/dtptngts.cpp
index 6fe8af05b60..dde9d4dd3ac 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/dtptngts.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/dtptngts.cpp
@@ -46,6 +46,7 @@ void IntlTestDateTimePatternGeneratorAPI::runIndexedTest( int32_t index, UBool e
TESTCASE(10, testGetDefaultHourCycle_OnEmptyInstance);
TESTCASE(11, test_jConsistencyOddLocales);
TESTCASE(12, testBestPattern);
+ TESTCASE(13, testDateTimePatterns);
default: name = ""; break;
}
}
@@ -530,7 +531,7 @@ void IntlTestDateTimePatternGeneratorAPI::testAPI(/*char *par*/)
format->applyPattern(gen->getBestPattern(UnicodeString("MMMMdHmm"), status));
dateReturned.remove();
dateReturned = format->format(sampleDate, dateReturned, status);
- expectedResult=UnicodeString("14. von Oktober, 08:58", -1, US_INV);
+ expectedResult=UnicodeString("14. von Oktober um 08:58", -1, US_INV);
if ( dateReturned != expectedResult ) {
errln(UnicodeString("ERROR: Simple test addPattern failed!: d\'. von\' MMMM Got: ") + dateReturned + UnicodeString(" Expected: ") + expectedResult);
}
@@ -1631,4 +1632,150 @@ void IntlTestDateTimePatternGeneratorAPI::testBestPattern() {
}
}
+void IntlTestDateTimePatternGeneratorAPI::testDateTimePatterns() {
+ UnicodeString skeletons[kNumDateTimePatterns] = {
+ UnicodeString("yMMMMEEEEdjmm"), // full date, short time
+ UnicodeString("yMMMMdjmm"), // long date, short time
+ UnicodeString("yMMMdjmm"), // medium date, short time
+ UnicodeString("yMdjmm") // short date, short time
+ };
+ // The following tests some locales in which there are differences between the
+ // DateTimePatterns of various length styles.
+ DTPLocaleAndResults localeAndResults[] = {
+ { "en", { UnicodeString(u"EEEE, MMMM d, y 'at' h:mm a"), // long != medium
+ UnicodeString(u"MMMM d, y 'at' h:mm a"),
+ UnicodeString(u"MMM d, y, h:mm a"),
+ UnicodeString(u"M/d/y, h:mm a") } },
+ { "fr", { UnicodeString(u"EEEE d MMMM y 'à' HH:mm"), // medium != short
+ UnicodeString(u"d MMMM y 'à' HH:mm"),
+ UnicodeString(u"d MMM y, HH:mm"),
+ UnicodeString(u"dd/MM/y HH:mm") } },
+ { "ha", { UnicodeString(u"EEEE d MMMM, y HH:mm"), // full != long
+ UnicodeString(u"d MMMM, y 'da' HH:mm"),
+ UnicodeString(u"d MMM, y, HH:mm"),
+ UnicodeString(u"y-MM-dd, HH:mm") } },
+ { nullptr, { UnicodeString(""), UnicodeString(""), // terminator
+ UnicodeString(""), UnicodeString("") } },
+ };
+
+ UnicodeString enDTPatterns[kNumDateTimePatterns] = {
+ UnicodeString(u"{1} 'at' {0}"),
+ UnicodeString(u"{1} 'at' {0}"),
+ UnicodeString(u"{1}, {0}"),
+ UnicodeString(u"{1}, {0}")
+ };
+ UnicodeString modDTPatterns[kNumDateTimePatterns] = {
+ UnicodeString(u"{1} _0_ {0}"),
+ UnicodeString(u"{1} _1_ {0}"),
+ UnicodeString(u"{1} _2_ {0}"),
+ UnicodeString(u"{1} _3_ {0}")
+ };
+ DTPLocaleAndResults enModResults = { "en", { UnicodeString(u"EEEE, MMMM d, y _0_ h:mm a"),
+ UnicodeString(u"MMMM d, y _1_ h:mm a"),
+ UnicodeString(u"MMM d, y _2_ h:mm a"),
+ UnicodeString(u"M/d/y _3_ h:mm a") }
+ };
+
+ // Test various locales with standard data
+ UErrorCode status;
+ LocalPointer<DateTimePatternGenerator> dtpg;
+ DTPLocaleAndResults* localeAndResultsPtr = localeAndResults;
+ for (; localeAndResultsPtr->localeID != nullptr; localeAndResultsPtr++) {
+ status = U_ZERO_ERROR;
+ Locale locale(localeAndResultsPtr->localeID);
+ dtpg.adoptInstead(DateTimePatternGenerator::createInstance(locale, status));
+ if (U_FAILURE(status)) {
+ dataerrln("FAIL: DateTimePatternGenerator::createInstance for locale %s: %s",
+ localeAndResultsPtr->localeID, u_errorName(status));
+ } else {
+ doDTPatternTest(dtpg.getAlias(), skeletons, localeAndResultsPtr);
+ }
+ }
+ // Test getting and modifying date-time combining patterns
+ status = U_ZERO_ERROR;
+ dtpg.adoptInstead(DateTimePatternGenerator::createInstance(Locale::getEnglish(), status));
+ if (U_FAILURE(status)) {
+ dataerrln("FAIL: DateTimePatternGenerator::createInstance #2 for locale en: %s", u_errorName(status));
+ } else {
+ char bExpect[64];
+ char bGet[64];
+ // Test style out of range
+ status = U_ZERO_ERROR;
+ const UnicodeString& dtFormat0 = dtpg->getDateTimeFormat(UDAT_NONE, status);
+ int32_t dtFormat0Len = dtFormat0.length();
+ if (status != U_ILLEGAL_ARGUMENT_ERROR || dtFormat0Len != 0) {
+ errln("ERROR: getDateTimeFormat with invalid style, expected U_ILLEGAL_ARGUMENT_ERROR and lero-length string, "
+ "got %s with length %d", u_errorName(status), dtFormat0Len);
+ }
+ // Test normal getting and setting
+ for (int32_t patStyle = 0; patStyle < kNumDateTimePatterns; patStyle++) {
+ status = U_ZERO_ERROR;
+ const UnicodeString& dtFormat1 = dtpg->getDateTimeFormat((UDateFormatStyle)patStyle, status);
+ if (U_FAILURE(status)) {
+ errln("FAIL: getDateTimeFormat for en before mod, style %d, get %s", patStyle, u_errorName(status));
+ } else if (dtFormat1 != enDTPatterns[patStyle]) {
+ enDTPatterns[patStyle].extract(0, enDTPatterns[patStyle].length(), bExpect, 64);
+ dtFormat1.extract(0, dtFormat1.length(), bGet, 64);
+ errln("ERROR: getDateTimeFormat for en before mod, style %d, expect \"%s\", get \"%s\"",
+ patStyle, bExpect, bGet);
+ }
+ status = U_ZERO_ERROR;
+ dtpg->setDateTimeFormat((UDateFormatStyle)patStyle, modDTPatterns[patStyle], status);
+ if (U_FAILURE(status)) {
+ errln("FAIL: setDateTimeFormat for en, style %d, get %s", patStyle, u_errorName(status));
+ } else {
+ const UnicodeString& dtFormat2 = dtpg->getDateTimeFormat((UDateFormatStyle)patStyle, status);
+ if (U_FAILURE(status)) {
+ errln("FAIL: getDateTimeFormat for en after mod, style %d, get %s", patStyle, u_errorName(status));
+ } else if (dtFormat2 != modDTPatterns[patStyle]) {
+ modDTPatterns[patStyle].extract(0, modDTPatterns[patStyle].length(), bExpect, 64);
+ dtFormat2.extract(0, dtFormat2.length(), bGet, 64);
+ errln("ERROR: getDateTimeFormat for en after mod, style %d, expect \"%s\", get \"%s\"",
+ patStyle, bExpect, bGet);
+ }
+ }
+ }
+ // Test result of setting
+ doDTPatternTest(dtpg.getAlias(), skeletons, &enModResults);
+ // Test old get/set functions
+ const UnicodeString& dtFormat3 = dtpg->getDateTimeFormat();
+ if (dtFormat3 != modDTPatterns[UDAT_MEDIUM]) {
+ modDTPatterns[UDAT_MEDIUM].extract(0, modDTPatterns[UDAT_MEDIUM].length(), bExpect, 64);
+ dtFormat3.extract(0, dtFormat3.length(), bGet, 64);
+ errln("ERROR: old getDateTimeFormat for en after mod, expect \"%s\", get \"%s\"", bExpect, bGet);
+ }
+ dtpg->setDateTimeFormat(modDTPatterns[UDAT_SHORT]); // set all dateTimePatterns to the short format
+ modDTPatterns[UDAT_SHORT].extract(0, modDTPatterns[UDAT_SHORT].length(), bExpect, 64);
+ for (int32_t patStyle = 0; patStyle < kNumDateTimePatterns; patStyle++) {
+ status = U_ZERO_ERROR;
+ const UnicodeString& dtFormat4 = dtpg->getDateTimeFormat((UDateFormatStyle)patStyle, status);
+ if (U_FAILURE(status)) {
+ errln("FAIL: getDateTimeFormat for en after second mod, style %d, get %s", patStyle, u_errorName(status));
+ } else if (dtFormat4 != modDTPatterns[UDAT_SHORT]) {
+ dtFormat4.extract(0, dtFormat4.length(), bGet, 64);
+ errln("ERROR: getDateTimeFormat for en after second mod, style %d, expect \"%s\", get \"%s\"",
+ patStyle, bExpect, bGet);
+ }
+ }
+ }
+}
+
+void IntlTestDateTimePatternGeneratorAPI::doDTPatternTest(DateTimePatternGenerator* dtpg, UnicodeString* skeletons, DTPLocaleAndResults* localeAndResultsPtr) {
+ for (int32_t patStyle = 0; patStyle < kNumDateTimePatterns; patStyle++) {
+ UErrorCode status = U_ZERO_ERROR;
+ UnicodeString getPat = dtpg->getBestPattern(skeletons[patStyle], UDATPG_MATCH_NO_OPTIONS, status);
+ if (U_FAILURE(status)) {
+ errln("FAIL: DateTimePatternGenerator::getBestPattern locale %s, style %d: %s",
+ localeAndResultsPtr->localeID, patStyle, u_errorName(status));
+ } else if (getPat != localeAndResultsPtr->expectPat[patStyle]) {
+ char bExpect[64];
+ char bGet[64];
+ localeAndResultsPtr->expectPat[patStyle].extract(0, localeAndResultsPtr->expectPat[patStyle].length(), bExpect, 64);
+ getPat.extract(0, getPat.length(), bGet, 64);
+ errln("ERROR: DateTimePatternGenerator::getBestPattern locale %s, style %d, expect \"%s\", get \"%s\"",
+ localeAndResultsPtr->localeID, patStyle, bExpect, bGet);
+ }
+ }
+}
+
#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/dtptngts.h b/Build/source/libs/icu/icu-src/source/test/intltest/dtptngts.h
index 4650fd7fcf6..ec700603eb1 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/dtptngts.h
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/dtptngts.h
@@ -13,6 +13,8 @@
#if !UCONFIG_NO_FORMATTING
+#include "unicode/dtptngen.h"
+#include "unicode/ustring.h"
#include "intltest.h"
/**
@@ -38,6 +40,14 @@ private:
void testGetDefaultHourCycle_OnEmptyInstance();
void test_jConsistencyOddLocales();
void testBestPattern();
+ void testDateTimePatterns();
+
+ enum { kNumDateTimePatterns = 4 };
+ typedef struct {
+ const char* localeID;
+ const UnicodeString expectPat[kNumDateTimePatterns];
+ } DTPLocaleAndResults;
+ void doDTPatternTest(DateTimePatternGenerator* dtpg, UnicodeString* skeletons, DTPLocaleAndResults* localeAndResultsPtr);
};
#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/icusvtst.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/icusvtst.cpp
index aa2d9ca05ce..cb863c5b71b 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/icusvtst.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/icusvtst.cpp
@@ -558,7 +558,7 @@ class TestMultipleKeyStringFactory : public ICUServiceFactory {
, _factoryID(factoryID + ": ")
{
for (int i = 0; i < count; ++i) {
- _ids.addElementX(new UnicodeString(ids[i]), _status);
+ _ids.adoptElement(new UnicodeString(ids[i]), _status);
}
}
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/incaltst.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/incaltst.cpp
index ad75f185f63..250b61c7ac0 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/incaltst.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/incaltst.cpp
@@ -988,7 +988,7 @@ void IntlCalendarTest::TestConsistencyEthiopicAmeteAlem() {
}
void IntlCalendarTest::checkConsistency(const char* locale) {
// Check 2.5 years in quick mode and 8000 years in exhaustive mode.
- int32_t numOfDaysToTest = (quick ? 2.5 : 8000) * 365;
+ int32_t numOfDaysToTest = static_cast<int32_t>((quick ? 2.5 : 8000) * 365);
constexpr int32_t msInADay = 1000*60*60*24;
std::string msg("TestConsistency");
IcuTestErrorCode status(*this, (msg + locale).c_str());
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/intltest.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/intltest.cpp
index 7ff28961271..f2956ebcb48 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/intltest.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/intltest.cpp
@@ -2188,14 +2188,20 @@ UBool IntlTest::assertEqualsNear(const char* message,
double expected,
double actual,
double delta) {
+ bool bothNaN = std::isnan(expected) && std::isnan(actual);
+ bool bothPosInf = uprv_isPositiveInfinity(expected) && uprv_isPositiveInfinity(actual);
+ bool bothNegInf = uprv_isNegativeInfinity(expected) && uprv_isNegativeInfinity(actual);
+ if (bothPosInf || bothNegInf || bothNaN) {
+ // We don't care about delta in these cases
+ return TRUE;
+ }
if (std::isnan(delta) || std::isinf(delta)) {
errln((UnicodeString)("FAIL: ") + message + "; nonsensical delta " + delta +
- " - delta may not be NaN or Inf");
+ " - delta may not be NaN or Inf. (Got " + actual + "; expected " + expected + ".)");
return FALSE;
}
- bool bothNaN = std::isnan(expected) && std::isnan(actual);
double difference = std::abs(expected - actual);
- if (expected != actual && (difference > delta || std::isnan(difference)) && !bothNaN) {
+ if (expected != actual && (difference > delta || std::isnan(difference))) {
errln((UnicodeString)("FAIL: ") + message + "; got " + actual + "; expected " + expected +
"; acceptable delta " + delta);
return FALSE;
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/listformattertest.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/listformattertest.cpp
index 831642241e6..1a4ec97f37d 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/listformattertest.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/listformattertest.cpp
@@ -49,6 +49,7 @@ void ListFormatterTest::runIndexedTest(int32_t index, UBool exec,
TESTCASE_AUTO(TestContextual);
TESTCASE_AUTO(TestNextPosition);
TESTCASE_AUTO(TestInt32Overflow);
+ TESTCASE_AUTO(Test21871);
TESTCASE_AUTO_END;
}
@@ -276,7 +277,7 @@ void ListFormatterTest::RunTestFieldPositionIteratorWithNItemsPatternShift(
const char* testName) {
IcuTestErrorCode errorCode(*this, testName);
LocalPointer<ListFormatter> formatter(ListFormatter::createInstance(
- Locale("ur", "IN"),
+ Locale("ur", "IN"), // in CLDR 41 alpha1 the "backwards order" patterns in this and other locales were removed.
ULISTFMT_TYPE_UNITS,
ULISTFMT_WIDTH_NARROW,
errorCode));
@@ -329,21 +330,21 @@ void ListFormatterTest::TestFieldPositionIteratorWith3Items() {
}
void ListFormatterTest::TestFieldPositionIteratorWith3ItemsPatternShift() {
- // 0 1
- // 012345678901234
- // "cc bbb a"
+ // Note: In CLDR 41 alpha1 the "backwards order" patterns in ur_IN (and one or two
+ // other locales) were removed, ur_IN now just inherits list patterns from ur.
+ // So this test may no longer be interesting.
UnicodeString data[3] = {"a", "bbb", "cc"};
int32_t expected[] = {
- ULISTFMT_ELEMENT_FIELD, 7, 8,
- ULISTFMT_LITERAL_FIELD, 6, 7,
+ ULISTFMT_ELEMENT_FIELD, 0, 1,
+ ULISTFMT_LITERAL_FIELD, 1, 3,
ULISTFMT_ELEMENT_FIELD, 3, 6,
- ULISTFMT_LITERAL_FIELD, 2, 3,
- ULISTFMT_ELEMENT_FIELD, 0, 2
+ ULISTFMT_LITERAL_FIELD, 6, 12,
+ ULISTFMT_ELEMENT_FIELD, 12, 14
};
int32_t tupleCount = sizeof(expected)/(3 * sizeof(*expected));
RunTestFieldPositionIteratorWithNItemsPatternShift(
data, 3, expected, tupleCount,
- u"cc bbb a",
+ u"a، bbb، اور cc",
"TestFieldPositionIteratorWith3ItemsPatternShift");
}
@@ -365,19 +366,19 @@ void ListFormatterTest::TestFieldPositionIteratorWith2Items() {
}
void ListFormatterTest::TestFieldPositionIteratorWith2ItemsPatternShift() {
- // 0 1
- // 01234567890
- // "cc bbb"
+ // Note: In CLDR 41 alpha1 the "backwards order" patterns in ur_IN (and one or two
+ // other locales) were removed, ur_IN now just inherits list patterns from ur.
+ // So this test may no longer be interesting.
UnicodeString data[2] = {"bbb", "cc"};
int32_t expected[] = {
- ULISTFMT_ELEMENT_FIELD, 3, 6,
- ULISTFMT_LITERAL_FIELD, 2, 3,
- ULISTFMT_ELEMENT_FIELD, 0, 2
+ ULISTFMT_ELEMENT_FIELD, 0, 3,
+ ULISTFMT_LITERAL_FIELD, 3, 8,
+ ULISTFMT_ELEMENT_FIELD, 8, 10
};
int32_t tupleCount = sizeof(expected)/(3 * sizeof(*expected));
RunTestFieldPositionIteratorWithNItemsPatternShift(
data, 2, expected, tupleCount,
- u"cc bbb",
+ u"bbb اور cc",
"TestFieldPositionIteratorWith2ItemsPatternShift");
}
@@ -840,4 +841,30 @@ void ListFormatterTest::TestInt32Overflow() {
status.expectErrorAndReset(U_INPUT_TOO_LONG_ERROR);
}
+
+void ListFormatterTest::Test21871() {
+ IcuTestErrorCode status(*this, "Test21871");
+ LocalPointer<ListFormatter> fmt(ListFormatter::createInstance("en", status), status);
+ {
+ UnicodeString strings[] = {{u"A"}, {u""}};
+ FormattedList result = fmt->formatStringsToValue(strings, 2, status);
+ ConstrainedFieldPosition cfp;
+ cfp.constrainField(UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD);
+ assertTrue("nextPosition 1", result.nextPosition(cfp, status));
+ assertEquals("start", cfp.getStart(), 0);
+ assertEquals("limit", cfp.getLimit(), 1);
+ assertFalse("nextPosition 2", result.nextPosition(cfp, status));
+ }
+ {
+ UnicodeString strings[] = {{u""}, {u"B"}};
+ FormattedList result = fmt->formatStringsToValue(strings, 2, status);
+ ConstrainedFieldPosition cfp;
+ cfp.constrainField(UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD);
+ assertTrue("nextPosition 1", result.nextPosition(cfp, status));
+ assertEquals("start", cfp.getStart(), 5);
+ assertEquals("limit", cfp.getLimit(), 6);
+ assertFalse("nextPosition 2", result.nextPosition(cfp, status));
+ }
+}
+
#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/listformattertest.h b/Build/source/libs/icu/icu-src/source/test/intltest/listformattertest.h
index d6bf3bc0d68..0f0390010e4 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/listformattertest.h
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/listformattertest.h
@@ -56,6 +56,7 @@ class ListFormatterTest : public IntlTestWithFieldPosition {
void TestContextual();
void TestNextPosition();
void TestInt32Overflow();
+ void Test21871();
private:
void CheckFormatting(
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/lstmbetst.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/lstmbetst.cpp
index 6c5d5d0ad61..0ffc0fa20e5 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/lstmbetst.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/lstmbetst.cpp
@@ -153,7 +153,7 @@ void LSTMBETest::runTestFromFile(const char* filename) {
dataerrln("%s:%d Error %s Could not allocate UVextor32", __FILE__, __LINE__, u_errorName(status));
return;
}
- engine->findBreaks(&ut, 0, value.length(), actual, status);
+ engine->findBreaks(&ut, 0, value.length(), actual, false, status);
if (U_FAILURE(status)) {
dataerrln("%s:%d Error %s findBreaks failed", __FILE__, __LINE__, u_errorName(status));
return;
@@ -288,7 +288,7 @@ void LSTMBETest::runTestWithLargeMemory( const char* model, UScriptCode script)
return;
}
- engine->findBreaks(&ut, 0, text.length(), actual, status);
+ engine->findBreaks(&ut, 0, text.length(), actual, false, status);
utext_close(&ut);
text += text;
}
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/measfmttest.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/measfmttest.cpp
index 003804db9a4..05488b7c360 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/measfmttest.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/measfmttest.cpp
@@ -2683,7 +2683,7 @@ void MeasureFormatTest::TestCompatible69() {
assertSuccess("", status);
}
-void MeasureFormatTest::TestCompatible70() {
+void MeasureFormatTest::TestCompatible70() { // TestCompatible71 would be identical
UErrorCode status = U_ZERO_ERROR;
LocalPointer<MeasureUnit> measureUnit;
MeasureUnit measureUnitValue;
@@ -3064,6 +3064,9 @@ void MeasureFormatTest::TestCompatible70() {
assertSuccess("", status);
}
+// TestCompatible71 would be identical to TestCompatible70,
+// no need to add it
+
void MeasureFormatTest::TestBasic() {
UErrorCode status = U_ZERO_ERROR;
MeasureUnit *ptr1 = MeasureUnit::createArcMinute(status);
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest.h b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest.h
index d6d71543fb6..c0f2e6fd58a 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest.h
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest.h
@@ -66,6 +66,7 @@ class NumberFormatterApiTest : public IntlTestWithFieldPosition {
void unitUsageSkeletons();
void unitCurrency();
void unitInflections();
+ void unitNounClass();
void unitGender();
void unitNotConvertible();
void unitPercent();
@@ -75,6 +76,7 @@ class NumberFormatterApiTest : public IntlTestWithFieldPosition {
void roundingFractionFigures();
void roundingOther();
void roundingIncrementRegressionTest();
+ void roundingPriorityCoverageTest();
void grouping();
void padding();
void integerWidth();
@@ -99,7 +101,8 @@ class NumberFormatterApiTest : public IntlTestWithFieldPosition {
void toObject();
void toDecimalNumber();
void microPropsInternals();
-
+ void formatUnitsAliases();
+
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
private:
@@ -206,6 +209,7 @@ class DecimalQuantityTest : public IntlTest {
void testNickelRounding();
void testScientificAndCompactSuppressedExponent();
void testSuppressedExponentUnchangedByInitialScaling();
+ void testDecimalQuantityParseFormatRoundTrip();
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_api.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_api.cpp
index cf8fecc0a28..b477a16e93e 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_api.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_api.cpp
@@ -87,6 +87,7 @@ void NumberFormatterApiTest::runIndexedTest(int32_t index, UBool exec, const cha
TESTCASE_AUTO(unitUsageSkeletons);
TESTCASE_AUTO(unitCurrency);
TESTCASE_AUTO(unitInflections);
+ TESTCASE_AUTO(unitNounClass);
TESTCASE_AUTO(unitGender);
TESTCASE_AUTO(unitNotConvertible);
TESTCASE_AUTO(unitPercent);
@@ -99,6 +100,7 @@ void NumberFormatterApiTest::runIndexedTest(int32_t index, UBool exec, const cha
TESTCASE_AUTO(roundingFractionFigures);
TESTCASE_AUTO(roundingOther);
TESTCASE_AUTO(roundingIncrementRegressionTest);
+ TESTCASE_AUTO(roundingPriorityCoverageTest);
TESTCASE_AUTO(grouping);
TESTCASE_AUTO(padding);
TESTCASE_AUTO(integerWidth);
@@ -127,6 +129,7 @@ void NumberFormatterApiTest::runIndexedTest(int32_t index, UBool exec, const cha
TESTCASE_AUTO(toObject);
TESTCASE_AUTO(toDecimalNumber);
TESTCASE_AUTO(microPropsInternals);
+ TESTCASE_AUTO(formatUnitsAliases);
TESTCASE_AUTO_END;
}
@@ -1747,6 +1750,46 @@ void NumberFormatterApiTest::unitUsage() {
30500,
u"350 m");
+ assertFormatSingle(u"Fuel consumption: inverted units", //
+ u"unit/liter-per-100-kilometer usage/vehicle-fuel", //
+ u"unit/liter-per-100-kilometer usage/vehicle-fuel", //
+ NumberFormatter::with() //
+ .unit(MeasureUnit::forIdentifier("liter-per-100-kilometer", status)) //
+ .usage("vehicle-fuel"), //
+ Locale("en-US"), //
+ 6.6, //
+ "36 mpg");
+
+ assertFormatSingle(u"Fuel consumption: inverted units, divide-by-zero, en-US", //
+ u"unit/liter-per-100-kilometer usage/vehicle-fuel", //
+ u"unit/liter-per-100-kilometer usage/vehicle-fuel", //
+ NumberFormatter::with() //
+ .unit(MeasureUnit::forIdentifier("liter-per-100-kilometer", status)) //
+ .usage("vehicle-fuel"), //
+ Locale("en-US"), //
+ 0, //
+ u"∞ mpg");
+
+ assertFormatSingle(u"Fuel consumption: inverted units, divide-by-zero, en-ZA", //
+ u"unit/mile-per-gallon usage/vehicle-fuel", //
+ u"unit/mile-per-gallon usage/vehicle-fuel", //
+ NumberFormatter::with() //
+ .unit(MeasureUnit::forIdentifier("mile-per-gallon", status)) //
+ .usage("vehicle-fuel"), //
+ Locale("en-ZA"), //
+ 0, //
+ u"∞ l/100 km");
+
+ assertFormatSingle(u"Fuel consumption: inverted units, divide-by-inf", //
+ u"unit/mile-per-gallon usage/vehicle-fuel", //
+ u"unit/mile-per-gallon usage/vehicle-fuel", //
+ NumberFormatter::with() //
+ .unit(MeasureUnit::forIdentifier("mile-per-gallon", status)) //
+ .usage("vehicle-fuel"), //
+ Locale("de-CH"), //
+ uprv_getInfinity(), //
+ u"0 L/100 km");
+
// Test calling `.usage("")` should unset the existing usage.
// First: without usage
assertFormatSingle(u"Rounding Mode propagates: rounding up",
@@ -1853,10 +1896,6 @@ void NumberFormatterApiTest::unitUsage() {
Locale("en-US"), //
1, //
"0.019 psi");
-
- // TODO(icu-units#38): improve unit testing coverage. E.g. add vehicle-fuel
- // triggering inversion conversion code. Test with 0 too, to see
- // divide-by-zero behaviour.
}
void NumberFormatterApiTest::unitUsageErrorCodes() {
@@ -2384,7 +2423,7 @@ void NumberFormatterApiTest::unitInflections() {
{"centimeter", "de", nullptr, 1, u"1 Zentimeter"},
{"centimeter", "de", "genitive", 1, u"1 Zentimeters"},
{"centimeter", "de", "dative", 10, u"10 Zentimetern"},
- // TODO(CLDR-14502): check that these inflections are correct, and
+ // TODO(CLDR-14582): check that these inflections are correct, and
// whether CLDR needs any rules for them (presumably CLDR spec
// should mention it, if it's a consistent rule):
{"meter-and-centimeter", "de", nullptr, 1.01, u"1 Meter, 1 Zentimeter"},
@@ -2401,6 +2440,307 @@ void NumberFormatterApiTest::unitInflections() {
// TODO: look at "↑↑↑" cases: check that inheritance is done right.
}
+using icu::NounClass;
+void NumberFormatterApiTest::unitNounClass() {
+ IcuTestErrorCode status(*this, "unitNounClass");
+ const struct TestCase {
+ const char *locale;
+ const char *unitIdentifier;
+ const NounClass expectedNounClass;
+ } cases[] = {
+ {"de", "inch", NounClass::MASCULINE},
+ {"de", "yard", NounClass::NEUTER},
+ {"de", "meter", NounClass::MASCULINE},
+ {"de", "liter", NounClass::MASCULINE},
+ {"de", "second", NounClass::FEMININE},
+ {"de", "minute", NounClass::FEMININE},
+ {"de", "hour", NounClass::FEMININE},
+ {"de", "day", NounClass::MASCULINE},
+ {"de", "year", NounClass::NEUTER},
+ {"de", "gram", NounClass::NEUTER},
+ {"de", "watt", NounClass::NEUTER},
+ {"de", "bit", NounClass::NEUTER},
+ {"de", "byte", NounClass::NEUTER},
+
+ {"fr", "inch", NounClass::MASCULINE},
+ {"fr", "yard", NounClass::MASCULINE},
+ {"fr", "meter", NounClass::MASCULINE},
+ {"fr", "liter", NounClass::MASCULINE},
+ {"fr", "second", NounClass::FEMININE},
+ {"fr", "minute", NounClass::FEMININE},
+ {"fr", "hour", NounClass::FEMININE},
+ {"fr", "day", NounClass::MASCULINE},
+ {"fr", "year", NounClass::MASCULINE},
+ {"fr", "gram", NounClass::MASCULINE},
+
+ // grammaticalFeatures deriveCompound "per" rule takes the gender of the
+ // numerator unit:
+ {"de", "meter-per-hour", NounClass::MASCULINE},
+ {"fr", "meter-per-hour", NounClass::MASCULINE},
+ {"af", "meter-per-hour", NounClass::OTHER}, // ungendered language
+
+ // French "times" takes gender from first value, German takes the
+ // second. Prefix and power does not have impact on gender for these
+ // languages:
+ {"de", "square-decimeter-square-second", NounClass::FEMININE},
+ {"fr", "square-decimeter-square-second", NounClass::MASCULINE},
+
+ // TODO(icu-units#149): percent and permille bypasses LongNameHandler
+ // when unitWidth is not FULL_NAME:
+ // // Gender of per-second might be that of percent? TODO(icu-units#28)
+ // {"de", "percent", NounClass::NEUTER},
+ // {"fr", "percent", NounClass::MASCULINE},
+
+ // Built-in units whose simple units lack gender in the CLDR data file
+ {"de", "kilopascal", NounClass::NEUTER},
+ {"fr", "kilopascal", NounClass::MASCULINE},
+ // {"de", "pascal", NounClass::OTHER},
+ // {"fr", "pascal", NounClass::OTHER},
+
+ // Built-in units that lack gender in the CLDR data file
+ // {"de", "revolution", NounClass::OTHER},
+ // {"de", "radian", NounClass::OTHER},
+ // {"de", "arc-minute", NounClass::OTHER},
+ // {"de", "arc-second", NounClass::OTHER},
+ {"de", "square-yard", NounClass::NEUTER}, // POWER
+ {"de", "square-inch", NounClass::MASCULINE}, // POWER
+ // {"de", "dunam", NounClass::OTHER},
+ // {"de", "karat", NounClass::OTHER},
+ // {"de", "milligram-ofglucose-per-deciliter", NounClass::OTHER}, // COMPOUND, ofglucose
+ // {"de", "millimole-per-liter", NounClass::OTHER}, // COMPOUND, mole
+ // {"de", "permillion", NounClass::OTHER},
+ // {"de", "permille", NounClass::OTHER},
+ // {"de", "permyriad", NounClass::OTHER},
+ // {"de", "mole", NounClass::OTHER},
+ {"de", "liter-per-kilometer", NounClass::MASCULINE}, // COMPOUND
+ {"de", "petabyte", NounClass::NEUTER}, // PREFIX
+ {"de", "terabit", NounClass::NEUTER}, // PREFIX
+ // {"de", "century", NounClass::OTHER},
+ // {"de", "decade", NounClass::OTHER},
+ {"de", "millisecond", NounClass::FEMININE}, // PREFIX
+ {"de", "microsecond", NounClass::FEMININE}, // PREFIX
+ {"de", "nanosecond", NounClass::FEMININE}, // PREFIX
+ // {"de", "ampere", NounClass::OTHER},
+ // {"de", "milliampere", NounClass::OTHER}, // PREFIX, ampere
+ // {"de", "ohm", NounClass::OTHER},
+ // {"de", "calorie", NounClass::OTHER},
+ // {"de", "kilojoule", NounClass::OTHER}, // PREFIX, joule
+ // {"de", "joule", NounClass::OTHER},
+ {"de", "kilowatt-hour", NounClass::FEMININE}, // COMPOUND
+ // {"de", "electronvolt", NounClass::OTHER},
+ // {"de", "british-thermal-unit", NounClass::OTHER},
+ // {"de", "therm-us", NounClass::OTHER},
+ // {"de", "pound-force", NounClass::OTHER},
+ // {"de", "newton", NounClass::OTHER},
+ // {"de", "gigahertz", NounClass::OTHER}, // PREFIX, hertz
+ // {"de", "megahertz", NounClass::OTHER}, // PREFIX, hertz
+ // {"de", "kilohertz", NounClass::OTHER}, // PREFIX, hertz
+ // {"de", "hertz", NounClass::OTHER},
+ // {"de", "em", NounClass::OTHER},
+ // {"de", "pixel", NounClass::OTHER},
+ // {"de", "megapixel", NounClass::OTHER},
+ // {"de", "pixel-per-centimeter", NounClass::OTHER}, // COMPOUND, pixel
+ // {"de", "pixel-per-inch", NounClass::OTHER}, // COMPOUND, pixel
+ // {"de", "dot-per-centimeter", NounClass::OTHER}, // COMPOUND, dot
+ // {"de", "dot-per-inch", NounClass::OTHER}, // COMPOUND, dot
+ // {"de", "dot", NounClass::OTHER},
+ // {"de", "earth-radius", NounClass::OTHER},
+ {"de", "decimeter", NounClass::MASCULINE}, // PREFIX
+ {"de", "micrometer", NounClass::MASCULINE}, // PREFIX
+ {"de", "nanometer", NounClass::MASCULINE}, // PREFIX
+ // {"de", "light-year", NounClass::OTHER},
+ // {"de", "astronomical-unit", NounClass::OTHER},
+ // {"de", "furlong", NounClass::OTHER},
+ // {"de", "fathom", NounClass::OTHER},
+ // {"de", "nautical-mile", NounClass::OTHER},
+ // {"de", "mile-scandinavian", NounClass::OTHER},
+ // {"de", "point", NounClass::OTHER},
+ // {"de", "lux", NounClass::OTHER},
+ // {"de", "candela", NounClass::OTHER},
+ // {"de", "lumen", NounClass::OTHER},
+ // {"de", "metric-ton", NounClass::OTHER},
+ // {"de", "microgram", NounClass::NEUTER}, // PREFIX
+ // {"de", "ton", NounClass::OTHER},
+ // {"de", "stone", NounClass::OTHER},
+ // {"de", "ounce-troy", NounClass::OTHER},
+ // {"de", "carat", NounClass::OTHER},
+ {"de", "gigawatt", NounClass::NEUTER}, // PREFIX
+ {"de", "milliwatt", NounClass::NEUTER}, // PREFIX
+ // {"de", "horsepower", NounClass::OTHER},
+ // {"de", "millimeter-ofhg", NounClass::OTHER},
+ // {"de", "pound-force-per-square-inch", NounClass::OTHER}, // COMPOUND, pound-force
+ // {"de", "inch-ofhg", NounClass::OTHER},
+ // {"de", "bar", NounClass::OTHER},
+ // {"de", "millibar", NounClass::OTHER}, // PREFIX, bar
+ // {"de", "atmosphere", NounClass::OTHER},
+ // {"de", "pascal", NounClass::OTHER}, // PREFIX, kilopascal? neuter?
+ // {"de", "hectopascal", NounClass::OTHER}, // PREFIX, pascal, neuter?
+ // {"de", "megapascal", NounClass::OTHER}, // PREFIX, pascal, neuter?
+ // {"de", "knot", NounClass::OTHER},
+ {"de", "pound-force-foot", NounClass::MASCULINE}, // COMPOUND
+ {"de", "newton-meter", NounClass::MASCULINE}, // COMPOUND
+ {"de", "cubic-kilometer", NounClass::MASCULINE}, // POWER
+ {"de", "cubic-yard", NounClass::NEUTER}, // POWER
+ {"de", "cubic-inch", NounClass::MASCULINE}, // POWER
+ {"de", "megaliter", NounClass::MASCULINE}, // PREFIX
+ {"de", "hectoliter", NounClass::MASCULINE}, // PREFIX
+ // {"de", "pint-metric", NounClass::OTHER},
+ // {"de", "cup-metric", NounClass::OTHER},
+ {"de", "acre-foot", NounClass::MASCULINE}, // COMPOUND
+ // {"de", "bushel", NounClass::OTHER},
+ // {"de", "barrel", NounClass::OTHER},
+ // Units missing gender in German also misses gender in French:
+ // {"fr", "revolution", NounClass::OTHER},
+ // {"fr", "radian", NounClass::OTHER},
+ // {"fr", "arc-minute", NounClass::OTHER},
+ // {"fr", "arc-second", NounClass::OTHER},
+ {"fr", "square-yard", NounClass::MASCULINE}, // POWER
+ {"fr", "square-inch", NounClass::MASCULINE}, // POWER
+ // {"fr", "dunam", NounClass::OTHER},
+ // {"fr", "karat", NounClass::OTHER},
+ {"fr", "milligram-ofglucose-per-deciliter", NounClass::MASCULINE}, // COMPOUND
+ // {"fr", "millimole-per-liter", NounClass::OTHER}, // COMPOUND, mole
+ // {"fr", "permillion", NounClass::OTHER},
+ // {"fr", "permille", NounClass::OTHER},
+ // {"fr", "permyriad", NounClass::OTHER},
+ // {"fr", "mole", NounClass::OTHER},
+ {"fr", "liter-per-kilometer", NounClass::MASCULINE}, // COMPOUND
+ // {"fr", "petabyte", NounClass::OTHER}, // PREFIX
+ // {"fr", "terabit", NounClass::OTHER}, // PREFIX
+ // {"fr", "century", NounClass::OTHER},
+ // {"fr", "decade", NounClass::OTHER},
+ {"fr", "millisecond", NounClass::FEMININE}, // PREFIX
+ {"fr", "microsecond", NounClass::FEMININE}, // PREFIX
+ {"fr", "nanosecond", NounClass::FEMININE}, // PREFIX
+ // {"fr", "ampere", NounClass::OTHER},
+ // {"fr", "milliampere", NounClass::OTHER}, // PREFIX, ampere
+ // {"fr", "ohm", NounClass::OTHER},
+ // {"fr", "calorie", NounClass::OTHER},
+ // {"fr", "kilojoule", NounClass::OTHER}, // PREFIX, joule
+ // {"fr", "joule", NounClass::OTHER},
+ // {"fr", "kilowatt-hour", NounClass::OTHER}, // COMPOUND
+ // {"fr", "electronvolt", NounClass::OTHER},
+ // {"fr", "british-thermal-unit", NounClass::OTHER},
+ // {"fr", "therm-us", NounClass::OTHER},
+ // {"fr", "pound-force", NounClass::OTHER},
+ // {"fr", "newton", NounClass::OTHER},
+ // {"fr", "gigahertz", NounClass::OTHER}, // PREFIX, hertz
+ // {"fr", "megahertz", NounClass::OTHER}, // PREFIX, hertz
+ // {"fr", "kilohertz", NounClass::OTHER}, // PREFIX, hertz
+ // {"fr", "hertz", NounClass::OTHER},
+ // {"fr", "em", NounClass::OTHER},
+ // {"fr", "pixel", NounClass::OTHER},
+ // {"fr", "megapixel", NounClass::OTHER},
+ // {"fr", "pixel-per-centimeter", NounClass::OTHER}, // COMPOUND, pixel
+ // {"fr", "pixel-per-inch", NounClass::OTHER}, // COMPOUND, pixel
+ // {"fr", "dot-per-centimeter", NounClass::OTHER}, // COMPOUND, dot
+ // {"fr", "dot-per-inch", NounClass::OTHER}, // COMPOUND, dot
+ // {"fr", "dot", NounClass::OTHER},
+ // {"fr", "earth-radius", NounClass::OTHER},
+ {"fr", "decimeter", NounClass::MASCULINE}, // PREFIX
+ {"fr", "micrometer", NounClass::MASCULINE}, // PREFIX
+ {"fr", "nanometer", NounClass::MASCULINE}, // PREFIX
+ // {"fr", "light-year", NounClass::OTHER},
+ // {"fr", "astronomical-unit", NounClass::OTHER},
+ // {"fr", "furlong", NounClass::OTHER},
+ // {"fr", "fathom", NounClass::OTHER},
+ // {"fr", "nautical-mile", NounClass::OTHER},
+ // {"fr", "mile-scandinavian", NounClass::OTHER},
+ // {"fr", "point", NounClass::OTHER},
+ // {"fr", "lux", NounClass::OTHER},
+ // {"fr", "candela", NounClass::OTHER},
+ // {"fr", "lumen", NounClass::OTHER},
+ // {"fr", "metric-ton", NounClass::OTHER},
+ // {"fr", "microgram", NounClass::MASCULINE}, // PREFIX
+ // {"fr", "ton", NounClass::OTHER},
+ // {"fr", "stone", NounClass::OTHER},
+ // {"fr", "ounce-troy", NounClass::OTHER},
+ // {"fr", "carat", NounClass::OTHER},
+ // {"fr", "gigawatt", NounClass::OTHER}, // PREFIX
+ // {"fr", "milliwatt", NounClass::OTHER},
+ // {"fr", "horsepower", NounClass::OTHER},
+ {"fr", "millimeter-ofhg", NounClass::MASCULINE},
+ // {"fr", "pound-force-per-square-inch", NounClass::OTHER}, // COMPOUND, pound-force
+ {"fr", "inch-ofhg", NounClass::MASCULINE},
+ // {"fr", "bar", NounClass::OTHER},
+ // {"fr", "millibar", NounClass::OTHER}, // PREFIX, bar
+ // {"fr", "atmosphere", NounClass::OTHER},
+ // {"fr", "pascal", NounClass::OTHER}, // PREFIX, kilopascal?
+ // {"fr", "hectopascal", NounClass::OTHER}, // PREFIX, pascal
+ // {"fr", "megapascal", NounClass::OTHER}, // PREFIX, pascal
+ // {"fr", "knot", NounClass::OTHER},
+ // {"fr", "pound-force-foot", NounClass::OTHER},
+ // {"fr", "newton-meter", NounClass::OTHER},
+ {"fr", "cubic-kilometer", NounClass::MASCULINE}, // POWER
+ {"fr", "cubic-yard", NounClass::MASCULINE}, // POWER
+ {"fr", "cubic-inch", NounClass::MASCULINE}, // POWER
+ {"fr", "megaliter", NounClass::MASCULINE}, // PREFIX
+ {"fr", "hectoliter", NounClass::MASCULINE}, // PREFIX
+ // {"fr", "pint-metric", NounClass::OTHER},
+ // {"fr", "cup-metric", NounClass::OTHER},
+ {"fr", "acre-foot", NounClass::FEMININE}, // COMPOUND
+ // {"fr", "bushel", NounClass::OTHER},
+ // {"fr", "barrel", NounClass::OTHER},
+ // Some more French units missing gender:
+ // {"fr", "degree", NounClass::OTHER},
+ {"fr", "square-meter", NounClass::MASCULINE}, // POWER
+ // {"fr", "terabyte", NounClass::OTHER}, // PREFIX, byte
+ // {"fr", "gigabyte", NounClass::OTHER}, // PREFIX, byte
+ // {"fr", "gigabit", NounClass::OTHER}, // PREFIX, bit
+ // {"fr", "megabyte", NounClass::OTHER}, // PREFIX, byte
+ // {"fr", "megabit", NounClass::OTHER}, // PREFIX, bit
+ // {"fr", "kilobyte", NounClass::OTHER}, // PREFIX, byte
+ // {"fr", "kilobit", NounClass::OTHER}, // PREFIX, bit
+ // {"fr", "byte", NounClass::OTHER},
+ // {"fr", "bit", NounClass::OTHER},
+ // {"fr", "volt", NounClass::OTHER},
+ // {"fr", "watt", NounClass::OTHER},
+ {"fr", "cubic-meter", NounClass::MASCULINE}, // POWER
+
+ // gender-lacking builtins within compound units
+ {"de", "newton-meter-per-second", NounClass::MASCULINE},
+
+ // TODO(ICU-21494): determine whether list genders behave as follows,
+ // and implement proper getListGender support (covering more than just
+ // two genders):
+ // // gender rule for lists of people: de "neutral", fr "maleTaints"
+ // {"de", "day-and-hour-and-minute", NounClass::NEUTER},
+ // {"de", "hour-and-minute", NounClass::FEMININE},
+ // {"fr", "day-and-hour-and-minute", NounClass::MASCULINE},
+ // {"fr", "hour-and-minute", NounClass::FEMININE},
+ };
+
+ LocalizedNumberFormatter formatter;
+ FormattedNumber fn;
+ for (const TestCase &t : cases) {
+ formatter = NumberFormatter::with()
+ .unit(MeasureUnit::forIdentifier(t.unitIdentifier, status))
+ .locale(Locale(t.locale));
+ fn = formatter.formatDouble(1.1, status);
+ assertEquals(UnicodeString("Testing NounClass with default width, unit: ") + t.unitIdentifier +
+ ", locale: " + t.locale,
+ t.expectedNounClass, fn.getNounClass(status));
+ status.assertSuccess();
+
+ formatter = NumberFormatter::with()
+ .unit(MeasureUnit::forIdentifier(t.unitIdentifier, status))
+ .unitWidth(UNUM_UNIT_WIDTH_FULL_NAME)
+ .locale(Locale(t.locale));
+ fn = formatter.formatDouble(1.1, status);
+ assertEquals(UnicodeString("Testing NounClass with UNUM_UNIT_WIDTH_FULL_NAME, unit: ") +
+ t.unitIdentifier + ", locale: " + t.locale,
+ t.expectedNounClass, fn.getNounClass(status));
+ status.assertSuccess();
+ }
+
+ // Make sure getNounClass does not return garbage for languages without noun classes.
+ formatter = NumberFormatter::with().locale(Locale::getEnglish());
+ fn = formatter.formatDouble(1.1, status);
+ status.assertSuccess();
+ assertEquals("getNounClasses for a not supported language", NounClass::OTHER,
+ fn.getNounClass(status));
+}
+
void NumberFormatterApiTest::unitGender() {
IcuTestErrorCode status(*this, "unitGender");
@@ -2975,6 +3315,28 @@ void NumberFormatterApiTest::roundingFraction() {
Locale::getEnglish(),
1,
"1");
+
+ assertFormatSingle(
+ u"Hide If Whole with Rounding Mode A (ICU-21881)",
+ u".00/w rounding-mode-floor",
+ u".00/w rounding-mode-floor",
+ NumberFormatter::with().precision(Precision::fixedFraction(2)
+ .trailingZeroDisplay(UNUM_TRAILING_ZERO_HIDE_IF_WHOLE))
+ .roundingMode(UNUM_ROUND_FLOOR),
+ Locale::getEnglish(),
+ 3.009,
+ "3");
+
+ assertFormatSingle(
+ u"Hide If Whole with Rounding Mode B (ICU-21881)",
+ u".00/w rounding-mode-half-up",
+ u".00/w rounding-mode-half-up",
+ NumberFormatter::with().precision(Precision::fixedFraction(2)
+ .trailingZeroDisplay(UNUM_TRAILING_ZERO_HIDE_IF_WHOLE))
+ .roundingMode(UNUM_ROUND_HALFUP),
+ Locale::getEnglish(),
+ 3.001,
+ "3");
}
void NumberFormatterApiTest::roundingFigures() {
@@ -2997,6 +3359,15 @@ void NumberFormatterApiTest::roundingFigures() {
u"-98.8");
assertFormatSingle(
+ u"Fixed Significant at rounding boundary",
+ u"@@@",
+ u"@@@",
+ NumberFormatter::with().precision(Precision::fixedSignificantDigits(3)),
+ Locale::getEnglish(),
+ 9.999,
+ u"10.0");
+
+ assertFormatSingle(
u"Fixed Significant Zero",
u"@@@",
u"@@@",
@@ -3156,7 +3527,7 @@ void NumberFormatterApiTest::roundingFractionFigures() {
assertFormatDescending(
u"FracSig withSignificantDigits STRICT",
u"precision-integer/@#s",
- u"./@#",
+ u"./@#s",
NumberFormatter::with().precision(Precision::maxFraction(0)
.withSignificantDigits(1, 2, UNUM_ROUNDING_PRIORITY_STRICT)),
Locale::getEnglish(),
@@ -3180,7 +3551,7 @@ void NumberFormatterApiTest::roundingFractionFigures() {
1,
u"1.00");
- // Trailing zeros are always retained:
+ // Trailing zeros follow the strategy that was chosen:
assertFormatSingle(
u"FracSig withSignificantDigits Trailing Zeros STRICT",
u".0/@@@s",
@@ -3189,7 +3560,7 @@ void NumberFormatterApiTest::roundingFractionFigures() {
.withSignificantDigits(3, 3, UNUM_ROUNDING_PRIORITY_STRICT)),
Locale::getEnglish(),
1,
- u"1.00");
+ u"1.0");
assertFormatSingle(
u"FracSig withSignificantDigits at rounding boundary",
@@ -3199,7 +3570,7 @@ void NumberFormatterApiTest::roundingFractionFigures() {
.withSignificantDigits(3, 3, UNUM_ROUNDING_PRIORITY_STRICT)),
Locale::getEnglish(),
9.99,
- u"10.0");
+ u"10");
assertFormatSingle(
u"FracSig with Trailing Zero Display",
@@ -3397,6 +3768,42 @@ void NumberFormatterApiTest::roundingOther() {
u"0.0",
u"0.0");
+ assertFormatSingle(
+ u"Large integer increment",
+ u"precision-increment/24000000000000000000000",
+ u"precision-increment/24000000000000000000000",
+ NumberFormatter::with().precision(Precision::incrementExact(24, 21)),
+ Locale::getEnglish(),
+ 3.1e22,
+ u"24,000,000,000,000,000,000,000");
+
+ assertFormatSingle(
+ u"Quarter rounding",
+ u"precision-increment/250",
+ u"precision-increment/250",
+ NumberFormatter::with().precision(Precision::incrementExact(250, 0)),
+ Locale::getEnglish(),
+ 700,
+ u"750");
+
+ assertFormatSingle(
+ u"ECMA-402 limit",
+ u"precision-increment/.00000000000000000020",
+ u"precision-increment/.00000000000000000020",
+ NumberFormatter::with().precision(Precision::incrementExact(20, -20)),
+ Locale::getEnglish(),
+ 333e-20,
+ u"0.00000000000000000340");
+
+ assertFormatSingle(
+ u"ECMA-402 limit with increment = 1",
+ u"precision-increment/.00000000000000000001",
+ u"precision-increment/.00000000000000000001",
+ NumberFormatter::with().precision(Precision::incrementExact(1, -20)),
+ Locale::getEnglish(),
+ 4321e-21,
+ u"0.00000000000000000432");
+
assertFormatDescending(
u"Currency Standard",
u"currency/CZK precision-currency-standard",
@@ -3583,6 +3990,67 @@ void NumberFormatterApiTest::roundingIncrementRegressionTest() {
assertEquals("ICU-21668", u"5,000", increment);
}
+void NumberFormatterApiTest::roundingPriorityCoverageTest() {
+ IcuTestErrorCode status(*this, "roundingPriorityCoverageTest");
+ struct TestCase {
+ double input;
+ const char16_t* expectedRelaxed0113;
+ const char16_t* expectedStrict0113;
+ const char16_t* expectedRelaxed1133;
+ const char16_t* expectedStrict1133;
+ } cases[] = {
+ { 0.9999, u"1", u"1", u"1.00", u"1.0" },
+ { 9.9999, u"10", u"10", u"10.0", u"10.0" },
+ { 99.999, u"100", u"100", u"100.0", u"100" },
+ { 999.99, u"1000", u"1000", u"1000.0", u"1000" },
+
+ { 0, u"0", u"0", u"0.00", u"0.0" },
+
+ { 9.876, u"9.88", u"9.9", u"9.88", u"9.9" },
+ { 9.001, u"9", u"9", u"9.00", u"9.0" },
+ };
+ for (const auto& cas : cases) {
+ auto precisionRelaxed0113 = Precision::minMaxFraction(0, 1)
+ .withSignificantDigits(1, 3, UNUM_ROUNDING_PRIORITY_RELAXED);
+ auto precisionStrict0113 = Precision::minMaxFraction(0, 1)
+ .withSignificantDigits(1, 3, UNUM_ROUNDING_PRIORITY_STRICT);
+ auto precisionRelaxed1133 = Precision::minMaxFraction(1, 1)
+ .withSignificantDigits(3, 3, UNUM_ROUNDING_PRIORITY_RELAXED);
+ auto precisionStrict1133 = Precision::minMaxFraction(1, 1)
+ .withSignificantDigits(3, 3, UNUM_ROUNDING_PRIORITY_STRICT);
+
+ auto messageBase = DoubleToUnicodeString(cas.input);
+
+ auto check = [&](
+ const char16_t* name,
+ const UnicodeString& expected,
+ const Precision& precision
+ ) {
+ assertEquals(
+ messageBase + name,
+ expected,
+ NumberFormatter::withLocale(Locale::getEnglish())
+ .precision(precision)
+ .grouping(UNUM_GROUPING_OFF)
+ .formatDouble(cas.input, status)
+ .toString(status)
+ );
+ };
+
+ check(u" Relaxed 0113", cas.expectedRelaxed0113, precisionRelaxed0113);
+ if (status.errIfFailureAndReset()) continue;
+
+ check(u" Strict 0113", cas.expectedStrict0113, precisionStrict0113);
+ if (status.errIfFailureAndReset()) continue;
+
+ check(u" Relaxed 1133", cas.expectedRelaxed1133, precisionRelaxed1133);
+ if (status.errIfFailureAndReset()) continue;
+
+ check(u" Strict 1133", cas.expectedStrict1133, precisionStrict1133);
+ if (status.errIfFailureAndReset()) continue;
+ }
+}
+
void NumberFormatterApiTest::grouping() {
assertFormatDescendingBig(
u"Western Grouping",
@@ -5707,6 +6175,37 @@ void NumberFormatterApiTest::microPropsInternals() {
assertEquals("Copy Assigned capacity", 4, copyAssigned.mixedMeasures.getCapacity());
}
+void NumberFormatterApiTest::formatUnitsAliases() {
+ IcuTestErrorCode status(*this, "formatUnitsAliases");
+
+ struct TestCase {
+ const MeasureUnit measureUnit;
+ const UnicodeString expectedFormat;
+ } testCases[]{
+ // Aliases
+ {MeasureUnit::getMilligramPerDeciliter(), u"2 milligrams per deciliter"},
+ {MeasureUnit::getLiterPer100Kilometers(), u"2 liters per 100 kilometers"},
+ {MeasureUnit::getPartPerMillion(), u"2 parts per million"},
+ {MeasureUnit::getMillimeterOfMercury(), u"2 millimeters of mercury"},
+
+ // Replacements
+ {MeasureUnit::getMilligramOfglucosePerDeciliter(), u"2 milligrams per deciliter"},
+ {MeasureUnit::forIdentifier("millimeter-ofhg", status), u"2 millimeters of mercury"},
+ {MeasureUnit::forIdentifier("liter-per-100-kilometer", status), u"2 liters per 100 kilometers"},
+ {MeasureUnit::forIdentifier("permillion", status), u"2 parts per million"},
+ };
+
+ for (const auto &testCase : testCases) {
+ UnicodeString actualFormat = NumberFormatter::withLocale(icu::Locale::getEnglish())
+ .unit(testCase.measureUnit)
+ .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME)
+ .formatDouble(2.0, status)
+ .toString(status);
+
+ assertEquals("test unit aliases", testCase.expectedFormat, actualFormat);
+ }
+}
+
/* For skeleton comparisons: this checks the toSkeleton output for `f` and for
* `conciseSkeleton` against the normalized version of `uskeleton` - this does
* not round-trip uskeleton itself.
@@ -5882,7 +6381,7 @@ NumberFormatterApiTest::assertFormatSingle(
// Only compare normalized skeletons: the tests need not provide the normalized forms.
// Use the normalized form to construct the testing formatter to ensure no loss of info.
UnicodeString normalized = NumberFormatter::forSkeleton(skeleton, status).toSkeleton(status);
- assertEquals(message + ": Skeleton:", normalized, f.toSkeleton(status));
+ assertEquals(message + ": Skeleton", normalized, f.toSkeleton(status));
LocalizedNumberFormatter l3 = NumberFormatter::forSkeleton(normalized, status).locale(locale);
UnicodeString actual3 = l3.formatDouble(input, status).toString(status);
assertEquals(message + ": Skeleton Path: '" + normalized + "': " + input, expected, actual3);
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_decimalquantity.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_decimalquantity.cpp
index 7403dda7e75..87cd7707b55 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_decimalquantity.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_decimalquantity.cpp
@@ -33,6 +33,7 @@ void DecimalQuantityTest::runIndexedTest(int32_t index, UBool exec, const char *
TESTCASE_AUTO(testNickelRounding);
TESTCASE_AUTO(testScientificAndCompactSuppressedExponent);
TESTCASE_AUTO(testSuppressedExponentUnchangedByInitialScaling);
+ TESTCASE_AUTO(testDecimalQuantityParseFormatRoundTrip);
TESTCASE_AUTO_END;
}
@@ -101,8 +102,11 @@ void DecimalQuantityTest::testDecimalQuantityBehaviorStandalone() {
assertToStringAndHealth(fq, u"<DecimalQuantity 2:-3 long 987654321E-6>");
fq.roundToInfinity();
assertToStringAndHealth(fq, u"<DecimalQuantity 2:-3 long 987654321E-6>");
- fq.roundToIncrement(0.005, RoundingMode::UNUM_ROUND_HALFEVEN, status);
+ fq.roundToIncrement(4, -3, RoundingMode::UNUM_ROUND_HALFEVEN, status);
assertSuccess("Rounding to increment", status);
+ assertToStringAndHealth(fq, u"<DecimalQuantity 2:-3 long 987656E-3>");
+ fq.roundToNickel(-3, RoundingMode::UNUM_ROUND_HALFEVEN, status);
+ assertSuccess("Rounding to nickel", status);
assertToStringAndHealth(fq, u"<DecimalQuantity 2:-3 long 987655E-3>");
fq.roundToMagnitude(-2, RoundingMode::UNUM_ROUND_HALFEVEN, status);
assertSuccess("Rounding to magnitude", status);
@@ -317,7 +321,7 @@ void DecimalQuantityTest::testUseApproximateDoubleWhenAble() {
{1.235, 3, RoundingMode::UNUM_ROUND_CEILING, true}};
UErrorCode status = U_ZERO_ERROR;
- for (TestCase cas : cases) {
+ for (const TestCase& cas : cases) {
DecimalQuantity fq;
fq.setToDouble(cas.d);
assertTrue("Should be using approximate double", !fq.isExplicitExactDouble());
@@ -623,7 +627,7 @@ void DecimalQuantityTest::testScientificAndCompactSuppressedExponent() {
// test the actual computed values of the plural operands
double expectedNOperand = cas.expectedDouble;
- double expectedIOperand = cas.expectedLong;
+ double expectedIOperand = static_cast<double>(cas.expectedLong);
double expectedEOperand = cas.expectedSuppressedScientificExponent;
double expectedCOperand = cas.expectedSuppressedCompactExponent;
double actualNOperand = dq.getPluralOperand(PLURAL_OPERAND_N);
@@ -721,4 +725,52 @@ void DecimalQuantityTest::testSuppressedExponentUnchangedByInitialScaling() {
}
}
+
+void DecimalQuantityTest::testDecimalQuantityParseFormatRoundTrip() {
+ IcuTestErrorCode status(*this, "testDecimalQuantityParseFormatRoundTrip");
+
+ struct TestCase {
+ UnicodeString numberString;
+ } cases[] = {
+ // number string
+ { u"0" },
+ { u"1" },
+ { u"1.0" },
+ { u"1.00" },
+ { u"1.1" },
+ { u"1.10" },
+ { u"-1.10" },
+ { u"0.0" },
+ { u"1c5" },
+ { u"1.0c5" },
+ { u"1.1c5" },
+ { u"1.10c5" },
+ { u"0.00" },
+ { u"0.1" },
+ { u"1c-1" },
+ { u"1.0c-1" }
+ };
+
+ for (const auto& cas : cases) {
+ UnicodeString numberString = cas.numberString;
+
+ DecimalQuantity dq = DecimalQuantity::fromExponentString(numberString, status);
+ UnicodeString roundTrip = dq.toExponentString();
+
+ assertEquals("DecimalQuantity format(parse(s)) should equal original s", numberString, roundTrip);
+ }
+
+ DecimalQuantity dq = DecimalQuantity::fromExponentString(u"1c0", status);
+ assertEquals("Zero ignored for visible exponent",
+ u"1",
+ dq.toExponentString());
+
+ dq.clear();
+ dq = DecimalQuantity::fromExponentString(u"1.0c0", status);
+ assertEquals("Zero ignored for visible exponent",
+ u"1.0",
+ dq.toExponentString());
+
+}
+
#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_range.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_range.cpp
index 08e74df8f52..a47c675c974 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_range.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/numbertest_range.cpp
@@ -811,6 +811,28 @@ void NumberRangeFormatterTest::testFieldPositions() {
expectedFieldPositions,
UPRV_LENGTHOF(expectedFieldPositions));
}
+
+ {
+ const char16_t* message = u"Field position with approximately sign";
+ const char16_t* expectedString = u"~-100";
+ FormattedNumberRange result = assertFormattedRangeEquals(
+ message,
+ NumberRangeFormatter::withLocale("en-us"),
+ -100,
+ -100,
+ expectedString);
+ static const UFieldPositionWithCategory expectedFieldPositions[] = {
+ // category, field, begin index, end index
+ {UFIELD_CATEGORY_NUMBER, UNUM_APPROXIMATELY_SIGN_FIELD, 0, 1},
+ {UFIELD_CATEGORY_NUMBER, UNUM_SIGN_FIELD, 1, 2},
+ {UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD, 2, 5}};
+ checkMixedFormattedValue(
+ message,
+ result,
+ expectedString,
+ expectedFieldPositions,
+ UPRV_LENGTHOF(expectedFieldPositions));
+ }
}
void NumberRangeFormatterTest::testCopyMove() {
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/numfmtst.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/numfmtst.cpp
index 011cc32dd34..7f271cb3f66 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/numfmtst.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/numfmtst.cpp
@@ -3357,6 +3357,7 @@ void NumberFormatTest::TestRoundingPattern() {
void NumberFormatTest::checkRounding(DecimalFormat* df, double base, int iterations, double increment) {
df->setRoundingIncrement(increment);
+ assertEquals("Rounding increment round-trip", increment, df->getRoundingIncrement());
double lastParsed=INT32_MIN; //Intger.MIN_VALUE
for (int i=-iterations; i<=iterations;i++) {
double iValue=base+(increment*(i*0.1));
@@ -4889,9 +4890,9 @@ NumberFormatTest::TestParseCurrencyInUCurr() {
"Peruvian soles1.00",
"Peruvian sol (1863\\u20131965)1.00",
"Peruvian soles (1863\\u20131965)1.00",
- "Philippine Piso1.00",
- "Philippine piso1.00",
- "Philippine pisos1.00",
+ "Philippine Peso1.00",
+ "Philippine peso1.00",
+ "Philippine pesos1.00",
"Platinum1.00",
"Platinum1.00",
"Polish Zloty (1950\\u20131995)1.00",
@@ -5826,9 +5827,9 @@ NumberFormatTest::TestParseCurrencyInUCurr() {
"1.00 Peruvian soles random",
"1.00 Peruvian sol (1863\\u20131965) random",
"1.00 Peruvian soles (1863\\u20131965) random",
- "1.00 Philippine Piso random",
- "1.00 Philippine piso random",
- "1.00 Philippine pisos random",
+ "1.00 Philippine Peso random",
+ "1.00 Philippine peso random",
+ "1.00 Philippine pesos random",
"1.00 Platinum random",
"1.00 Platinum random",
"1.00 Polish Zloty (1950\\u20131995) random",
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/plurults.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/plurults.cpp
index 9131d370317..54cc77a0c9e 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/plurults.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/plurults.cpp
@@ -919,7 +919,7 @@ PluralRulesTest::testDoubleValue() {
const int64_t inputNum = cas.inputNum;
const double expVal = cas.expVal;
- FixedDecimal fd(inputNum);
+ FixedDecimal fd(static_cast<double>(inputNum));
UnicodeString message(u"FixedDecimal::doubleValue() for" + Int64ToUnicodeString(inputNum));
assertEquals(message, expVal, fd.doubleValue());
}
@@ -963,7 +963,7 @@ PluralRulesTest::testLongValue() {
const int64_t inputNum = cas.inputNum;
const int64_t expVal = cas.expVal;
- FixedDecimal fd(inputNum);
+ FixedDecimal fd(static_cast<double>(inputNum));
UnicodeString message(u"FixedDecimal::longValue() for" + Int64ToUnicodeString(inputNum));
assertEquals(message, expVal, fd.longValue());
}
@@ -982,7 +982,7 @@ PluralRulesTest::testLongValue() {
const double inputNum = cas.inputNum;
const int64_t expVal = cas.expVal;
- FixedDecimal fd(inputNum);
+ FixedDecimal fd(static_cast<double>(inputNum));
UnicodeString message(u"FixedDecimal::longValue() for" + DoubleToUnicodeString(inputNum));
assertEquals(message, expVal, fd.longValue());
}
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/rbbitst.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/rbbitst.cpp
index 73d4393843b..69db5db018c 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/rbbitst.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/rbbitst.cpp
@@ -149,6 +149,10 @@ void RBBITest::runIndexedTest( int32_t index, UBool exec, const char* &name, cha
TESTCASE_AUTO(TestTraceCreateLineNormal);
TESTCASE_AUTO(TestTraceCreateLineLoose);
TESTCASE_AUTO(TestTraceCreateLineStrict);
+ TESTCASE_AUTO(TestTraceCreateLineNormalPhrase);
+ TESTCASE_AUTO(TestTraceCreateLineLoosePhrase);
+ TESTCASE_AUTO(TestTraceCreateLineStrictPhrase);
+ TESTCASE_AUTO(TestTraceCreateLinePhrase);
TESTCASE_AUTO(TestTraceCreateBreakEngine);
#endif
@@ -5144,7 +5148,7 @@ void RBBITest::TestTraceCreateLine(void) {
LocalPointer<BreakIterator> brkitr(
BreakIterator::createLineInstance("zh-CN", status));
status.errIfFailureAndReset();
- assertTestTraceResult(UTRACE_UBRK_CREATE_LINE, "");
+ assertTestTraceResult(UTRACE_UBRK_CREATE_LINE, "line");
}
void RBBITest::TestTraceCreateLineStrict(void) {
@@ -5153,7 +5157,7 @@ void RBBITest::TestTraceCreateLineStrict(void) {
LocalPointer<BreakIterator> brkitr(
BreakIterator::createLineInstance("zh-CN-u-lb-strict", status));
status.errIfFailureAndReset();
- assertTestTraceResult(UTRACE_UBRK_CREATE_LINE, "strict");
+ assertTestTraceResult(UTRACE_UBRK_CREATE_LINE, "line_strict");
}
void RBBITest::TestTraceCreateLineNormal(void) {
@@ -5162,7 +5166,7 @@ void RBBITest::TestTraceCreateLineNormal(void) {
LocalPointer<BreakIterator> brkitr(
BreakIterator::createLineInstance("zh-CN-u-lb-normal", status));
status.errIfFailureAndReset();
- assertTestTraceResult(UTRACE_UBRK_CREATE_LINE, "normal");
+ assertTestTraceResult(UTRACE_UBRK_CREATE_LINE, "line_normal");
}
void RBBITest::TestTraceCreateLineLoose(void) {
@@ -5171,7 +5175,43 @@ void RBBITest::TestTraceCreateLineLoose(void) {
LocalPointer<BreakIterator> brkitr(
BreakIterator::createLineInstance("zh-CN-u-lb-loose", status));
status.errIfFailureAndReset();
- assertTestTraceResult(UTRACE_UBRK_CREATE_LINE, "loose");
+ assertTestTraceResult(UTRACE_UBRK_CREATE_LINE, "line_loose");
+}
+
+void RBBITest::TestTraceCreateLineLoosePhrase(void) {
+ SetupTestTrace();
+ IcuTestErrorCode status(*this, "TestTraceCreateLineLoosePhrase");
+ LocalPointer<BreakIterator> brkitr(
+ BreakIterator::createLineInstance("ja-u-lb-loose-lw-phrase", status));
+ status.errIfFailureAndReset();
+ assertTestTraceResult(UTRACE_UBRK_CREATE_LINE, "line_loose_phrase");
+}
+
+void RBBITest::TestTraceCreateLineNormalPhrase(void) {
+ SetupTestTrace();
+ IcuTestErrorCode status(*this, "TestTraceCreateLineNormalPhrase");
+ LocalPointer<BreakIterator> brkitr(
+ BreakIterator::createLineInstance("ja-u-lb-normal-lw-phrase", status));
+ status.errIfFailureAndReset();
+ assertTestTraceResult(UTRACE_UBRK_CREATE_LINE, "line_normal_phrase");
+}
+
+void RBBITest::TestTraceCreateLineStrictPhrase(void) {
+ SetupTestTrace();
+ IcuTestErrorCode status(*this, "TestTraceCreateLineStrictPhrase");
+ LocalPointer<BreakIterator> brkitr(
+ BreakIterator::createLineInstance("ja-u-lb-strict-lw-phrase", status));
+ status.errIfFailureAndReset();
+ assertTestTraceResult(UTRACE_UBRK_CREATE_LINE, "line_strict_phrase");
+}
+
+void RBBITest::TestTraceCreateLinePhrase(void) {
+ SetupTestTrace();
+ IcuTestErrorCode status(*this, "TestTraceCreateLinePhrase");
+ LocalPointer<BreakIterator> brkitr(
+ BreakIterator::createLineInstance("ja-u-lw-phrase", status));
+ status.errIfFailureAndReset();
+ assertTestTraceResult(UTRACE_UBRK_CREATE_LINE, "line_phrase");
}
void RBBITest::TestTraceCreateBreakEngine(void) {
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/rbbitst.h b/Build/source/libs/icu/icu-src/source/test/intltest/rbbitst.h
index acb3e82bbec..d5d52119bc0 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/rbbitst.h
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/rbbitst.h
@@ -105,6 +105,10 @@ public:
void TestTraceCreateLineNormal();
void TestTraceCreateLineStrict();
void TestTraceCreateLineLoose();
+ void TestTraceCreateLineNormalPhrase();
+ void TestTraceCreateLineLoosePhrase();
+ void TestTraceCreateLineStrictPhrase();
+ void TestTraceCreateLinePhrase();
void TestTraceCreateBreakEngine();
#endif
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/strcase.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/strcase.cpp
index 006bcd64ed3..b5eff9f0af8 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/strcase.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/strcase.cpp
@@ -51,6 +51,7 @@ public:
void *iter, const char *localeID, uint32_t options);
void TestCasing();
void TestTitleOptions();
+ void TestDutchTitle();
void TestFullCaseFoldingIterator();
void TestGreekUpper();
void TestArmenian();
@@ -95,6 +96,7 @@ StringCaseTest::runIndexedTest(int32_t index, UBool exec, const char *&name, cha
#if !UCONFIG_NO_BREAK_ITERATION && !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
TESTCASE_AUTO(TestCasing);
TESTCASE_AUTO(TestTitleOptions);
+ TESTCASE_AUTO(TestDutchTitle);
#endif
TESTCASE_AUTO(TestFullCaseFoldingIterator);
TESTCASE_AUTO(TestGreekUpper);
@@ -451,6 +453,7 @@ StringCaseTest::TestCasingImpl(const UnicodeString &input,
}
if(result!=output) {
dataerrln("error: UnicodeString.%s() got a wrong result for a test case from casing.res", name);
+ dataerrln(UnicodeString("input = [") + input + "], expected = [" + output + "], actual = [" + result + "]");
}
#if !UCONFIG_NO_BREAK_ITERATION
if(whichCase==TEST_TITLE && options==0) {
@@ -667,6 +670,106 @@ StringCaseTest::TestTitleOptions() {
#endif
}
+#if !UCONFIG_NO_BREAK_ITERATION
+void StringCaseTest::TestDutchTitle() {
+ IcuTestErrorCode errorCode(*this, "TestDutchTitle");
+
+ Locale nl("nl"); // Dutch
+ LocalPointer<BreakIterator> iter(
+ BreakIterator::createWordInstance(nl, errorCode));
+
+ // Dutch titlecase check in English
+ TestCasingImpl(
+ u"ijssel igloo IJMUIDEN",
+ u"Ijssel Igloo Ijmuiden",
+ TEST_TITLE,
+ nullptr,
+ "en",
+ 0);
+
+ // Dutch titlecase check in Dutch
+ TestCasingImpl(
+ u"ijssel igloo IJMUIDEN",
+ u"IJssel Igloo IJmuiden",
+ TEST_TITLE,
+ nullptr,
+ "nl",
+ 0);
+
+ // Dutch titlecase check in Dutch with nolowercase option
+ if (U_SUCCESS(errorCode)) {
+ iter->setText(u"ijssel igloo IjMUIdEN iPoD ijenough");
+ TestCasingImpl(
+ u"ijssel igloo IjMUIdEN iPoD ijenough",
+ u"IJssel Igloo IJMUIdEN IPoD IJenough",
+ TEST_TITLE,
+ nullptr,
+ "nl",
+ U_TITLECASE_NO_LOWERCASE);
+ }
+
+ errorCode.reset();
+
+ // Accented IJ testing
+
+ struct dutchTitleTestCase {
+ const UnicodeString input;
+ const UnicodeString expectedFull;
+ const UnicodeString expectedOnlyChanged;
+ } dutchTitleTestCases[] = {
+ // input, expectedFull, expectedOnlyChanged
+ {u"ij", u"IJ", u"IJ"},
+ {u"IJ", u"IJ", u""},
+ {u"íj́", u"ÍJ́", u"ÍJ"},
+ {u"ÍJ́", u"ÍJ́", u""},
+ {u"íJ́", u"ÍJ́", u"Í"},
+ {u"Ij́", u"Ij́", u""},
+ {u"ij́", u"Ij́", u"I"},
+ {u"ïj́", u"Ïj́", u"Ï"},
+ {u"íj\u0308", u"Íj\u0308", u"Í"},
+ {u"íj́\U0001D16E", u"Íj́\U0001D16E", u"Í"},
+ {u"íj\u1ABE", u"Íj\u1ABE", u"Í"},
+
+ {u"ijabc", u"IJabc", u"IJ"},
+ {u"IJabc", u"IJabc", u""},
+ {u"íj́abc", u"ÍJ́abc", u"ÍJ"},
+ {u"ÍJ́abc", u"ÍJ́abc", u""},
+ {u"íJ́abc", u"ÍJ́abc", u"Í"},
+ {u"Ij́abc", u"Ij́abc", u""},
+ {u"ij́abc", u"Ij́abc", u"I"},
+ {u"ïj́abc", u"Ïj́abc", u"Ï"},
+ {u"íjabc\u0308", u"Íjabc\u0308", u"Í"},
+ {u"íj́abc\U0001D16E", u"ÍJ́abc\U0001D16E", u"ÍJ"},
+ {u"íjabc\u1ABE", u"Íjabc\u1ABE", u"Í"},
+
+ // Bug ICU-21919
+ {u"Í", u"Í", u""},
+ };
+
+ for (const auto& cas : dutchTitleTestCases) {
+ const UnicodeString &input = cas.input;
+ const UnicodeString &expectedFull = cas.expectedFull;
+ const UnicodeString &expectedOnlyChanged = cas.expectedOnlyChanged;
+
+ for (const auto& isOnlyChanged : {true, false}) {
+ uint32_t testOptions = U_TITLECASE_NO_LOWERCASE
+ | (isOnlyChanged ? U_OMIT_UNCHANGED_TEXT : 0);
+
+ const UnicodeString &expected = isOnlyChanged ? expectedOnlyChanged : expectedFull;
+
+ TestCasingImpl(
+ input,
+ expected,
+ TEST_TITLE,
+ nullptr,
+ "nl",
+ testOptions
+ );
+ }
+ }
+}
+#endif
+
void
StringCaseTest::TestFullCaseFoldingIterator() {
UnicodeString ffi=UNICODE_STRING_SIMPLE("ffi");
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/tmsgfmt.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/tmsgfmt.cpp
index e55aa8fbe37..66f49822217 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/tmsgfmt.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/tmsgfmt.cpp
@@ -2051,7 +2051,7 @@ void TestMessageFormat::TestMessageFormatDateSkeleton() {
UDate date = LocaleTest::date(2021-1900, UCAL_NOVEMBER, 23, 16, 42, 55);
doTheRealDateTimeSkeletonTesting(date, u"{0,date,::MMMMd}", "en", u"November 23", status);
- doTheRealDateTimeSkeletonTesting(date, u"{0,date,::yMMMMdjm}", "en", u"November 23, 2021, 4:42 PM", status);
+ doTheRealDateTimeSkeletonTesting(date, u"{0,date,::yMMMMdjm}", "en", u"November 23, 2021 at 4:42 PM", status);
doTheRealDateTimeSkeletonTesting(date, u"{0,date, :: yMMMMd }", "en", u"November 23, 2021", status);
doTheRealDateTimeSkeletonTesting(date, u"{0,date,::yMMMMd}", "fr", u"23 novembre 2021", status);
doTheRealDateTimeSkeletonTesting(date, u"Expiration: {0,date,::yMMM}!", "en", u"Expiration: Nov 2021!", status);
@@ -2065,7 +2065,7 @@ void TestMessageFormat::TestMessageFormatTimeSkeleton() {
UDate date = LocaleTest::date(2021-1900, UCAL_NOVEMBER, 23, 16, 42, 55);
doTheRealDateTimeSkeletonTesting(date, u"{0,time,::MMMMd}", "en", u"November 23", status);
- doTheRealDateTimeSkeletonTesting(date, u"{0,time,::yMMMMdjm}", "en", u"November 23, 2021, 4:42 PM", status);
+ doTheRealDateTimeSkeletonTesting(date, u"{0,time,::yMMMMdjm}", "en", u"November 23, 2021 at 4:42 PM", status);
doTheRealDateTimeSkeletonTesting(date, u"{0,time, :: yMMMMd }", "en", u"November 23, 2021", status);
doTheRealDateTimeSkeletonTesting(date, u"{0,time,::yMMMMd}", "fr", u"23 novembre 2021", status);
doTheRealDateTimeSkeletonTesting(date, u"Expiration: {0,time,::yMMM}!", "en", u"Expiration: Nov 2021!", status);
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/transtst.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/transtst.cpp
index 8a81b5b3377..aaf283f7a4e 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/transtst.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/transtst.cpp
@@ -3639,7 +3639,7 @@ void TransliteratorTest::TestIncrementalProgress(void) {
Transliterator *t = Transliterator::createInstance(id, UTRANS_FORWARD, err, status);
if (U_FAILURE(status)) {
- dataerrln((UnicodeString)"FAIL: Could not create " + id);
+ dataerrln((UnicodeString)"FAIL: Could not create " + id + ", status " + u_errorName(status));
delete t;
continue;
}
@@ -3654,19 +3654,38 @@ void TransliteratorTest::TestIncrementalProgress(void) {
// 1. Devanagari-Arabic
// 2. Any-*/BGN
// 2a. Any-*/BGN_1981
- // 3. Any-*/UNGEGN
- // 4. Any-*/MNS
- // If UCONFIG_NO_BREAK_ITERATION is on, Latin-Thai is also not expected to work.
+ // 3. Any-*/MNS
+ //
+ // 4. If UCONFIG_NO_BREAK_ITERATION is on, Latin-Thai is also not expected to work.
+ //
+ // The following are direction="both" transforms with variants, inverting the Any-Xxxx/Variant for
+ // any of these does not work; see ICU-21911 (not sure whether this is intentional or an ICU bug).
+ // Unfortunately we do not easily have the info at this point as to whether the original transform
+ // had direction="both" specified.
+ // 5. Any-*/UNGEGN
+ // 6. Any-Ethiopic/*
+ // 7. Any-Braille/*
+ // 8. Any-*/Gurage_2013
+ // 9. Any-*/Gutgarts
+ // 10. Any-*/Tekie_Alibekit
+ // 11. Any-*/Xaleget
+ //
if ( id.compare((UnicodeString)"Devanagari-Arabic/") != 0
&& !(id.startsWith((UnicodeString)"Any-") &&
- (id.endsWith((UnicodeString)"/BGN") || id.endsWith((UnicodeString)"/BGN_1981") || id.endsWith((UnicodeString)"/UNGEGN") || id.endsWith((UnicodeString)"/MNS"))
+ (id.endsWith((UnicodeString)"/BGN") || id.endsWith((UnicodeString)"/BGN_1981") || id.endsWith((UnicodeString)"/MNS"))
)
#if UCONFIG_NO_BREAK_ITERATION
&& id.compare((UnicodeString)"Latin-Thai/") != 0
#endif
+ && !(logKnownIssue("21911", "ICU4C cannot create inverse of Any-Xxxx/Variant transform created from both-direction transform") &&
+ id.startsWith((UnicodeString)"Any-") &&
+ (id.endsWith((UnicodeString)"/UNGEGN") || id.startsWith((UnicodeString)"Any-Ethiopic/") || id.startsWith((UnicodeString)"Any-Braille/") ||
+ id.endsWith((UnicodeString)"/Gurage_2013") || id.endsWith((UnicodeString)"/Gutgarts") || id.endsWith((UnicodeString)"/Tekie_Alibekit") ||
+ id.endsWith((UnicodeString)"/Xaleget"))
+ )
)
{
- errln((UnicodeString)"FAIL: Could not create inverse of " + id);
+ errln((UnicodeString)"FAIL: Could not create inverse of " + id + ", status " + u_errorName(status));
}
delete t;
delete inv;
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/tztest.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/tztest.cpp
index 0d58bab197d..5ae9ae7175c 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/tztest.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/tztest.cpp
@@ -906,7 +906,7 @@ void TimeZoneTest::TestShortZoneIDs()
{"AET", 600, TRUE}, // ICU Link - Australia/Sydney
{"SST", 660, FALSE}, // ICU Link - Pacific/Guadalcanal
{"NST", 720, TRUE}, // ICU Link - Pacific/Auckland
- {"MIT", 780, TRUE}, // ICU Link - Pacific/Apia
+ {"MIT", 780, FALSE}, // ICU Link - Pacific/Apia
{"Etc/Unknown", 0, FALSE}, // CLDR
@@ -2036,12 +2036,20 @@ void TimeZoneTest::TestCanonicalIDAPI() {
void TimeZoneTest::TestCanonicalID() {
- // Some canonical IDs in CLDR are defined as "Link"
- // in Olson tzdata.
+ // Olson (IANA) tzdata used to have very few "Link"s long time ago.
+ // This test case was written when most of CLDR canonical time zones are
+ // defined as independent "Zone" in the TZ database.
+ // Since then, the TZ maintainer found some historic rules in mid 20th century
+ // were not really reliable, and many zones are now sharing rules.
+ // As of TZ database release 2022a, there are quite a lot of zones defined
+ // by "Link" to another zone, so the exception table below becomes really
+ // big. It might be still useful to make sure CLDR zone aliases are consistent
+ // with zone rules.
static const struct {
- const char *alias;
- const char *zone;
+ const char *alias; // link-from
+ const char *zone; // link-to (A zone ID with "Zone" rule)
} excluded1[] = {
+ {"Africa/Accra", "Africa/Abidjan"},
{"Africa/Addis_Ababa", "Africa/Nairobi"},
{"Africa/Asmera", "Africa/Nairobi"},
{"Africa/Bamako", "Africa/Abidjan"},
@@ -2076,35 +2084,43 @@ void TimeZoneTest::TestCanonicalID() {
{"Africa/Ouagadougou", "Africa/Abidjan"},
{"Africa/Porto-Novo", "Africa/Lagos"},
{"Africa/Sao_Tome", "Africa/Abidjan"},
- {"America/Antigua", "America/Port_of_Spain"},
- {"America/Anguilla", "America/Port_of_Spain"},
+ {"America/Antigua", "America/Puerto_Rico"},
+ {"America/Anguilla", "America/Puerto_Rico"},
+ {"America/Aruba", "America/Puerto_Rico"},
+ {"America/Atikokan", "America/Panama"},
+ {"America/Blanc-Sablon", "America/Puerto_Rico"},
{"America/Cayman", "America/Panama"},
{"America/Coral_Harbour", "America/Panama"},
- {"America/Curacao", "America/Aruba"},
- {"America/Dominica", "America/Port_of_Spain"},
- {"America/Grenada", "America/Port_of_Spain"},
- {"America/Guadeloupe", "America/Port_of_Spain"},
- {"America/Kralendijk", "America/Aruba"},
- {"America/Lower_Princes", "America/Aruba"},
- {"America/Marigot", "America/Port_of_Spain"},
- {"America/Montserrat", "America/Port_of_Spain"},
+ {"America/Creston", "America/Phoenix"},
+ {"America/Curacao", "America/Puerto_Rico"},
+ {"America/Dominica", "America/Puerto_Rico"},
+ {"America/Grenada", "America/Puerto_Rico"},
+ {"America/Guadeloupe", "America/Puerto_Rico"},
+ {"America/Kralendijk", "America/Puerto_Rico"},
+ {"America/Lower_Princes", "America/Puerto_Rico"},
+ {"America/Marigot", "America/Puerto_Rico"},
+ {"America/Montreal", "America/Toronto"},
+ {"America/Montserrat", "America/Puerto_Rico"},
+ {"America/Nassau", "America/Toronto"},
+ {"America/Port_of_Spain", "America/Puerto_Rico"},
{"America/Santa_Isabel", "America/Tijuana"},
{"America/Shiprock", "America/Denver"},
- {"America/St_Barthelemy", "America/Port_of_Spain"},
- {"America/St_Kitts", "America/Port_of_Spain"},
- {"America/St_Lucia", "America/Port_of_Spain"},
- {"America/St_Thomas", "America/Port_of_Spain"},
- {"America/St_Vincent", "America/Port_of_Spain"},
- {"America/Toronto", "America/Montreal"},
- {"America/Tortola", "America/Port_of_Spain"},
+ {"America/St_Barthelemy", "America/Puerto_Rico"},
+ {"America/St_Kitts", "America/Puerto_Rico"},
+ {"America/St_Lucia", "America/Puerto_Rico"},
+ {"America/St_Thomas", "America/Puerto_Rico"},
+ {"America/St_Vincent", "America/Puerto_Rico"},
+ {"America/Tortola", "America/Puerto_Rico"},
{"America/Virgin", "America/Puerto_Rico"},
+ {"Antarctica/DumontDUrville", "Pacific/Port_Moresby"},
{"Antarctica/South_Pole", "Antarctica/McMurdo"},
+ {"Antarctica/Syowa", "Asia/Riyadh"},
{"Arctic/Longyearbyen", "Europe/Oslo"},
- {"Asia/Kuwait", "Asia/Aden"},
+ {"Asia/Aden", "Asia/Riyadh"},
+ {"Asia/Kuwait", "Asia/Riyadh"},
{"Asia/Muscat", "Asia/Dubai"},
{"Asia/Phnom_Penh", "Asia/Bangkok"},
{"Asia/Qatar", "Asia/Bahrain"},
- {"Asia/Riyadh", "Asia/Aden"},
{"Asia/Vientiane", "Asia/Bangkok"},
{"Atlantic/Jan_Mayen", "Europe/Oslo"},
{"Atlantic/St_Helena", "Africa/Abidjan"},
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/units_test.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/units_test.cpp
index c65a5e03229..ca41e3b0d03 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/units_test.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/units_test.cpp
@@ -325,6 +325,12 @@ void UnitsTest::testConverter() {
// Fuel Consumption
{"cubic-meter-per-meter", "mile-per-gallon", 2.1383143939394E-6, 1.1},
{"cubic-meter-per-meter", "mile-per-gallon", 2.6134953703704E-6, 0.9},
+ {"liter-per-100-kilometer", "mile-per-gallon", 6.6, 35.6386},
+ {"liter-per-100-kilometer", "mile-per-gallon", 0, uprv_getInfinity()},
+ {"mile-per-gallon", "liter-per-100-kilometer", 0, uprv_getInfinity()},
+ {"mile-per-gallon", "liter-per-100-kilometer", uprv_getInfinity(), 0},
+ // We skip testing -Inf, because the inverse conversion loses the sign:
+ // {"mile-per-gallon", "liter-per-100-kilometer", -uprv_getInfinity(), 0},
// Test Aliases
// Alias is just another name to the same unit. Therefore, converting
@@ -348,54 +354,42 @@ void UnitsTest::testConverter() {
continue;
}
+ double maxDelta = 1e-6 * uprv_fabs(testCase.expectedValue);
+ if (testCase.expectedValue == 0) {
+ maxDelta = 1e-12;
+ }
+ double inverseMaxDelta = 1e-6 * uprv_fabs(testCase.inputValue);
+ if (testCase.inputValue == 0) {
+ inverseMaxDelta = 1e-12;
+ }
+
ConversionRates conversionRates(status);
if (status.errIfFailureAndReset("conversionRates(status)")) {
continue;
}
+
UnitsConverter converter(source, target, conversionRates, status);
if (status.errIfFailureAndReset("UnitsConverter(<%s>, <%s>, ...)", testCase.source,
testCase.target)) {
continue;
}
-
- double maxDelta = 1e-6 * uprv_fabs(testCase.expectedValue);
- if (testCase.expectedValue == 0) {
- maxDelta = 1e-12;
- }
assertEqualsNear(UnicodeString("testConverter: ") + testCase.source + " to " + testCase.target,
testCase.expectedValue, converter.convert(testCase.inputValue), maxDelta);
-
- maxDelta = 1e-6 * uprv_fabs(testCase.inputValue);
- if (testCase.inputValue == 0) {
- maxDelta = 1e-12;
- }
assertEqualsNear(
UnicodeString("testConverter inverse: ") + testCase.target + " back to " + testCase.source,
- testCase.inputValue, converter.convertInverse(testCase.expectedValue), maxDelta);
+ testCase.inputValue, converter.convertInverse(testCase.expectedValue), inverseMaxDelta);
-
- // TODO: Test UnitsConverter created using CLDR separately.
// Test UnitsConverter created by CLDR unit identifiers
UnitsConverter converter2(testCase.source, testCase.target, status);
if (status.errIfFailureAndReset("UnitsConverter(<%s>, <%s>, ...)", testCase.source,
testCase.target)) {
continue;
}
-
- maxDelta = 1e-6 * uprv_fabs(testCase.expectedValue);
- if (testCase.expectedValue == 0) {
- maxDelta = 1e-12;
- }
assertEqualsNear(UnicodeString("testConverter2: ") + testCase.source + " to " + testCase.target,
testCase.expectedValue, converter2.convert(testCase.inputValue), maxDelta);
-
- maxDelta = 1e-6 * uprv_fabs(testCase.inputValue);
- if (testCase.inputValue == 0) {
- maxDelta = 1e-12;
- }
assertEqualsNear(
UnicodeString("testConverter2 inverse: ") + testCase.target + " back to " + testCase.source,
- testCase.inputValue, converter2.convertInverse(testCase.expectedValue), maxDelta);
+ testCase.inputValue, converter2.convertInverse(testCase.expectedValue), inverseMaxDelta);
}
}
@@ -647,6 +641,16 @@ void UnitsTest::testComplexUnitsConverter() {
Measure(2.1, MeasureUnit::createMeter(status), status)},
2,
0.001},
+
+ // Negative numbers
+ {"Negative number conversion",
+ "yard",
+ "mile-and-yard",
+ -1800,
+ {Measure(-1, MeasureUnit::createMile(status), status),
+ Measure(-40, MeasureUnit::createYard(status), status)},
+ 2,
+ 1e-10},
};
status.assertSuccess();
@@ -694,11 +698,7 @@ void UnitsTest::testComplexUnitsConverter() {
ComplexUnitsConverter converter2( testCase.input, testCase.output, status);
testATestCase(converter2, "ComplexUnitsConverter #1 " , testCase);
}
-
-
status.assertSuccess();
-
- // TODO(icu-units#63): test negative numbers!
}
void UnitsTest::testComplexUnitsConverterSorting() {
diff --git a/Build/source/libs/icu/icu-src/source/test/intltest/ustrtest.cpp b/Build/source/libs/icu/icu-src/source/test/intltest/ustrtest.cpp
index cd9751d761b..309a29713d7 100644
--- a/Build/source/libs/icu/icu-src/source/test/intltest/ustrtest.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/intltest/ustrtest.cpp
@@ -1653,6 +1653,16 @@ UnicodeStringTest::TestBogus() {
if(test1>=test2 || !(test2>test1) || test1.compare(test2)>=0 || !(test2.compare(test1)>0)) {
errln("bogus<empty failed");
}
+
+ // test that copy constructor of bogus is bogus & clone of bogus is nullptr
+ {
+ test3.setToBogus();
+ UnicodeString test3Copy(test3);
+ UnicodeString *test3Clone = test3.clone();
+ assertTrue(WHERE, test3.isBogus());
+ assertTrue(WHERE, test3Copy.isBogus());
+ assertTrue(WHERE, test3Clone == nullptr);
+ }
}
// StringEnumeration ------------------------------------------------------- ***
@@ -2354,7 +2364,7 @@ void UnicodeStringTest::TestLargeAppend() {
} else if (total <= INT32_MAX) {
// Check that a string of exactly the maximum size works
UnicodeString str2;
- int32_t remain = INT32_MAX - total;
+ int32_t remain = static_cast<int32_t>(INT32_MAX - total);
char16_t *buf2 = str2.getBuffer(remain);
if (buf2 == nullptr) {
// if somehow memory allocation fail, return the test
diff --git a/Build/source/libs/icu/icu-src/source/test/iotest/strtst.c b/Build/source/libs/icu/icu-src/source/test/iotest/strtst.c
index ee67b4c3ab1..3ffec2b25dc 100644
--- a/Build/source/libs/icu/icu-src/source/test/iotest/strtst.c
+++ b/Build/source/libs/icu/icu-src/source/test/iotest/strtst.c
@@ -315,9 +315,10 @@ static void TestLocalizedString(void) {
#if !UCONFIG_NO_FORMATTING
#define Test_u_snprintf(limit, format, value, expectedSize, expectedStr) UPRV_BLOCK_MACRO_BEGIN { \
u_uastrncpy(testStr, "xxxxxxxxxxxxxx", UPRV_LENGTHOF(testStr));\
- size = u_snprintf(testStr, limit, format, value);\
+ size = u_snprintf(0, 0, format, value);\
+ written = u_snprintf(testStr, limit, format, value);\
u_austrncpy(cTestResult, testStr, UPRV_LENGTHOF(cTestResult));\
- if (size != expectedSize || strcmp(cTestResult, expectedStr) != 0) {\
+ if (size != written || size != expectedSize || strcmp(cTestResult, expectedStr) != 0) {\
log_err("Unexpected formatting. size=%d expectedSize=%d cTestResult=%s expectedStr=%s\n",\
size, expectedSize, cTestResult, expectedStr);\
}\
@@ -332,7 +333,7 @@ static void TestSnprintf(void) {
#if !UCONFIG_NO_FORMATTING
UChar testStr[256];
char cTestResult[256];
- int32_t size;
+ int32_t size, written;
Test_u_snprintf(0, "%d", 123, 3, "xxxxxxxxxxxxxx");
Test_u_snprintf(2, "%d", 123, 3, "12xxxxxxxxxxxx");
diff --git a/Build/source/libs/icu/icu-src/source/test/perf/Makefile.in b/Build/source/libs/icu/icu-src/source/test/perf/Makefile.in
index cb7c2f15943..85469cf092f 100644
--- a/Build/source/libs/icu/icu-src/source/test/perf/Makefile.in
+++ b/Build/source/libs/icu/icu-src/source/test/perf/Makefile.in
@@ -22,7 +22,7 @@ subdir = test/perf
## Files to remove for 'make clean'
CLEANFILES = *~
-SUBDIRS = collationperf collperf collperf2 charperf dicttrieperf localecanperf normperf ubrkperf unisetperf usetperf ustrperf utfperf utrie2perf DateFmtPerf howExpensiveIs
+SUBDIRS = collationperf collperf collperf2 charperf dicttrieperf localecanperf normperf strsrchperf ubrkperf unisetperf usetperf ustrperf utfperf utrie2perf DateFmtPerf howExpensiveIs
# Subdirs that support 'xperf'
XSUBDIRS = DateFmtPerf
@@ -38,10 +38,7 @@ check check-recursive check-local xperf xperf-recursive
## List of standard targets
everything: all-recursive all-local
-all:
-ifneq ($(RECURSIVE),YES)
- @echo simply use \`make\' \(or \`make everything\'\) to do all
-endif
+all: everything
install: install-recursive install-local
clean: clean-recursive clean-local
diff --git a/Build/source/libs/icu/icu-src/source/test/perf/charperf/charperf.cpp b/Build/source/libs/icu/icu-src/source/test/perf/charperf/charperf.cpp
index 6fc576cd235..651434b6a49 100644
--- a/Build/source/libs/icu/icu-src/source/test/perf/charperf/charperf.cpp
+++ b/Build/source/libs/icu/icu-src/source/test/perf/charperf/charperf.cpp
@@ -81,7 +81,6 @@ CharPerformanceTest::CharPerformanceTest(int32_t argc, const char *argv[],
else {
MAX_ = 0xffff;
}
- printf("MAX_ size will be 0x%x\n", MAX_);
if (options[MIN_OPTION_].doesOccur) {
MIN_ = atoi(options[MIN_OPTION_].value);
}
diff --git a/Build/source/libs/icu/icu-src/source/test/perf/ustrperf/Makefile.in b/Build/source/libs/icu/icu-src/source/test/perf/ustrperf/Makefile.in
index 4d601137ac0..8ef95af01d2 100644
--- a/Build/source/libs/icu/icu-src/source/test/perf/ustrperf/Makefile.in
+++ b/Build/source/libs/icu/icu-src/source/test/perf/ustrperf/Makefile.in
@@ -20,7 +20,7 @@ subdir = test/perf/ustrperf
CLEANFILES = *~ $(DEPS)
## Target information
-TARGET = stringperf
+TARGET = ustrperf
CPPFLAGS += -I$(top_srcdir)/common -I$(top_srcdir)/tools/toolutil -I$(top_srcdir)/tools/ctestfw
LIBS = $(LIBCTESTFW) $(LIBICUI18N) $(LIBICUUC) $(LIBICUTOOLUTIL) $(DEFAULT_LIBS) $(LIB_M)
diff --git a/Build/source/libs/icu/icu-src/source/test/perf/ustrperf/stringperf.h b/Build/source/libs/icu/icu-src/source/test/perf/ustrperf/stringperf.h
index 59b841865a3..39ca45987c9 100644
--- a/Build/source/libs/icu/icu-src/source/test/perf/ustrperf/stringperf.h
+++ b/Build/source/libs/icu/icu-src/source/test/perf/ustrperf/stringperf.h
@@ -444,7 +444,6 @@ inline void catenate(const UChar* src,int32_t srcLen, UnicodeString s0)
utimer_getTime(&mystop);
double mytime = utimer_getDeltaSeconds(&mystart,&mystop);
- printf("\nmytime=%f \n", mytime);
*catICU += uCatenate_STR;
}
@@ -533,7 +532,6 @@ inline void StdLibCatenate(const wchar_t* src,int32_t srcLen, stlstring s0)
utimer_getTime(&mystop);
double mytime = utimer_getDeltaSeconds(&mystart,&mystop);
- printf("\nmytime=%f \n", mytime);
}
diff --git a/Build/source/libs/icu/icu-src/source/test/testdata/break_rules/line_loose_cj.txt b/Build/source/libs/icu/icu-src/source/test/testdata/break_rules/line_loose_cj.txt
index d0693d567cd..9d7b2cc12c6 100644
--- a/Build/source/libs/icu/icu-src/source/test/testdata/break_rules/line_loose_cj.txt
+++ b/Build/source/libs/icu/icu-src/source/test/testdata/break_rules/line_loose_cj.txt
@@ -20,7 +20,8 @@
# line-break=loose (BCP47 -u-lb-loose) as defined for Chinese & Japanese.
# It sets characters of class CJ to behave like ID.
# In addition, it allows breaks:
-# * before hyphens 2010 & 2013 (both BA) and 301C, 30A0 (both NS)
+# * between ID and hyphens 2010 & 2013 (both BA)
+# * before 301C, 30A0 (both NS)
# * before iteration marks 3005, 303B, 309D, 309E, 30FD, 30FE (all NS)
# * between characters of LineBreak class IN such as 2026
# * before some centered punct 203C, 2047, 2048, 2049, 30FB, FF1A, FF1B,
@@ -200,8 +201,9 @@ LB20.09: ^(HY | HH) CM* AL;
LB21a: HL CM* (HY | BA | BAX) CM* [^CM CB]?;
-LB21.1: . CM* [BA HY NS];
-LB21.2: BB CM* [^CM CB];
+LB21.1: [^ID] CM* [BA BAX HY NS];
+LB21.2: ID CM* [BA HY NS];
+LB21.3: BB CM* [^CM CB];
LB21b: SY CM* HL;
@@ -236,9 +238,9 @@ LB30.1: (AL | CM | HL | NU) CM* OP30;
LB30.2: CP30 CM* (AL | HL | NU);
# LB30a keep pairs of RI together.
-LB30a.1: RI CM* RI ÷ [^BK CR LF NL SP ZW WJ CL CP EX IS SY GL QU BA HY NS IN CM];
-LB30a.2: RI CM* RI CM* CMS ÷ [^BK CR LF NL SP ZW WJ CL CP EX IS SY GL QU BA HY NS IN CM];
-LB30a.3: RI CM* RI CM* [BK CR LF NL SP ZW WJ GL CL CP EX IS SY QU BA HY NS IN ZWJ]?;
+LB30a.1: RI CM* RI ÷ [^BK CR LF NL SP ZW WJ CL CP EX IS SY GL QU BA BAX HY NS IN CM];
+LB30a.2: RI CM* RI CM* CMS ÷ [^BK CR LF NL SP ZW WJ CL CP EX IS SY GL QU BA BAX HY NS IN CM];
+LB30a.3: RI CM* RI CM* [BK CR LF NL SP ZW WJ GL CL CP EX IS SY QU BA BAX HY NS IN ZWJ]?;
# LB30b Do not break between Emoji Base (or potential emoji) and Emoji Modifier
LB30b.1: EB CM* EM;
diff --git a/Build/source/libs/icu/icu-src/source/test/testdata/break_rules/line_normal_cj.txt b/Build/source/libs/icu/icu-src/source/test/testdata/break_rules/line_normal_cj.txt
index a2704821441..a4e1428c2b2 100644
--- a/Build/source/libs/icu/icu-src/source/test/testdata/break_rules/line_normal_cj.txt
+++ b/Build/source/libs/icu/icu-src/source/test/testdata/break_rules/line_normal_cj.txt
@@ -20,7 +20,7 @@
# line-break=normal (BCP47 -u-lb-normal) as defined for Chinese & Japanese.
# It sets characters of class CJ to behave like ID.
# In addition, it allows breaks:
-# * before hyphens 2010 & 2013 (both BA) and 301C, 30A0 (both NS)
+# * before 301C, 30A0 (both NS)
# It allows breaking before 201C and after 201D, for zh_Hans, zh_Hant, and ja.
type = line;
@@ -28,8 +28,7 @@ locale = ja@lb=normal;
AI = [:LineBreak = Ambiguous:];
AL = [:LineBreak = Alphabetic:];
-BAX = [\u2010 \u2013];
-BA = [[:LineBreak = Break_After:] - BAX];
+BA = [:LineBreak = Break_After:];
HH = [\u2010]; # \u2010 is HYPHEN, default line break is BA.
BB = [:LineBreak = Break_Before:];
BK = [:LineBreak = Mandatory_Break:];
@@ -154,7 +153,7 @@ LB11.3: WJ CM* [^CM];
LB12: GL CM* [^CM];
-LB12a: [^SP BA BAX HY] CM* GL;
+LB12a: [^SP BA HY] CM* GL;
# LB 13 Do not break before ‘]’ or ‘!’ or ‘/’, even after spaces.
LB13.1: [^SP] CM* [CL CP EX SY];
@@ -182,12 +181,9 @@ LB20.09: ^(HY | HH) CM* AL;
# Note: Rule 21a must come before 21 to prevent 21.1 from matching HL BA, then
# not picking up the continuing match after the BA from 21a.
-# TODO: For CJ tailorings (with BAX) does this rule want to include BAX? If so,
-# should "HL BAX" not break when followed by a CB? Thats what the current
-# rules do, which is why "[^CM CB]?" includes the ?.
-LB21a: HL CM* (HY | BA | BAX) CM* [^CM CB]?;
+LB21a: HL CM* (HY | BA) CM* [^CM CB]?;
-# DO allow breaks here before $BAXcm and $NSXcm, so don't include them
+# DO allow breaks here before $NSXcm, so don't include it
LB21.1: . CM* [BA HY NS];
LB21.2: BB CM* [^CM CB];
diff --git a/Build/source/libs/icu/icu-src/source/test/testdata/rbbitst.txt b/Build/source/libs/icu/icu-src/source/test/testdata/rbbitst.txt
index 7fb30c9e8e3..a8d1e8e7158 100644
--- a/Build/source/libs/icu/icu-src/source/test/testdata/rbbitst.txt
+++ b/Build/source/libs/icu/icu-src/source/test/testdata/rbbitst.txt
@@ -796,6 +796,9 @@
<word>
<data>•ジョージア<400> •</data>
+<word>
+<data>•[<0>携帯<400>電話<400>]<0>お金<400>が<400>かかる<400>ん<400>です<400>。<0></data>
+
# Test for #11723
<word>
<data>•アレルギー性<400>結膜炎<400></data>
@@ -1445,6 +1448,9 @@ Bangkok)•</data>
<data>•ກວາກຊວາກ•ກະເຈາະກະຈອກ•</data>
<data>•ກະຊວງປ້ອງກັນຄວາມສະຫງົບ•</data>
<data>•ໄຮ•ໄຮ່•ໄຮ້•</data>
+# Checks for ICU-21409 (and ICU-21384)
+<line>
+<data>•ຣະຄັງ•ຣະມາ•ລູຊີເຟີ•</data>
##########################################################################################
#
@@ -1643,11 +1649,17 @@ Bangkok)•</data>
# •brk OK before 3063 •brk OK before 301C •no brk btw 2026 •no brk before FF01•
<data>•\u3084•\u3063•\u3071•\u308A\u0020•\u0031•\u301C\u0020•\u2026\u2026\u0020•\u30A2\uFF01\u0020•</data>
+# •no brk before 2010 •
+<data>•\u3042\u2010•\u0031\u0020•\u0061\u2010•\u0031\u0020•</data>
+
<locale ja@lb=loose>
<line>
# •brk OK before 3063 •brk OK before 301C •brk OK btw 2026 •brk OK before FF01•
<data>•\u3084•\u3063•\u3071•\u308A\u0020•\u0031•\u301C\u0020•\u2026•\u2026\u0020•u30A2•\uFF01\u0020•</data>
+# •no brk before 2010 except ok after ID •
+<data>•\u3042•\u2010•\u0031\u0020•\u0061\u2010•\u0031\u0020•</data>
+
<locale en@lb=strict>
<line>
# •no brk before 3063 •no brk before 301C•no brk btw 2026 •no brk before FF01•
@@ -1881,6 +1893,48 @@ Bangkok)•</data>
# woman astronaut, woman astronaut / fitz4
<data>•\U0001F469\u200D\U0001F680•\U0001F469\U0001F3FD\u200D\U0001F680\u0020•</data>
+<locale ja@lw=phrase>
+<line>
+#[京都観光]時雨殿に行った。-> [京都•観光]•時雨•殿に•行った。•
+<data>•\uff3b\u4eac\u90fd•\u89b3\u5149\uff3d•\u6642\u96e8•\u6bbf\u306b•\u884c\u3063\u305f\u3002•</data>
+#9月に東京から友達が遊びに来た -> 9月に•東京から•友達が•遊びに•来た•
+<data>•\uff19\u6708\u306b•\u6771\u4eac\u304b\u3089•\u53cb\u9054\u304c•\u904a\u3073\u306b•\u6765\u305f•</data>
+#る文字「そうだ、京都」-> る•文字•「そうだ、•京都」•
+<data>•\u308b•\u6587\u5b57•\u300c\u305d\u3046\u3060\u3001•\u4eac\u90fd\u300d•</data>
+#乗車率90%程度だろうか。 -> 乗車•率•90%•程度だろうか。•
+<data>•\u4e57\u8eca•\u7387•\uff19\uff10\uff05•\u7a0b\u5ea6\u3060\u308d\u3046\u304b\u3002•</data>
+#[携帯電話]正しい選択 -> [携帯•電話]•正しい•選択•
+<data>•\uff3b\u643a\u5e2f•\u96fb\u8a71\uff3d•\u6b63\u3057\u3044•\u9078\u629e•</data>
+#純金製百人一首にサッカーボール -> 純金•製•百人一首に•サッカーボール
+<data>•\u7D14\u91D1•\u88FD•\u767E\u4EBA\u4E00\u9996\u306B•\u30B5\u30C3\u30AB\u30FC\u30DC\u30FC\u30EB•</data>
+#Kana supplement: 𛁈(U+1B048) -> \uD82C\uDC48, 𛀸(U+1B038) -> \uD82C\uDC38, 𛀙(U+1B019)-> \uD82C\uDC19</data>
+#𛁈る𛀸(しるこ)、あ𛀙よろし(あかよろし) -> 𛁈る𛀸•(しるこ)、•あ𛀙よろし•(あ•かよろし)
+<data>•\uD82C\uDC48\u308B\uD82C\uDC38•\uFF08\u3057\u308B\u3053\uFF09\u3001•\u3042\uD82C\uDC19\u3088\u308D\u3057•\uFF08\u3042•\u304B\u3088\u308D\u3057\uFF09•</data>
+#最初に目に入るのは、「許諾なき写真禁止」のサインである。 -> 最初に▁目に▁入るのは、▁「許諾なき▁写真▁禁止」▁の▁サインで▁ある。
+<data>•\u6700\u521D\u306B•\u76EE\u306B•\u5165\u308B\u306E\u306F\u3001•\u300C\u8A31\u8AFE\u306A\u304D•\u5199\u771F•\u7981\u6B62\u300D•\u306E•\u30B5\u30A4\u30F3\u3067•\u3042\u308B\u3002•</data>
+#docomoのサイト情報によると、78000パケット以上▁使うならパケ放題がいいとか -> docomoの▁サイト▁情報によると、▁78000パケット▁以上▁使うなら▁パケ▁放題が▁いい▁とか
+<data>•\uFF44\uFF4F\uFF43\uFF4F\uFF4D\uFF4F\u306E•\u30B5\u30A4\u30C8•\u60C5\u5831\u306B\u3088\u308B\u3068\u3001•\uFF17\uFF18\uFF10\uFF10\uFF10\u30D1\u30B1\u30C3\u30C8•\u4EE5\u4E0A•\u4F7F\u3046\u306A\u3089•\u30D1\u30B1•\u653E\u984C\u304C•\u3044\u3044•\u3068\u304B•</data>
+#日本の携帯はCDMAの形だといわれています -> 日本の▁携帯は▁CDMAの▁形だと▁いわれ▁ています
+<data>•\u65E5\u672C\u306E•\u643A\u5E2F\u306F•\uFF23\uFF24\uFF2D\uFF21\u306E•\u5F62\u3060\u3068•\u3044\u308F\u308C•\u3066\u3044\u307E\u3059•</data>
+#中国の携帯は約500元から5000元です -> 中国の▁携帯は▁約▁500元から▁5000元です
+<data>•\u4E2D\u56FD\u306E•\u643A\u5E2F\u306F•\u7D04•\uFF15\uFF10\uFF10\u5143\u304B\u3089•\uFF15\uFF10\uFF10\uFF10\u5143\u3067\u3059•</data>
+#プリペイドカード携帯布教 -> プリペイドカード▁携帯▁布教
+<data>•\u30D7\u30EA\u30DA\u30A4\u30C9\u30AB\u30FC\u30C9•\u643A\u5E2F•\u5E03\u6559•</data>
+#しかもロゴがUnicode!! -> しかも▁ロゴが▁Unicode!!
+<data>•\u3057\u304B\u3082•\u30ED\u30B4\u304C•\uFF35\uFF4E\uFF49\uFF43\uFF4F\uFF44\uFF45\uFF01\uFF01•</data>
+#しかし、これらのサービスは6年間使ってこなかった自分にとっては特に必要でないものであり、これからこの機能が加わったからといって特別ハッピーなわけでもない。
+#-> しかし、▁これらの▁サービスは▁6年間▁使ってこなかった▁自分にとっては▁特に▁必要でない▁もので▁あり、▁これから▁この▁機能が▁加わったから▁といって▁特別▁ハッピーな▁わけでもない。
+<data>•\u3057\u304B\u3057\u3001•\u3053\u308C\u3089\u306E•\u30B5\u30FC\u30D3\u30B9\u306F•\uFF16\u5E74\u9593•\u4F7F\u3063\u3066\u3053\u306A\u304B\u3063\u305F•\u81EA\u5206\u306B\u3068\u3063\u3066\u306F•\u7279\u306B•\u5FC5\u8981\u3067\u306A\u3044•\u3082\u306E\u3067•\u3042\u308A\u3001•\u3053\u308C\u304B\u3089•\u3053\u306E•\u6A5F\u80FD\u304C•\u52A0\u308F\u3063\u305F\u304B\u3089•\u3068\u3044\u3063\u3066•\u7279\u5225•\u30CF\u30C3\u30D4\u30FC\u306A•\u308F\u3051\u3067\u3082\u306A\u3044\u3002•</data>
+#自由が丘での三ヶ月の生活を通して得られる経験 -> 自由が丘での▁三ヶ月の▁生活を通して▁得られる▁経験
+<data>•\u81EA\u7531\u304C\u4E18\u3067\u306E•\u4E09\u30F6\u6708\u306E•\u751F\u6D3B\u3092\u901A\u3057\u3066•\u5F97\u3089\u308C\u308B•\u7D4C\u9A13•</data>
+#幕の内弁当がよく買われるらしいです。 -> 幕の内▁弁当が▁よく▁買われるらしいです。
+<data>•\u5E55\u306E\u5185•\u5F01\u5F53\u304C•\u3088\u304F•\u8CB7\u308F\u308C\u308B\u3089\u3057\u3044\u3067\u3059\u3002•</data>
+#その名の通りに伝われと望まれています。 -> その▁名の通りに▁伝われと▁望まれ▁ています。
+<data>•\u305D\u306E•\u540D\u306E\u901A\u308A\u306B•\u4F1D\u308F\u308C\u3068•\u671B\u307E\u308C•\u3066\u3044\u307E\u3059\u3002•</data>
+#下鴨神社の糺の森は、静かだし、ちょっとした空き時間の散歩にいいですよ♪ -> 下鴨▁神社の▁糺の森は、▁静か▁だし、▁ちょっとした▁空き▁時間の▁散歩に▁いいですよ♪
+<data>•\u4E0B\u9D28•\u795E\u793E\u306E•\u7CFA\u306E\u68EE\u306F\u3001•\u9759\u304B•\u3060\u3057\u3001•\u3061\u3087\u3063\u3068\u3057\u305F•\u7A7A\u304D•\u6642\u9593\u306E•\u6563\u6B69\u306B•\u3044\u3044\u3067\u3059\u3088\u266A•</data>
+#この論理は、別の弱点から逃避するためによく使われるので注意が必要ですが。 -> この▁論理は、▁別の▁弱点から▁逃避▁する▁ために▁よく▁使われるので▁注意が▁必要▁ですが。
+<data>•\u3053\u306E•\u8AD6\u7406\u306F\u3001•\u5225\u306E•\u5F31\u70B9\u304B\u3089•\u9003\u907F•\u3059\u308B•\u305F\u3081\u306B•\u3088\u304F•\u4F7F\u308F\u308C\u308B\u306E\u3067•\u6CE8\u610F\u304C•\u5FC5\u8981•\u3067\u3059\u304C\u3002•</data>
####################################################################################
#
diff --git a/Build/source/libs/icu/icu-src/source/test/testdata/root.txt b/Build/source/libs/icu/icu-src/source/test/testdata/root.txt
index 2d6fcb7f8f3..f3a9a151ee4 100644
--- a/Build/source/libs/icu/icu-src/source/test/testdata/root.txt
+++ b/Build/source/libs/icu/icu-src/source/test/testdata/root.txt
@@ -13,8 +13,8 @@
root
{
Version { 44.0 }
- ExpectCLDRVersionAtLeast { 40.0 } // 'base' cldr version. Allow up to version =.=.* of this
- CurrentCLDRVersion { 40.0 } // Current CLDR version as of the test update. Warn if not an exact match.
+ ExpectCLDRVersionAtLeast { 41.0 } // 'base' cldr version. Allow up to version =.=.* of this
+ CurrentCLDRVersion { 41.0 } // Current CLDR version as of the test update. Warn if not an exact match.
ShortLanguage { xxx }
diff --git a/Build/source/libs/icu/icu-src/source/tools/ctestfw/ctestfw.vcxproj b/Build/source/libs/icu/icu-src/source/tools/ctestfw/ctestfw.vcxproj
index 1dd8e2602c5..a4bd954bf56 100644
--- a/Build/source/libs/icu/icu-src/source/tools/ctestfw/ctestfw.vcxproj
+++ b/Build/source/libs/icu/icu-src/source/tools/ctestfw/ctestfw.vcxproj
@@ -53,7 +53,7 @@
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Link>
- <OutputFile>..\..\..\$(IcuBinOutputDir)\icutest70d.exe</OutputFile>
+ <OutputFile>..\..\..\$(IcuBinOutputDir)\icutest71d.exe</OutputFile>
<ProgramDatabaseFile>.\..\..\..\$(IcuLibOutputDir)\icutestd.pdb</ProgramDatabaseFile>
<ImportLibrary>.\..\..\..\$(IcuLibOutputDir)\icutestd.lib</ImportLibrary>
<AdditionalDependencies>icuucd.lib;icutud.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -66,7 +66,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
</ClCompile>
<Link>
- <OutputFile>..\..\..\$(IcuBinOutputDir)\icutest70.exe</OutputFile>
+ <OutputFile>..\..\..\$(IcuBinOutputDir)\icutest71.exe</OutputFile>
<ProgramDatabaseFile>.\..\..\..\$(IcuLibOutputDir)\icutest.pdb</ProgramDatabaseFile>
<ImportLibrary>.\..\..\..\$(IcuLibOutputDir)\icutest.lib</ImportLibrary>
<AdditionalDependencies>icuuc.lib;icutu.lib;%(AdditionalDependencies)</AdditionalDependencies>
diff --git a/Build/source/libs/icu/icu-src/source/tools/ctestfw/uperf.cpp b/Build/source/libs/icu/icu-src/source/tools/ctestfw/uperf.cpp
index 5605f0d2e3d..67b9fe50aae 100644
--- a/Build/source/libs/icu/icu-src/source/tools/ctestfw/uperf.cpp
+++ b/Build/source/libs/icu/icu-src/source/tools/ctestfw/uperf.cpp
@@ -390,7 +390,7 @@ UBool UPerfTest::runTestLoop( char* testname, char* par )
loops = failsafe;
failsafe *= 10;
} else {
- //System.out.println("# " + meth.getName() + " x " + loops + " = " + t);
+ //System.out.println("# " + meth.getName() + " x " + loops + " = " + t);
loops = (int)((double)n / t * loops + 0.5);
if (loops == 0) {
fprintf(stderr,"Unable to converge on desired duration");
@@ -412,15 +412,13 @@ UBool UPerfTest::runTestLoop( char* testname, char* par )
long events = -1;
for(int32_t ps =0; ps < passes; ps++){
- fprintf(stdout,"= %s begin " ,name);
if(verbose==TRUE){
+ fprintf(stdout,"= %s begin " ,name);
if(iterations > 0) {
fprintf(stdout, "%i\n", (int)loops);
} else {
fprintf(stdout, "%i\n", (int)n);
}
- } else {
- fprintf(stdout, "\n");
}
t = testFunction->time(loops, &status);
if(U_FAILURE(status)){
@@ -439,12 +437,6 @@ UBool UPerfTest::runTestLoop( char* testname, char* par )
}else{
fprintf(stdout, "= %s end: %f loops: %i operations: %li events: %li\n", name, t, (int)loops, ops, events);
}
- }else{
- if(events == -1){
- fprintf(stdout,"= %s end %f %i %li\n", name, t, (int)loops, ops);
- }else{
- fprintf(stdout,"= %s end %f %i %li %li\n", name, t, (int)loops, ops, events);
- }
}
}
if(verbose && U_SUCCESS(status)) {
@@ -465,6 +457,12 @@ UBool UPerfTest::runTestLoop( char* testname, char* par )
name, min_t, (int)loops, (min_t*1E9)/(loops*ops), (min_t*1E9)/(loops*events));
}
}
+ else if(U_SUCCESS(status)) {
+ // Print results in ndjson format for GHA Benchmark to process.
+ fprintf(stdout,
+ "{\"biggerIsBetter\":false,\"name\":\"%s\",\"unit\":\"ns/iter\",\"value\":%.4f}\n",
+ name, (min_t*1E9)/(loops*ops));
+ }
delete testFunction;
}
index++;
diff --git a/Build/source/libs/icu/icu-src/source/tools/gennorm2/BUILD b/Build/source/libs/icu/icu-src/source/tools/gennorm2/BUILD.bazel
index c602897bafc..c602897bafc 100644
--- a/Build/source/libs/icu/icu-src/source/tools/gennorm2/BUILD
+++ b/Build/source/libs/icu/icu-src/source/tools/gennorm2/BUILD.bazel
diff --git a/Build/source/libs/icu/icu-src/source/tools/icuexportdata/icuexportdata.cpp b/Build/source/libs/icu/icu-src/source/tools/icuexportdata/icuexportdata.cpp
index ef933676115..7431ac74ab8 100644
--- a/Build/source/libs/icu/icu-src/source/tools/icuexportdata/icuexportdata.cpp
+++ b/Build/source/libs/icu/icu-src/source/tools/icuexportdata/icuexportdata.cpp
@@ -3,6 +3,7 @@
#include <iostream>
#include <vector>
+#include <algorithm>
#include "toolutil.h"
#include "uoptions.h"
#include "cmemory.h"
@@ -11,8 +12,10 @@
#include "unicode/uchar.h"
#include "unicode/errorcode.h"
#include "unicode/uniset.h"
+#include "unicode/uscript.h"
#include "unicode/putil.h"
#include "unicode/umutablecptrie.h"
+#include "ucase.h"
#include "writesrc.h"
U_NAMESPACE_USE
@@ -27,6 +30,75 @@ UBool haveCopyright = TRUE;
UCPTrieType trieType = UCPTRIE_TYPE_SMALL;
const char* destdir = "";
+// Mask constants for modified values in the Script CodePointTrie, values are logically 12-bits.
+int16_t DATAEXPORT_SCRIPT_X_WITH_COMMON = 0x0400;
+int16_t DATAEXPORT_SCRIPT_X_WITH_INHERITED = 0x0800;
+int16_t DATAEXPORT_SCRIPT_X_WITH_OTHER = 0x0c00;
+
+// TODO(ICU-21821): Replace this with a call to a library function
+int32_t scxCodePoints[] = {
+ 7415, 7377, 7380, 7387, 7390, 7391, 7394, 7395, 7396, 7397,
+ 7398, 7399, 7400, 7403, 7404, 7406, 7407, 7408, 7409, 113824,
+ 113825, 113826, 113827, 834, 837, 7616, 7617, 12294, 12350, 12351,
+ 12688, 12689, 12690, 12691, 12692, 12693, 12694, 12695, 12696, 12697,
+ 12698, 12699, 12700, 12701, 12702, 12703, 12736, 12737, 12738, 12739,
+ 12740, 12741, 12742, 12743, 12744, 12745, 12746, 12747, 12748, 12749,
+ 12750, 12751, 12752, 12753, 12754, 12755, 12756, 12757, 12758, 12759,
+ 12760, 12761, 12762, 12763, 12764, 12765, 12766, 12767, 12768, 12769,
+ 12770, 12771, 12832, 12833, 12834, 12835, 12836, 12837, 12838, 12839,
+ 12840, 12841, 12842, 12843, 12844, 12845, 12846, 12847, 12848, 12849,
+ 12850, 12851, 12852, 12853, 12854, 12855, 12856, 12857, 12858, 12859,
+ 12860, 12861, 12862, 12863, 12864, 12865, 12866, 12867, 12868, 12869,
+ 12870, 12871, 12928, 12929, 12930, 12931, 12932, 12933, 12934, 12935,
+ 12936, 12937, 12938, 12939, 12940, 12941, 12942, 12943, 12944, 12945,
+ 12946, 12947, 12948, 12949, 12950, 12951, 12952, 12953, 12954, 12955,
+ 12956, 12957, 12958, 12959, 12960, 12961, 12962, 12963, 12964, 12965,
+ 12966, 12967, 12968, 12969, 12970, 12971, 12972, 12973, 12974, 12975,
+ 12976, 12992, 12993, 12994, 12995, 12996, 12997, 12998, 12999, 13000,
+ 13001, 13002, 13003, 13055, 13144, 13145, 13146, 13147, 13148, 13149,
+ 13150, 13151, 13152, 13153, 13154, 13155, 13156, 13157, 13158, 13159,
+ 13160, 13161, 13162, 13163, 13164, 13165, 13166, 13167, 13168, 13179,
+ 13180, 13181, 13182, 13183, 13280, 13281, 13282, 13283, 13284, 13285,
+ 13286, 13287, 13288, 13289, 13290, 13291, 13292, 13293, 13294, 13295,
+ 13296, 13297, 13298, 13299, 13300, 13301, 13302, 13303, 13304, 13305,
+ 13306, 13307, 13308, 13309, 13310, 119648, 119649, 119650, 119651, 119652,
+ 119653, 119654, 119655, 119656, 119657, 119658, 119659, 119660, 119661, 119662,
+ 119663, 119664, 119665, 127568, 127569, 867, 868, 869, 870, 871,
+ 872, 873, 874, 875, 876, 877, 878, 879, 7418, 7674,
+ 66272, 66273, 66274, 66275, 66276, 66277, 66278, 66279, 66280, 66281,
+ 66282, 66283, 66284, 66285, 66286, 66287, 66288, 66289, 66290, 66291,
+ 66292, 66293, 66294, 66295, 66296, 66297, 66298, 66299, 1748, 64830,
+ 64831, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619,
+ 1620, 1621, 1648, 65010, 65021, 7381, 7382, 7384, 7393, 7402,
+ 7405, 7413, 7414, 43249, 12330, 12331, 12332, 12333, 43471, 65794,
+ 65847, 65848, 65849, 65850, 65851, 65852, 65853, 65854, 65855, 1156,
+ 1159, 11843, 42607, 1157, 1158, 1155, 7672, 7379, 7411, 7416,
+ 7417, 7401, 7383, 7385, 7388, 7389, 7392, 43251, 4347, 3046,
+ 3047, 3048, 3049, 3050, 3051, 3052, 3053, 3054, 3055, 3056,
+ 3057, 3058, 3059, 70401, 70403, 70459, 70460, 73680, 73681, 73683,
+ 2790, 2791, 2792, 2793, 2794, 2795, 2796, 2797, 2798, 2799,
+ 2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671,
+ 42752, 42753, 42754, 42755, 42756, 42757, 42758, 42759, 12337, 12338,
+ 12339, 12340, 12341, 12441, 12442, 12443, 12444, 12448, 12540, 65392,
+ 65438, 65439, 3302, 3303, 3304, 3305, 3306, 3307, 3308, 3309,
+ 3310, 3311, 8239, 68338, 6146, 6147, 6149, 1564, 1632, 1633,
+ 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 2534, 2535,
+ 2536, 2537, 2538, 2539, 2540, 2541, 2542, 2543, 4160, 4161,
+ 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 65792, 65793,
+ 65799, 65800, 65801, 65802, 65803, 65804, 65805, 65806, 65807, 65808,
+ 65809, 65810, 65811, 65812, 65813, 65814, 65815, 65816, 65817, 65818,
+ 65819, 65820, 65821, 65822, 65823, 65824, 65825, 65826, 65827, 65828,
+ 65829, 65830, 65831, 65832, 65833, 65834, 65835, 65836, 65837, 65838,
+ 65839, 65840, 65841, 65842, 65843, 7412, 8432, 12348, 12349, 43310,
+ 7376, 7378, 5941, 5942, 2406, 2407, 2408, 2409, 2410, 2411,
+ 2412, 2413, 2414, 2415, 12291, 12307, 12316, 12317, 12318, 12319,
+ 12336, 12343, 65093, 65094, 1548, 1563, 12289, 12290, 12296, 12297,
+ 12298, 12299, 12300, 12301, 12302, 12303, 12304, 12305, 12308, 12309,
+ 12310, 12311, 12312, 12313, 12314, 12315, 12539, 65377, 65378, 65379,
+ 65380, 65381, 7386, 1567, 7410, 1600, 43062, 43063, 43064, 43065,
+ 2386, 2385, 43059, 43060, 43061, 43056, 43057, 43058, 2404, 2405
+ };
+
void handleError(ErrorCode& status, const char* context) {
if (status.isFailure()) {
std::cerr << "Error: " << context << ": " << status.errorName() << std::endl;
@@ -96,6 +168,110 @@ void dumpEnumeratedProperty(UProperty uproperty, FILE* f) {
usrc_writeUCPTrie(f, shortPropName, utrie.getAlias(), UPRV_TARGET_SYNTAX_TOML);
}
+void dumpScriptExtensions(FILE* f) {
+ IcuToolErrorCode status("icuexportdata: dumpScriptExtensions");
+
+ fputs("[[script_extensions]]\n", f);
+ const char* scxFullPropName = u_getPropertyName(UCHAR_SCRIPT_EXTENSIONS, U_LONG_PROPERTY_NAME);
+ const char* scxShortPropName = u_getPropertyName(UCHAR_SCRIPT_EXTENSIONS, U_SHORT_PROPERTY_NAME);
+ fprintf(f, "long_name = \"%s\"\n", scxFullPropName);
+ if (scxShortPropName) fprintf(f, "short_name = \"%s\"\n", scxShortPropName);
+
+ // We want to use 16 bits for our exported trie of sc/scx data because we
+ // need 12 bits to match the 12 bits of data stored for sc/scx in the trie
+ // in the uprops.icu data file.
+ UCPTrieValueWidth scWidth = UCPTRIE_VALUE_BITS_16;
+
+ // Create a mutable UCPTrie builder populated with Script property values data.
+ const UCPMap* scInvMap = u_getIntPropertyMap(UCHAR_SCRIPT, status);
+ handleError(status, scxFullPropName);
+ LocalUMutableCPTriePointer builder(umutablecptrie_fromUCPMap(scInvMap, status));
+ handleError(status, scxFullPropName);
+
+ // The values for the output scx companion array.
+ // Invariant is that all subvectors are distinct.
+ std::vector< std::vector<uint16_t> > outputDedupVec;
+
+ // The sc/scx companion array is an array of arrays (of script codes)
+ fputs("script_code_array = [\n", f);
+ for(const UChar32 cp : scxCodePoints) {
+ // Get the Script value
+ uint32_t scVal = umutablecptrie_get(builder.getAlias(), cp);
+ // Get the Script_Extensions value (array of Script codes)
+ const int32_t SCX_ARRAY_CAPACITY = 32;
+ UScriptCode scxValArray[SCX_ARRAY_CAPACITY];
+ int32_t numScripts = uscript_getScriptExtensions(cp, scxValArray, SCX_ARRAY_CAPACITY, status);
+ handleError(status, scxFullPropName);
+
+ // Convert the scx array into a vector
+ std::vector<uint16_t> scxValVec;
+ for(int i = 0; i < numScripts; i++) {
+ scxValVec.push_back(scxValArray[i]);
+ }
+ // Ensure that it is sorted
+ std::sort(scxValVec.begin(), scxValVec.end());
+ // Copy the Script value into the first position of the scx array only
+ // if we have the "other" case (Script value is not Common nor Inherited).
+ // This offers faster access when users want only the Script value.
+ if (scVal != USCRIPT_COMMON && scVal != USCRIPT_INHERITED) {
+ scxValVec.insert(scxValVec.begin(), scVal);
+ }
+
+ // See if there is already an scx value array matching the newly built one.
+ // If there is, then use its index.
+ // If not, then append the new value array.
+ bool isScxValUnique = true;
+ size_t outputIndex = 0;
+ for (outputIndex = 0; outputIndex < outputDedupVec.size(); outputIndex++) {
+ if (outputDedupVec[outputIndex] == scxValVec) {
+ isScxValUnique = false;
+ break;
+ }
+ }
+
+ if (isScxValUnique) {
+ outputDedupVec.push_back(scxValVec);
+ usrc_writeArray(f, " [", scxValVec.data(), 16, scxValVec.size(), " ", "],\n");
+ }
+
+ // We must update the value in the UCPTrie for the code point to contain:
+ // 9..0 the Script code in the lower 10 bits when 11..10 is 0, else it is
+ // the index into the companion array
+ // 11..10 the same higher-order 2 bits in the trie in uprops.icu indicating whether
+ // 3: other
+ // 2: Script=Inherited
+ // 1: Script=Common
+ // 0: Script=value in 9..0 (N/A because we are in this loop to create the companion array for non-0 cases)
+ uint16_t mask = 0;
+ if (scVal == USCRIPT_COMMON) {
+ mask = DATAEXPORT_SCRIPT_X_WITH_COMMON;
+ } else if (scVal == USCRIPT_INHERITED) {
+ mask = DATAEXPORT_SCRIPT_X_WITH_INHERITED;
+ } else {
+ mask = DATAEXPORT_SCRIPT_X_WITH_OTHER;
+ }
+
+ // The new trie value is the index into the new array with the high order bits set
+ uint32_t newScVal = outputIndex | mask;
+
+ // Update the code point in the mutable trie builder with the trie value
+ umutablecptrie_set(builder.getAlias(), cp, newScVal, status);
+ handleError(status, scxFullPropName);
+ }
+ fputs("]\n\n", f); // Print the TOML close delimiter for the outer array.
+
+ // Convert from mutable trie builder to immutable trie.
+ LocalUCPTriePointer utrie(umutablecptrie_buildImmutable(
+ builder.getAlias(),
+ trieType,
+ scWidth,
+ status));
+ handleError(status, scxFullPropName);
+
+ fputs("[script_extensions.code_point_trie]\n", f);
+ usrc_writeUCPTrie(f, scxShortPropName, utrie.getAlias(), UPRV_TARGET_SYNTAX_TOML);
+}
+
FILE* prepareOutputFile(const char* basename) {
IcuToolErrorCode status("icuexportdata");
CharString outFileName;
@@ -158,45 +334,42 @@ static UOption options[]={
UOPTION_QUIET,
};
-int main(int argc, char* argv[]) {
- U_MAIN_INIT_ARGS(argc, argv);
-
- /* preset then read command line options */
- options[OPT_DESTDIR].value=u_getDataDirectory();
- argc=u_parseArgs(argc, argv, UPRV_LENGTHOF(options), options);
-
- if(options[OPT_VERSION].doesOccur) {
- printf("icuexportdata version %s, ICU tool to dump data files for external consumers\n",
- U_ICU_DATA_VERSION);
- printf("%s\n", U_COPYRIGHT_STRING);
- exit(0);
- }
-
- /* error handling, printing usage message */
- if(argc<0) {
- fprintf(stderr,
- "error in command line argument \"%s\"\n",
- argv[-argc]);
- } else if(argc<2) {
- argc=-1;
- }
-
- /* get the options values */
- haveCopyright = options[OPT_COPYRIGHT].doesOccur;
- destdir = options[OPT_DESTDIR].value;
- VERBOSE = options[OPT_VERBOSE].doesOccur;
- QUIET = options[OPT_QUIET].doesOccur;
+void printHelp(FILE* stdfile, const char* program) {
+ fprintf(stdfile,
+ "usage: %s -m mode [-options] [--all | properties...]\n"
+ "\tdump Unicode property data to .toml files\n"
+ "options:\n"
+ "\t-h or -? or --help this usage text\n"
+ "\t-V or --version show a version message\n"
+ "\t-m or --mode mode: currently only 'uprops' and 'ucase', but more may be added\n"
+ "\t --trie-type set the trie type (small or fast, default small)\n"
+ "\t-d or --destdir destination directory, followed by the path\n"
+ "\t --all write out all properties known to icuexportdata\n"
+ "\t --index write an _index.toml summarizing all data exported\n"
+ "\t-c or --copyright include a copyright notice\n"
+ "\t-v or --verbose Turn on verbose output\n"
+ "\t-q or --quiet do not display warnings and progress\n",
+ program);
+}
+int exportUprops(int argc, char* argv[]) {
// Load list of Unicode properties
std::vector<const char*> propNames;
for (int i=1; i<argc; i++) {
propNames.push_back(argv[i]);
}
if (options[OPT_ALL].doesOccur) {
- for (int i=UCHAR_BINARY_START; i<UCHAR_INT_LIMIT; i++) {
+ int i = UCHAR_BINARY_START;
+ while (true) {
if (i == UCHAR_BINARY_LIMIT) {
i = UCHAR_INT_START;
}
+ if (i == UCHAR_INT_LIMIT) {
+ i = UCHAR_SCRIPT_EXTENSIONS;
+ }
+ if (i == UCHAR_SCRIPT_EXTENSIONS + 1) {
+ break;
+ }
UProperty uprop = static_cast<UProperty>(i);
const char* propName = u_getPropertyName(uprop, U_SHORT_PROPERTY_NAME);
if (propName == NULL) {
@@ -207,47 +380,10 @@ int main(int argc, char* argv[]) {
}
if (propName != NULL) {
propNames.push_back(propName);
+ } else {
+ std::cerr << "Warning: Could not find name for: " << uprop << std::endl;
}
- }
- }
-
- if (propNames.empty()
- || options[OPT_HELP_H].doesOccur
- || options[OPT_HELP_QUESTION_MARK].doesOccur
- || !options[OPT_MODE].doesOccur) {
- FILE *stdfile=argc<0 ? stderr : stdout;
- fprintf(stdfile,
- "usage: %s -m uprops [-options] [--all | properties...]\n"
- "\tdump Unicode property data to .toml files\n"
- "options:\n"
- "\t-h or -? or --help this usage text\n"
- "\t-V or --version show a version message\n"
- "\t-m or --mode mode: currently only 'uprops', but more may be added\n"
- "\t --trie-type set the trie type (small or fast, default small)\n"
- "\t-d or --destdir destination directory, followed by the path\n"
- "\t --all write out all properties known to icuexportdata\n"
- "\t --index write an _index.toml summarizing all data exported\n"
- "\t-c or --copyright include a copyright notice\n"
- "\t-v or --verbose Turn on verbose output\n"
- "\t-q or --quiet do not display warnings and progress\n",
- argv[0]);
- return argc<0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
- }
-
- const char* mode = options[OPT_MODE].value;
- if (uprv_strcmp(mode, "uprops") != 0) {
- fprintf(stderr, "Invalid option for --mode (must be uprops)\n");
- return U_ILLEGAL_ARGUMENT_ERROR;
- }
-
- if (options[OPT_TRIE_TYPE].doesOccur) {
- if (uprv_strcmp(options[OPT_TRIE_TYPE].value, "fast") == 0) {
- trieType = UCPTRIE_TYPE_FAST;
- } else if (uprv_strcmp(options[OPT_TRIE_TYPE].value, "small") == 0) {
- trieType = UCPTRIE_TYPE_SMALL;
- } else {
- fprintf(stderr, "Invalid option for --trie-type (must be small or fast)\n");
- return U_ILLEGAL_ARGUMENT_ERROR;
+ i++;
}
}
@@ -272,6 +408,8 @@ int main(int argc, char* argv[]) {
dumpBinaryProperty(propEnum, f);
} else if (UCHAR_INT_START <= propEnum && propEnum <= UCHAR_INT_LIMIT) {
dumpEnumeratedProperty(propEnum, f);
+ } else if (propEnum == UCHAR_SCRIPT_EXTENSIONS) {
+ dumpScriptExtensions(f);
} else {
std::cerr << "Don't know how to write property: " << propEnum << std::endl;
return U_INTERNAL_PROGRAM_ERROR;
@@ -293,3 +431,134 @@ int main(int argc, char* argv[]) {
return 0;
}
+
+struct AddRangeHelper {
+ UMutableCPTrie* ucptrie;
+};
+
+static UBool U_CALLCONV
+addRangeToUCPTrie(const void* context, UChar32 start, UChar32 end, uint32_t value) {
+ IcuToolErrorCode status("addRangeToUCPTrie");
+ UMutableCPTrie* ucptrie = ((const AddRangeHelper*) context)->ucptrie;
+ umutablecptrie_setRange(ucptrie, start, end, value, status);
+ handleError(status, "setRange");
+
+ return TRUE;
+}
+
+int exportCase(int argc, char* argv[]) {
+ if (argc > 1) {
+ fprintf(stderr, "ucase mode does not expect additional arguments\n");
+ return U_ILLEGAL_ARGUMENT_ERROR;
+ }
+ (void) argv; // Suppress unused variable warning
+
+ IcuToolErrorCode status("icuexportdata");
+ LocalUMutableCPTriePointer builder(umutablecptrie_open(0, 0, status));
+ handleError(status, "exportCase");
+
+ int32_t exceptionsLength, unfoldLength;
+ const UCaseProps *caseProps = ucase_getSingleton(&exceptionsLength, &unfoldLength);
+ const UTrie2* caseTrie = &caseProps->trie;
+
+ AddRangeHelper helper = { builder.getAlias() };
+ utrie2_enum(caseTrie, NULL, addRangeToUCPTrie, &helper);
+
+ UCPTrieValueWidth width = UCPTRIE_VALUE_BITS_16;
+ LocalUCPTriePointer utrie(umutablecptrie_buildImmutable(
+ builder.getAlias(),
+ trieType,
+ width,
+ status));
+ handleError(status, "exportCase");
+
+ FILE* f = prepareOutputFile("ucase");
+
+ UVersionInfo versionInfo;
+ u_getUnicodeVersion(versionInfo);
+ char uvbuf[U_MAX_VERSION_STRING_LENGTH];
+ u_versionToString(versionInfo, uvbuf);
+ fprintf(f, "icu_version = \"%s\"\nunicode_version = \"%s\"\n\n",
+ U_ICU_VERSION,
+ uvbuf);
+
+ fputs("[ucase.code_point_trie]\n", f);
+ usrc_writeUCPTrie(f, "case_trie", utrie.getAlias(), UPRV_TARGET_SYNTAX_TOML);
+ fputs("\n", f);
+
+ const char* indent = " ";
+ const char* suffix = "\n]\n";
+
+ fputs("[ucase.exceptions]\n", f);
+ const char* exceptionsPrefix = "exceptions = [\n ";
+ int32_t exceptionsWidth = 16;
+ usrc_writeArray(f, exceptionsPrefix, caseProps->exceptions, exceptionsWidth,
+ exceptionsLength, indent, suffix);
+ fputs("\n", f);
+
+ fputs("[ucase.unfold]\n", f);
+ const char* unfoldPrefix = "unfold = [\n ";
+ int32_t unfoldWidth = 16;
+ usrc_writeArray(f, unfoldPrefix, caseProps->unfold, unfoldWidth,
+ unfoldLength, indent, suffix);
+
+ return 0;
+}
+
+int main(int argc, char* argv[]) {
+ U_MAIN_INIT_ARGS(argc, argv);
+
+ /* preset then read command line options */
+ options[OPT_DESTDIR].value=u_getDataDirectory();
+ argc=u_parseArgs(argc, argv, UPRV_LENGTHOF(options), options);
+
+ if(options[OPT_VERSION].doesOccur) {
+ printf("icuexportdata version %s, ICU tool to dump data files for external consumers\n",
+ U_ICU_DATA_VERSION);
+ printf("%s\n", U_COPYRIGHT_STRING);
+ exit(0);
+ }
+
+ /* error handling, printing usage message */
+ if(argc<0) {
+ fprintf(stderr,
+ "error in command line argument \"%s\"\n",
+ argv[-argc]);
+ }
+
+ if (argc < 0
+ || options[OPT_HELP_H].doesOccur
+ || options[OPT_HELP_QUESTION_MARK].doesOccur
+ || !options[OPT_MODE].doesOccur) {
+ FILE *stdfile=argc<0 ? stderr : stdout;
+ printHelp(stdfile, argv[0]);
+ return argc<0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
+ }
+
+ /* get the options values */
+ haveCopyright = options[OPT_COPYRIGHT].doesOccur;
+ destdir = options[OPT_DESTDIR].value;
+ VERBOSE = options[OPT_VERBOSE].doesOccur;
+ QUIET = options[OPT_QUIET].doesOccur;
+
+ if (options[OPT_TRIE_TYPE].doesOccur) {
+ if (uprv_strcmp(options[OPT_TRIE_TYPE].value, "fast") == 0) {
+ trieType = UCPTRIE_TYPE_FAST;
+ } else if (uprv_strcmp(options[OPT_TRIE_TYPE].value, "small") == 0) {
+ trieType = UCPTRIE_TYPE_SMALL;
+ } else {
+ fprintf(stderr, "Invalid option for --trie-type (must be small or fast)\n");
+ return U_ILLEGAL_ARGUMENT_ERROR;
+ }
+ }
+
+ const char* mode = options[OPT_MODE].value;
+ if (uprv_strcmp(mode, "uprops") == 0) {
+ return exportUprops(argc, argv);
+ } else if (uprv_strcmp(mode, "ucase") == 0) {
+ return exportCase(argc, argv);
+ }
+
+ fprintf(stderr, "Invalid option for --mode (must be uprops or ucase)\n");
+ return U_ILLEGAL_ARGUMENT_ERROR;
+}
diff --git a/Build/source/libs/icu/icu-src/source/tools/toolutil/BUILD b/Build/source/libs/icu/icu-src/source/tools/toolutil/BUILD.bazel
index 276c857f124..276c857f124 100644
--- a/Build/source/libs/icu/icu-src/source/tools/toolutil/BUILD
+++ b/Build/source/libs/icu/icu-src/source/tools/toolutil/BUILD.bazel
diff --git a/Build/source/libs/icu/icu-src/source/tools/toolutil/toolutil.cpp b/Build/source/libs/icu/icu-src/source/tools/toolutil/toolutil.cpp
index 1fc68aa69c8..a9dc37377a8 100644
--- a/Build/source/libs/icu/icu-src/source/tools/toolutil/toolutil.cpp
+++ b/Build/source/libs/icu/icu-src/source/tools/toolutil/toolutil.cpp
@@ -228,18 +228,19 @@ uprv_compareGoldenFiles(
std::ifstream ifs(goldenFilePath, std::ifstream::in);
int32_t pos = 0;
char c;
- while ((c = ifs.get()) != std::char_traits<char>::eof() && pos < bufferLen) {
+ while (ifs.get(c) && pos < bufferLen) {
if (c != buffer[pos]) {
// Files differ at this position
- return pos;
+ break;
}
pos++;
}
- if (pos < bufferLen || c != std::char_traits<char>::eof()) {
- // Files are different lengths
- return pos;
+ if (pos == bufferLen && ifs.eof()) {
+ // Files are same lengths
+ pos = -1;
}
- return -1;
+ ifs.close();
+ return pos;
}
/*U_CAPI UDate U_EXPORT2
diff --git a/Build/source/libs/icu/icu-src/source/tools/toolutil/toolutil.vcxproj b/Build/source/libs/icu/icu-src/source/tools/toolutil/toolutil.vcxproj
index b74ac41cb0e..c7088baf676 100644
--- a/Build/source/libs/icu/icu-src/source/tools/toolutil/toolutil.vcxproj
+++ b/Build/source/libs/icu/icu-src/source/tools/toolutil/toolutil.vcxproj
@@ -74,7 +74,7 @@
<TypeLibraryName>.\..\..\..\lib\icutu.tlb</TypeLibraryName>
</Midl>
<Link>
- <OutputFile>..\..\..\bin\icutu70.dll</OutputFile>
+ <OutputFile>..\..\..\bin\icutu71.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\..\lib\icutu.pdb</ProgramDatabaseFile>
<DataExecutionPrevention>
</DataExecutionPrevention>
@@ -86,7 +86,7 @@
<TypeLibraryName>.\..\..\..\lib\icutud.tlb</TypeLibraryName>
</Midl>
<Link>
- <OutputFile>..\..\..\bin\icutu70d.dll</OutputFile>
+ <OutputFile>..\..\..\bin\icutu71d.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\..\lib\icutud.pdb</ProgramDatabaseFile>
<DataExecutionPrevention>
</DataExecutionPrevention>
@@ -113,7 +113,7 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
- <OutputFile>..\..\..\bin64\icutu70.dll</OutputFile>
+ <OutputFile>..\..\..\bin64\icutu71.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\..\lib64\icutu.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\..\lib64\icutu.lib</ImportLibrary>
</Link>
@@ -123,7 +123,7 @@
<TypeLibraryName>.\..\..\..\lib64\icutud.tlb</TypeLibraryName>
</Midl>
<Link>
- <OutputFile>..\..\..\bin64\icutu70d.dll</OutputFile>
+ <OutputFile>..\..\..\bin64\icutu71d.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\..\lib64\icutud.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\..\lib64\icutud.lib</ImportLibrary>
</Link>
@@ -144,7 +144,7 @@
<TypeLibraryName>..\..\..\libARM\icutu.tlb</TypeLibraryName>
</Midl>
<Link>
- <OutputFile>..\..\..\binARM\icutu70.dll</OutputFile>
+ <OutputFile>..\..\..\binARM\icutu71.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\..\libARM\icutu.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\..\libARM\icutu.lib</ImportLibrary>
</Link>
@@ -157,7 +157,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
- <OutputFile>..\..\..\binARM\icutu70d.dll</OutputFile>
+ <OutputFile>..\..\..\binARM\icutu71d.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\..\libARM\icutud.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\..\libARM\icutud.lib</ImportLibrary>
</Link>
@@ -178,7 +178,7 @@
<TypeLibraryName>.\..\..\..\libARM64\icutu.tlb</TypeLibraryName>
</Midl>
<Link>
- <OutputFile>..\..\..\binARM64\icutu70.dll</OutputFile>
+ <OutputFile>..\..\..\binARM64\icutu71.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\..\libARM64\icutu.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\..\libARM64\icutu.lib</ImportLibrary>
</Link>
@@ -191,7 +191,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
- <OutputFile>..\..\..\binARM64\icutu70d.dll</OutputFile>
+ <OutputFile>..\..\..\binARM64\icutu71d.dll</OutputFile>
<ProgramDatabaseFile>.\..\..\..\libARM64\icutud.pdb</ProgramDatabaseFile>
<ImportLibrary>..\..\..\libARM64\icutud.lib</ImportLibrary>
</Link>
diff --git a/Build/source/libs/icu/icu-src/source/tools/tzcode/icuregions b/Build/source/libs/icu/icu-src/source/tools/tzcode/icuregions
index 851f3242d19..c3c138a1228 100644
--- a/Build/source/libs/icu/icu-src/source/tools/tzcode/icuregions
+++ b/Build/source/libs/icu/icu-src/source/tools/tzcode/icuregions
@@ -12,6 +12,7 @@
Africa/Asmera ER
America/Coral_Harbour CA
America/Montreal CA
+America/Virgin VI
Europe/Simferopol UA
Pacific/Johnston UM