summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Wang <git@albertyw.com>2019-11-02 18:08:46 -0700
committerRichard Lau <riclau@uk.ibm.com>2019-12-05 20:39:20 -0500
commit418dd68b611cce7e916dae82c75cb3d63b3c43a6 (patch)
tree0ed206d2abae637584d4f5690a17b4ab4dd46d39
parent6c40cb2aca89df4c7c0e3923d93024734dd49f2d (diff)
downloadandroid-node-v8-418dd68b611cce7e916dae82c75cb3d63b3c43a6.tar.gz
android-node-v8-418dd68b611cce7e916dae82c75cb3d63b3c43a6.tar.bz2
android-node-v8-418dd68b611cce7e916dae82c75cb3d63b3c43a6.zip
tools: update icu to 65.1
Update the version of the bundled ICU (deps/icu-small) to ICU version 65.2. Fixes: https://github.com/nodejs/node/issues/30211 Fixes: https://github.com/nodejs/node/issues/29540 PR-URL: https://github.com/nodejs/node/pull/30232 Reviewed-By: Steven R Loomis <srloomis@us.ibm.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
-rw-r--r--deps/icu-small/README-FULL-ICU.txt4
-rw-r--r--deps/icu-small/source/common/brkeng.cpp2
-rw-r--r--deps/icu-small/source/common/brkiter.cpp2
-rw-r--r--deps/icu-small/source/common/bytesinkutil.h2
-rw-r--r--deps/icu-small/source/common/characterproperties.cpp13
-rw-r--r--deps/icu-small/source/common/charstr.cpp23
-rw-r--r--deps/icu-small/source/common/charstr.h14
-rw-r--r--deps/icu-small/source/common/cmemory.h45
-rw-r--r--deps/icu-small/source/common/edits.cpp2
-rw-r--r--deps/icu-small/source/common/filteredbrk.cpp2
-rw-r--r--deps/icu-small/source/common/localebuilder.cpp60
-rw-r--r--deps/icu-small/source/common/localematcher.cpp720
-rw-r--r--deps/icu-small/source/common/localeprioritylist.cpp239
-rw-r--r--deps/icu-small/source/common/localeprioritylist.h115
-rw-r--r--deps/icu-small/source/common/locavailable.cpp206
-rw-r--r--deps/icu-small/source/common/locbased.h2
-rw-r--r--deps/icu-small/source/common/locdistance.cpp364
-rw-r--r--deps/icu-small/source/common/locdistance.h109
-rw-r--r--deps/icu-small/source/common/locdspnm.cpp100
-rw-r--r--deps/icu-small/source/common/locid.cpp25
-rw-r--r--deps/icu-small/source/common/loclikely.cpp30
-rw-r--r--deps/icu-small/source/common/loclikelysubtags.cpp638
-rw-r--r--deps/icu-small/source/common/loclikelysubtags.h143
-rw-r--r--deps/icu-small/source/common/lsr.cpp101
-rw-r--r--deps/icu-small/source/common/lsr.h72
-rw-r--r--deps/icu-small/source/common/mutex.h72
-rw-r--r--deps/icu-small/source/common/normalizer2impl.h6
-rw-r--r--deps/icu-small/source/common/putil.cpp46
-rw-r--r--deps/icu-small/source/common/putilimp.h70
-rw-r--r--deps/icu-small/source/common/rbbi.cpp12
-rw-r--r--deps/icu-small/source/common/rbbi_cache.cpp2
-rw-r--r--deps/icu-small/source/common/resbund.cpp3
-rw-r--r--deps/icu-small/source/common/resource.h24
-rw-r--r--deps/icu-small/source/common/restrace.cpp130
-rw-r--r--deps/icu-small/source/common/restrace.h147
-rw-r--r--deps/icu-small/source/common/schriter.cpp2
-rw-r--r--deps/icu-small/source/common/serv.cpp21
-rw-r--r--deps/icu-small/source/common/servls.cpp2
-rw-r--r--deps/icu-small/source/common/servnotf.cpp13
-rw-r--r--deps/icu-small/source/common/uarrsort.cpp50
-rw-r--r--deps/icu-small/source/common/ubidiimp.h82
-rw-r--r--deps/icu-small/source/common/ubiditransform.cpp10
-rw-r--r--deps/icu-small/source/common/ucase.cpp5
-rw-r--r--deps/icu-small/source/common/uchar.cpp2
-rw-r--r--deps/icu-small/source/common/uchriter.cpp2
-rw-r--r--deps/icu-small/source/common/ucln_cmn.cpp15
-rw-r--r--deps/icu-small/source/common/ucln_cmn.h5
-rw-r--r--deps/icu-small/source/common/ucnv.cpp24
-rw-r--r--deps/icu-small/source/common/ucnv2022.cpp15
-rw-r--r--deps/icu-small/source/common/ucnv_bld.cpp27
-rw-r--r--deps/icu-small/source/common/ucnv_lmb.cpp12
-rw-r--r--deps/icu-small/source/common/ucnvbocu.cpp4
-rw-r--r--deps/icu-small/source/common/ucnvhz.cpp18
-rw-r--r--deps/icu-small/source/common/ucnvisci.cpp12
-rw-r--r--deps/icu-small/source/common/ucnvsel.cpp36
-rw-r--r--deps/icu-small/source/common/ucptrie.cpp2
-rw-r--r--deps/icu-small/source/common/ucurr.cpp41
-rw-r--r--deps/icu-small/source/common/udata.cpp45
-rw-r--r--deps/icu-small/source/common/uhash.cpp15
-rw-r--r--deps/icu-small/source/common/uidna.cpp7
-rw-r--r--deps/icu-small/source/common/uinvchar.cpp15
-rw-r--r--deps/icu-small/source/common/uinvchar.h89
-rw-r--r--deps/icu-small/source/common/uloc.cpp53
-rw-r--r--deps/icu-small/source/common/uloc_tag.cpp6
-rw-r--r--deps/icu-small/source/common/umutex.cpp122
-rwxr-xr-xdeps/icu-small/source/common/umutex.h119
-rw-r--r--deps/icu-small/source/common/unames.cpp4
-rw-r--r--deps/icu-small/source/common/unicode/appendable.h5
-rw-r--r--deps/icu-small/source/common/unicode/brkiter.h10
-rw-r--r--deps/icu-small/source/common/unicode/bytestream.h5
-rw-r--r--deps/icu-small/source/common/unicode/bytestrie.h47
-rw-r--r--deps/icu-small/source/common/unicode/bytestriebuilder.h5
-rw-r--r--deps/icu-small/source/common/unicode/caniter.h4
-rw-r--r--deps/icu-small/source/common/unicode/casemap.h5
-rw-r--r--deps/icu-small/source/common/unicode/char16ptr.h7
-rw-r--r--deps/icu-small/source/common/unicode/chariter.h8
-rw-r--r--deps/icu-small/source/common/unicode/dbbi.h6
-rw-r--r--deps/icu-small/source/common/unicode/docmain.h4
-rw-r--r--deps/icu-small/source/common/unicode/dtintrv.h6
-rw-r--r--deps/icu-small/source/common/unicode/edits.h7
-rw-r--r--deps/icu-small/source/common/unicode/errorcode.h5
-rw-r--r--deps/icu-small/source/common/unicode/filteredbrk.h7
-rw-r--r--deps/icu-small/source/common/unicode/idna.h5
-rw-r--r--deps/icu-small/source/common/unicode/localebuilder.h27
-rw-r--r--deps/icu-small/source/common/unicode/localematcher.h605
-rw-r--r--deps/icu-small/source/common/unicode/locdspnm.h4
-rw-r--r--deps/icu-small/source/common/unicode/locid.h163
-rw-r--r--deps/icu-small/source/common/unicode/messagepattern.h4
-rw-r--r--deps/icu-small/source/common/unicode/normalizer2.h5
-rw-r--r--deps/icu-small/source/common/unicode/normlzr.h11
-rw-r--r--deps/icu-small/source/common/unicode/parsepos.h5
-rw-r--r--deps/icu-small/source/common/unicode/platform.h74
-rw-r--r--deps/icu-small/source/common/unicode/rbbi.h15
-rw-r--r--deps/icu-small/source/common/unicode/rep.h9
-rw-r--r--deps/icu-small/source/common/unicode/resbund.h6
-rw-r--r--deps/icu-small/source/common/unicode/schriter.h8
-rw-r--r--deps/icu-small/source/common/unicode/simpleformatter.h5
-rw-r--r--deps/icu-small/source/common/unicode/std_string.h4
-rw-r--r--deps/icu-small/source/common/unicode/strenum.h9
-rw-r--r--deps/icu-small/source/common/unicode/stringpiece.h35
-rw-r--r--deps/icu-small/source/common/unicode/stringtriebuilder.h5
-rw-r--r--deps/icu-small/source/common/unicode/symtable.h5
-rw-r--r--deps/icu-small/source/common/unicode/uchar.h23
-rw-r--r--deps/icu-small/source/common/unicode/ucharstrie.h47
-rw-r--r--deps/icu-small/source/common/unicode/ucharstriebuilder.h5
-rw-r--r--deps/icu-small/source/common/unicode/uchriter.h8
-rw-r--r--deps/icu-small/source/common/unicode/uconfig.h2
-rw-r--r--deps/icu-small/source/common/unicode/ucpmap.h19
-rw-r--r--deps/icu-small/source/common/unicode/ucptrie.h116
-rw-r--r--deps/icu-small/source/common/unicode/ucurr.h15
-rw-r--r--deps/icu-small/source/common/unicode/udata.h38
-rw-r--r--deps/icu-small/source/common/unicode/uloc.h84
-rw-r--r--deps/icu-small/source/common/unicode/umachine.h36
-rw-r--r--deps/icu-small/source/common/unicode/umutablecptrie.h27
-rw-r--r--deps/icu-small/source/common/unicode/unifilt.h14
-rw-r--r--deps/icu-small/source/common/unicode/unifunct.h5
-rw-r--r--deps/icu-small/source/common/unicode/unimatch.h3
-rw-r--r--deps/icu-small/source/common/unicode/uniset.h15
-rw-r--r--deps/icu-small/source/common/unicode/unistr.h46
-rw-r--r--deps/icu-small/source/common/unicode/unorm.h4
-rw-r--r--deps/icu-small/source/common/unicode/uobject.h12
-rw-r--r--deps/icu-small/source/common/unicode/urename.h24
-rw-r--r--deps/icu-small/source/common/unicode/usetiter.h5
-rw-r--r--deps/icu-small/source/common/unicode/utext.h14
-rw-r--r--deps/icu-small/source/common/unicode/utf16.h92
-rw-r--r--deps/icu-small/source/common/unicode/utf8.h93
-rw-r--r--deps/icu-small/source/common/unicode/utf_old.h205
-rw-r--r--deps/icu-small/source/common/unicode/utrace.h71
-rw-r--r--deps/icu-small/source/common/unicode/utypes.h28
-rw-r--r--deps/icu-small/source/common/unicode/uvernum.h12
-rw-r--r--deps/icu-small/source/common/unicode/uversion.h32
-rw-r--r--deps/icu-small/source/common/unifiedcache.cpp51
-rw-r--r--deps/icu-small/source/common/uniset.cpp6
-rw-r--r--deps/icu-small/source/common/uniset_props.cpp5
-rw-r--r--deps/icu-small/source/common/unisetspan.cpp4
-rw-r--r--deps/icu-small/source/common/unistr.cpp2
-rw-r--r--deps/icu-small/source/common/uresbund.cpp278
-rw-r--r--deps/icu-small/source/common/uresdata.cpp96
-rw-r--r--deps/icu-small/source/common/uresdata.h76
-rw-r--r--deps/icu-small/source/common/uresimp.h8
-rw-r--r--deps/icu-small/source/common/usprep.cpp30
-rw-r--r--deps/icu-small/source/common/ustr_titlecase_brkiter.cpp14
-rw-r--r--deps/icu-small/source/common/ustring.cpp10
-rw-r--r--deps/icu-small/source/common/utext.cpp4
-rw-r--r--deps/icu-small/source/common/util.cpp10
-rw-r--r--deps/icu-small/source/common/util.h15
-rw-r--r--deps/icu-small/source/common/utrace.cpp12
-rw-r--r--deps/icu-small/source/common/utracimp.h93
-rw-r--r--deps/icu-small/source/common/utrie.h19
-rw-r--r--deps/icu-small/source/common/utrie2.h16
-rw-r--r--deps/icu-small/source/data/in/icudt65l.dat.bz2 (renamed from deps/icu-small/source/data/in/icudt64l.dat.bz2)bin9780309 -> 9881112 bytes
-rw-r--r--deps/icu-small/source/i18n/alphaindex.cpp7
-rw-r--r--deps/icu-small/source/i18n/anytrans.cpp2
-rw-r--r--deps/icu-small/source/i18n/anytrans.h2
-rw-r--r--deps/icu-small/source/i18n/astro.cpp17
-rw-r--r--deps/icu-small/source/i18n/bocsu.h4
-rw-r--r--deps/icu-small/source/i18n/brktrans.cpp2
-rw-r--r--deps/icu-small/source/i18n/brktrans.h2
-rw-r--r--deps/icu-small/source/i18n/buddhcal.cpp4
-rw-r--r--deps/icu-small/source/i18n/buddhcal.h2
-rw-r--r--deps/icu-small/source/i18n/calendar.cpp7
-rw-r--r--deps/icu-small/source/i18n/casetrn.cpp2
-rw-r--r--deps/icu-small/source/i18n/casetrn.h2
-rw-r--r--deps/icu-small/source/i18n/chnsecal.cpp19
-rw-r--r--deps/icu-small/source/i18n/chnsecal.h2
-rw-r--r--deps/icu-small/source/i18n/choicfmt.cpp2
-rw-r--r--deps/icu-small/source/i18n/coll.cpp2
-rw-r--r--deps/icu-small/source/i18n/collationiterator.cpp4
-rw-r--r--deps/icu-small/source/i18n/compactdecimalformat.cpp8
-rw-r--r--deps/icu-small/source/i18n/coptccal.cpp2
-rw-r--r--deps/icu-small/source/i18n/coptccal.h2
-rw-r--r--deps/icu-small/source/i18n/cpdtrans.cpp2
-rw-r--r--deps/icu-small/source/i18n/cpdtrans.h2
-rw-r--r--deps/icu-small/source/i18n/csdetect.cpp2
-rw-r--r--deps/icu-small/source/i18n/curramt.cpp2
-rw-r--r--deps/icu-small/source/i18n/currfmt.cpp2
-rw-r--r--deps/icu-small/source/i18n/currfmt.h2
-rw-r--r--deps/icu-small/source/i18n/currunit.cpp2
-rw-r--r--deps/icu-small/source/i18n/dangical.cpp2
-rw-r--r--deps/icu-small/source/i18n/dangical.h2
-rw-r--r--deps/icu-small/source/i18n/datefmt.cpp4
-rw-r--r--deps/icu-small/source/i18n/decNumberLocal.h4
-rw-r--r--deps/icu-small/source/i18n/decimfmt.cpp369
-rw-r--r--deps/icu-small/source/i18n/double-conversion-bignum-dtoa.cpp40
-rw-r--r--deps/icu-small/source/i18n/double-conversion-bignum.cpp581
-rw-r--r--deps/icu-small/source/i18n/double-conversion-bignum.h68
-rw-r--r--deps/icu-small/source/i18n/double-conversion-cached-powers.cpp204
-rw-r--r--deps/icu-small/source/i18n/double-conversion-cached-powers.h26
-rw-r--r--deps/icu-small/source/i18n/double-conversion-diy-fp.cpp74
-rw-r--r--deps/icu-small/source/i18n/double-conversion-diy-fp.h59
-rw-r--r--deps/icu-small/source/i18n/double-conversion-double-to-string.cpp450
-rw-r--r--deps/icu-small/source/i18n/double-conversion-double-to-string.h419
-rw-r--r--deps/icu-small/source/i18n/double-conversion-fast-dtoa.cpp54
-rw-r--r--deps/icu-small/source/i18n/double-conversion-ieee.h38
-rw-r--r--deps/icu-small/source/i18n/double-conversion-string-to-double.cpp (renamed from deps/icu-small/source/i18n/double-conversion.cpp)462
-rw-r--r--deps/icu-small/source/i18n/double-conversion-string-to-double.h244
-rw-r--r--deps/icu-small/source/i18n/double-conversion-strtod.cpp146
-rw-r--r--deps/icu-small/source/i18n/double-conversion-strtod.h5
-rw-r--r--deps/icu-small/source/i18n/double-conversion-utils.h107
-rw-r--r--deps/icu-small/source/i18n/double-conversion.h557
-rw-r--r--deps/icu-small/source/i18n/dtfmtsym.cpp26
-rw-r--r--deps/icu-small/source/i18n/dtitv_impl.h2
-rw-r--r--deps/icu-small/source/i18n/dtitvfmt.cpp31
-rw-r--r--deps/icu-small/source/i18n/dtitvinf.cpp4
-rw-r--r--deps/icu-small/source/i18n/dtptngen.cpp76
-rw-r--r--deps/icu-small/source/i18n/esctrn.cpp2
-rw-r--r--deps/icu-small/source/i18n/esctrn.h2
-rw-r--r--deps/icu-small/source/i18n/ethpccal.cpp2
-rw-r--r--deps/icu-small/source/i18n/ethpccal.h2
-rw-r--r--deps/icu-small/source/i18n/fmtable.cpp2
-rw-r--r--deps/icu-small/source/i18n/formatted_string_builder.cpp (renamed from deps/icu-small/source/i18n/number_stringbuilder.cpp)230
-rw-r--r--deps/icu-small/source/i18n/formatted_string_builder.h253
-rw-r--r--deps/icu-small/source/i18n/formattedval_impl.h39
-rw-r--r--deps/icu-small/source/i18n/formattedval_sbimpl.cpp182
-rw-r--r--deps/icu-small/source/i18n/funcrepl.cpp2
-rw-r--r--deps/icu-small/source/i18n/funcrepl.h2
-rw-r--r--deps/icu-small/source/i18n/gender.cpp2
-rw-r--r--deps/icu-small/source/i18n/gregocal.cpp32
-rw-r--r--deps/icu-small/source/i18n/hebrwcal.cpp2
-rw-r--r--deps/icu-small/source/i18n/hebrwcal.h2
-rw-r--r--deps/icu-small/source/i18n/indiancal.cpp2
-rw-r--r--deps/icu-small/source/i18n/indiancal.h2
-rw-r--r--deps/icu-small/source/i18n/islamcal.cpp4
-rw-r--r--deps/icu-small/source/i18n/islamcal.h2
-rw-r--r--deps/icu-small/source/i18n/japancal.cpp2
-rw-r--r--deps/icu-small/source/i18n/japancal.h2
-rw-r--r--deps/icu-small/source/i18n/listformatter.cpp6
-rw-r--r--deps/icu-small/source/i18n/measfmt.cpp239
-rw-r--r--deps/icu-small/source/i18n/measunit.cpp576
-rw-r--r--deps/icu-small/source/i18n/measure.cpp4
-rw-r--r--deps/icu-small/source/i18n/msgfmt.cpp6
-rw-r--r--deps/icu-small/source/i18n/name2uni.cpp2
-rw-r--r--deps/icu-small/source/i18n/name2uni.h2
-rw-r--r--deps/icu-small/source/i18n/nortrans.cpp2
-rw-r--r--deps/icu-small/source/i18n/nortrans.h2
-rw-r--r--deps/icu-small/source/i18n/nounit.cpp2
-rw-r--r--deps/icu-small/source/i18n/nultrans.cpp2
-rw-r--r--deps/icu-small/source/i18n/nultrans.h2
-rw-r--r--deps/icu-small/source/i18n/number_affixutils.cpp8
-rw-r--r--deps/icu-small/source/i18n/number_affixutils.h10
-rw-r--r--deps/icu-small/source/i18n/number_asformat.cpp10
-rw-r--r--deps/icu-small/source/i18n/number_asformat.h2
-rw-r--r--deps/icu-small/source/i18n/number_compact.cpp6
-rw-r--r--deps/icu-small/source/i18n/number_currencysymbols.cpp6
-rw-r--r--deps/icu-small/source/i18n/number_decimalquantity.cpp21
-rw-r--r--deps/icu-small/source/i18n/number_decimalquantity.h11
-rw-r--r--deps/icu-small/source/i18n/number_decnum.h2
-rw-r--r--deps/icu-small/source/i18n/number_fluent.cpp4
-rw-r--r--deps/icu-small/source/i18n/number_formatimpl.cpp76
-rw-r--r--deps/icu-small/source/i18n/number_formatimpl.h24
-rw-r--r--deps/icu-small/source/i18n/number_longnames.cpp29
-rw-r--r--deps/icu-small/source/i18n/number_longnames.h9
-rw-r--r--deps/icu-small/source/i18n/number_mapper.h12
-rw-r--r--deps/icu-small/source/i18n/number_modifiers.cpp22
-rw-r--r--deps/icu-small/source/i18n/number_modifiers.h56
-rw-r--r--deps/icu-small/source/i18n/number_output.cpp13
-rw-r--r--deps/icu-small/source/i18n/number_padding.cpp6
-rw-r--r--deps/icu-small/source/i18n/number_patternmodifier.cpp38
-rw-r--r--deps/icu-small/source/i18n/number_patternmodifier.h16
-rw-r--r--deps/icu-small/source/i18n/number_patternstring.cpp7
-rw-r--r--deps/icu-small/source/i18n/number_patternstring.h2
-rw-r--r--deps/icu-small/source/i18n/number_rounding.cpp14
-rw-r--r--deps/icu-small/source/i18n/number_scientific.cpp12
-rw-r--r--deps/icu-small/source/i18n/number_scientific.h2
-rw-r--r--deps/icu-small/source/i18n/number_skeletons.cpp11
-rw-r--r--deps/icu-small/source/i18n/number_skeletons.h6
-rw-r--r--deps/icu-small/source/i18n/number_stringbuilder.h164
-rw-r--r--deps/icu-small/source/i18n/number_types.h28
-rw-r--r--deps/icu-small/source/i18n/number_utils.cpp11
-rw-r--r--deps/icu-small/source/i18n/number_utils.h45
-rw-r--r--deps/icu-small/source/i18n/number_utypes.h6
-rw-r--r--deps/icu-small/source/i18n/numfmt.cpp30
-rw-r--r--deps/icu-small/source/i18n/numparse_affixes.cpp5
-rw-r--r--deps/icu-small/source/i18n/numparse_compositions.cpp1
-rw-r--r--deps/icu-small/source/i18n/numparse_currency.cpp1
-rw-r--r--deps/icu-small/source/i18n/numparse_decimal.cpp1
-rw-r--r--deps/icu-small/source/i18n/numparse_impl.cpp6
-rw-r--r--deps/icu-small/source/i18n/numparse_impl.h1
-rw-r--r--deps/icu-small/source/i18n/numparse_parsednumber.cpp5
-rw-r--r--deps/icu-small/source/i18n/numparse_scientific.cpp65
-rw-r--r--deps/icu-small/source/i18n/numparse_scientific.h2
-rw-r--r--deps/icu-small/source/i18n/numparse_stringsegment.h24
-rw-r--r--deps/icu-small/source/i18n/numparse_symbols.cpp9
-rw-r--r--deps/icu-small/source/i18n/numparse_symbols.h2
-rw-r--r--deps/icu-small/source/i18n/numparse_types.h115
-rw-r--r--deps/icu-small/source/i18n/numrange_fluent.cpp4
-rw-r--r--deps/icu-small/source/i18n/numrange_impl.cpp2
-rw-r--r--deps/icu-small/source/i18n/numrange_impl.h6
-rw-r--r--deps/icu-small/source/i18n/numsys.cpp2
-rw-r--r--deps/icu-small/source/i18n/olsontz.cpp9
-rw-r--r--deps/icu-small/source/i18n/olsontz.h4
-rw-r--r--deps/icu-small/source/i18n/persncal.cpp2
-rw-r--r--deps/icu-small/source/i18n/persncal.h2
-rw-r--r--deps/icu-small/source/i18n/plurfmt.cpp15
-rw-r--r--deps/icu-small/source/i18n/quant.cpp2
-rw-r--r--deps/icu-small/source/i18n/quant.h2
-rw-r--r--deps/icu-small/source/i18n/quantityformatter.cpp10
-rw-r--r--deps/icu-small/source/i18n/quantityformatter.h11
-rw-r--r--deps/icu-small/source/i18n/rbnf.cpp53
-rw-r--r--deps/icu-small/source/i18n/rbt.cpp6
-rw-r--r--deps/icu-small/source/i18n/rbt.h2
-rw-r--r--deps/icu-small/source/i18n/rbt_pars.cpp2
-rw-r--r--deps/icu-small/source/i18n/rbt_rule.cpp6
-rw-r--r--deps/icu-small/source/i18n/rbtz.cpp6
-rw-r--r--deps/icu-small/source/i18n/regexcmp.cpp64
-rw-r--r--deps/icu-small/source/i18n/regeximp.h2
-rw-r--r--deps/icu-small/source/i18n/region.cpp40
-rw-r--r--deps/icu-small/source/i18n/reldatefmt.cpp18
-rw-r--r--deps/icu-small/source/i18n/reldtfmt.cpp4
-rw-r--r--deps/icu-small/source/i18n/reldtfmt.h2
-rw-r--r--deps/icu-small/source/i18n/rematch.cpp144
-rw-r--r--deps/icu-small/source/i18n/remtrans.cpp6
-rw-r--r--deps/icu-small/source/i18n/remtrans.h2
-rw-r--r--deps/icu-small/source/i18n/repattrn.cpp4
-rw-r--r--deps/icu-small/source/i18n/rulebasedcollator.cpp2
-rw-r--r--deps/icu-small/source/i18n/scientificnumberformatter.cpp4
-rw-r--r--deps/icu-small/source/i18n/selfmt.cpp2
-rw-r--r--deps/icu-small/source/i18n/simpletz.cpp5
-rw-r--r--deps/icu-small/source/i18n/smpdtfmt.cpp50
-rw-r--r--deps/icu-small/source/i18n/string_segment.cpp (renamed from deps/icu-small/source/i18n/numparse_stringsegment.cpp)7
-rw-r--r--deps/icu-small/source/i18n/string_segment.h134
-rw-r--r--deps/icu-small/source/i18n/strmatch.cpp2
-rw-r--r--deps/icu-small/source/i18n/strmatch.h2
-rw-r--r--deps/icu-small/source/i18n/strrepl.cpp2
-rw-r--r--deps/icu-small/source/i18n/strrepl.h2
-rw-r--r--deps/icu-small/source/i18n/stsearch.cpp2
-rw-r--r--deps/icu-small/source/i18n/taiwncal.cpp2
-rw-r--r--deps/icu-small/source/i18n/taiwncal.h2
-rw-r--r--deps/icu-small/source/i18n/timezone.cpp20
-rw-r--r--deps/icu-small/source/i18n/titletrn.cpp2
-rw-r--r--deps/icu-small/source/i18n/titletrn.h2
-rw-r--r--deps/icu-small/source/i18n/tmunit.cpp2
-rw-r--r--deps/icu-small/source/i18n/tmutamt.cpp2
-rw-r--r--deps/icu-small/source/i18n/tmutfmt.cpp10
-rw-r--r--deps/icu-small/source/i18n/tolowtrn.cpp2
-rw-r--r--deps/icu-small/source/i18n/tolowtrn.h2
-rw-r--r--deps/icu-small/source/i18n/toupptrn.cpp2
-rw-r--r--deps/icu-small/source/i18n/toupptrn.h2
-rw-r--r--deps/icu-small/source/i18n/translit.cpp65
-rw-r--r--deps/icu-small/source/i18n/transreg.cpp8
-rw-r--r--deps/icu-small/source/i18n/tridpars.cpp12
-rw-r--r--deps/icu-small/source/i18n/tzfmt.cpp29
-rw-r--r--deps/icu-small/source/i18n/tzgnames.cpp52
-rw-r--r--deps/icu-small/source/i18n/tznames.cpp19
-rw-r--r--deps/icu-small/source/i18n/tznames_impl.cpp39
-rw-r--r--deps/icu-small/source/i18n/tznames_impl.h4
-rw-r--r--deps/icu-small/source/i18n/tzrule.cpp2
-rw-r--r--deps/icu-small/source/i18n/ucal.cpp29
-rw-r--r--deps/icu-small/source/i18n/udat.cpp8
-rw-r--r--deps/icu-small/source/i18n/unesctrn.cpp2
-rw-r--r--deps/icu-small/source/i18n/unesctrn.h2
-rw-r--r--deps/icu-small/source/i18n/uni2name.cpp2
-rw-r--r--deps/icu-small/source/i18n/uni2name.h2
-rw-r--r--deps/icu-small/source/i18n/unicode/alphaindex.h6
-rw-r--r--deps/icu-small/source/i18n/unicode/basictz.h12
-rw-r--r--deps/icu-small/source/i18n/unicode/calendar.h27
-rw-r--r--deps/icu-small/source/i18n/unicode/choicfmt.h9
-rw-r--r--deps/icu-small/source/i18n/unicode/coleitr.h4
-rw-r--r--deps/icu-small/source/i18n/unicode/coll.h24
-rw-r--r--deps/icu-small/source/i18n/unicode/compactdecimalformat.h7
-rw-r--r--deps/icu-small/source/i18n/unicode/curramt.h7
-rw-r--r--deps/icu-small/source/i18n/unicode/currpinf.h4
-rw-r--r--deps/icu-small/source/i18n/unicode/currunit.h7
-rw-r--r--deps/icu-small/source/i18n/unicode/datefmt.h12
-rw-r--r--deps/icu-small/source/i18n/unicode/dcfmtsym.h8
-rw-r--r--deps/icu-small/source/i18n/unicode/decimfmt.h31
-rw-r--r--deps/icu-small/source/i18n/unicode/dtfmtsym.h4
-rw-r--r--deps/icu-small/source/i18n/unicode/dtitvfmt.h6
-rw-r--r--deps/icu-small/source/i18n/unicode/dtitvinf.h6
-rw-r--r--deps/icu-small/source/i18n/unicode/dtptngen.h12
-rw-r--r--deps/icu-small/source/i18n/unicode/dtrule.h6
-rw-r--r--deps/icu-small/source/i18n/unicode/fieldpos.h4
-rw-r--r--deps/icu-small/source/i18n/unicode/fmtable.h4
-rw-r--r--deps/icu-small/source/i18n/unicode/format.h4
-rw-r--r--deps/icu-small/source/i18n/unicode/formattedvalue.h23
-rw-r--r--deps/icu-small/source/i18n/unicode/fpositer.h5
-rw-r--r--deps/icu-small/source/i18n/unicode/gender.h4
-rw-r--r--deps/icu-small/source/i18n/unicode/gregocal.h8
-rw-r--r--deps/icu-small/source/i18n/unicode/listformatter.h6
-rw-r--r--deps/icu-small/source/i18n/unicode/measfmt.h17
-rw-r--r--deps/icu-small/source/i18n/unicode/measunit.h229
-rw-r--r--deps/icu-small/source/i18n/unicode/measure.h7
-rw-r--r--deps/icu-small/source/i18n/unicode/msgfmt.h10
-rw-r--r--deps/icu-small/source/i18n/unicode/nounit.h9
-rw-r--r--deps/icu-small/source/i18n/unicode/numberformatter.h281
-rw-r--r--deps/icu-small/source/i18n/unicode/numberrangeformatter.h135
-rw-r--r--deps/icu-small/source/i18n/unicode/numfmt.h16
-rw-r--r--deps/icu-small/source/i18n/unicode/numsys.h4
-rw-r--r--deps/icu-small/source/i18n/unicode/plurfmt.h17
-rw-r--r--deps/icu-small/source/i18n/unicode/plurrule.h4
-rw-r--r--deps/icu-small/source/i18n/unicode/rbnf.h28
-rw-r--r--deps/icu-small/source/i18n/unicode/rbtz.h8
-rw-r--r--deps/icu-small/source/i18n/unicode/regex.h5
-rw-r--r--deps/icu-small/source/i18n/unicode/region.h7
-rw-r--r--deps/icu-small/source/i18n/unicode/reldatefmt.h25
-rw-r--r--deps/icu-small/source/i18n/unicode/scientificnumberformatter.h9
-rw-r--r--deps/icu-small/source/i18n/unicode/search.h7
-rwxr-xr-xdeps/icu-small/source/i18n/unicode/selfmt.h9
-rw-r--r--deps/icu-small/source/i18n/unicode/simpletz.h8
-rw-r--r--deps/icu-small/source/i18n/unicode/smpdtfmt.h8
-rw-r--r--deps/icu-small/source/i18n/unicode/sortkey.h4
-rw-r--r--deps/icu-small/source/i18n/unicode/stsearch.h9
-rw-r--r--deps/icu-small/source/i18n/unicode/tblcoll.h11
-rw-r--r--deps/icu-small/source/i18n/unicode/timezone.h14
-rw-r--r--deps/icu-small/source/i18n/unicode/tmunit.h7
-rw-r--r--deps/icu-small/source/i18n/unicode/tmutamt.h12
-rw-r--r--deps/icu-small/source/i18n/unicode/tmutfmt.h8
-rw-r--r--deps/icu-small/source/i18n/unicode/translit.h4
-rw-r--r--deps/icu-small/source/i18n/unicode/tzfmt.h7
-rw-r--r--deps/icu-small/source/i18n/unicode/tznames.h5
-rw-r--r--deps/icu-small/source/i18n/unicode/tzrule.h12
-rw-r--r--deps/icu-small/source/i18n/unicode/tztrans.h6
-rw-r--r--deps/icu-small/source/i18n/unicode/ucal.h40
-rw-r--r--deps/icu-small/source/i18n/unicode/ucol.h2
-rw-r--r--deps/icu-small/source/i18n/unicode/udat.h2
-rw-r--r--deps/icu-small/source/i18n/unicode/udatpg.h2
-rw-r--r--deps/icu-small/source/i18n/unicode/uformattedvalue.h3
-rw-r--r--deps/icu-small/source/i18n/unicode/ulistformatter.h4
-rw-r--r--deps/icu-small/source/i18n/unicode/unirepl.h4
-rw-r--r--deps/icu-small/source/i18n/unicode/unum.h4
-rw-r--r--deps/icu-small/source/i18n/unicode/unumberformatter.h71
-rw-r--r--deps/icu-small/source/i18n/unicode/usearch.h18
-rw-r--r--deps/icu-small/source/i18n/unicode/uspoof.h496
-rw-r--r--deps/icu-small/source/i18n/unicode/utrans.h11
-rw-r--r--deps/icu-small/source/i18n/unicode/vtzone.h8
-rw-r--r--deps/icu-small/source/i18n/unum.cpp5
-rw-r--r--deps/icu-small/source/i18n/usearch.cpp28
-rw-r--r--deps/icu-small/source/i18n/uspoof.cpp2
-rw-r--r--deps/icu-small/source/i18n/uspoof_impl.cpp4
-rw-r--r--deps/icu-small/source/i18n/vtzone.cpp14
-rw-r--r--deps/icu-small/source/i18n/windtfmt.cpp2
-rw-r--r--deps/icu-small/source/i18n/windtfmt.h2
-rw-r--r--deps/icu-small/source/i18n/winnmfmt.cpp2
-rw-r--r--deps/icu-small/source/i18n/winnmfmt.h2
-rw-r--r--deps/icu-small/source/i18n/zonemeta.cpp29
-rw-r--r--deps/icu-small/source/python/icutools/databuilder/filtration_schema.json169
-rw-r--r--deps/icu-small/source/tools/genccode/genccode.c15
-rw-r--r--deps/icu-small/source/tools/genrb/derb.cpp2
-rw-r--r--deps/icu-small/source/tools/genrb/filterrb.cpp3
-rw-r--r--deps/icu-small/source/tools/genrb/genrb.cpp8
-rw-r--r--deps/icu-small/source/tools/genrb/parse.cpp104
-rw-r--r--deps/icu-small/source/tools/genrb/reslist.cpp2
-rw-r--r--deps/icu-small/source/tools/genrb/rle.c4
-rw-r--r--deps/icu-small/source/tools/genrb/ustr.h8
-rw-r--r--deps/icu-small/source/tools/pkgdata/pkgdata.cpp80
-rw-r--r--deps/icu-small/source/tools/toolutil/filetools.cpp2
-rw-r--r--deps/icu-small/source/tools/toolutil/pkg_genc.cpp242
-rw-r--r--deps/icu-small/source/tools/toolutil/pkg_genc.h25
-rw-r--r--deps/icu-small/source/tools/toolutil/pkgitems.cpp3
-rw-r--r--deps/icu-small/source/tools/toolutil/toolutil.cpp2
-rw-r--r--deps/icu-small/source/tools/toolutil/ucbuf.h4
-rw-r--r--deps/icu-small/source/tools/toolutil/xmlparser.cpp2
-rw-r--r--tools/icu/current_ver.dep4
453 files changed, 11832 insertions, 5897 deletions
diff --git a/deps/icu-small/README-FULL-ICU.txt b/deps/icu-small/README-FULL-ICU.txt
index d954e58a5f..99a75bed1d 100644
--- a/deps/icu-small/README-FULL-ICU.txt
+++ b/deps/icu-small/README-FULL-ICU.txt
@@ -1,8 +1,8 @@
ICU sources - auto generated by shrink-icu-src.py
This directory contains the ICU subset used by --with-intl=full-icu
-It is a strict subset of ICU 64 source files with the following exception(s):
-* deps/icu-small/source/data/in/icudt64l.dat.bz2 : compressed data file
+It is a strict subset of ICU 65 source files with the following exception(s):
+* deps/icu-small/source/data/in/icudt65l.dat.bz2 : compressed data file
To rebuild this directory, see ../../tools/icu/README.md
diff --git a/deps/icu-small/source/common/brkeng.cpp b/deps/icu-small/source/common/brkeng.cpp
index 42771b3617..68c74f2359 100644
--- a/deps/icu-small/source/common/brkeng.cpp
+++ b/deps/icu-small/source/common/brkeng.cpp
@@ -129,7 +129,7 @@ ICULanguageBreakFactory::getEngineFor(UChar32 c) {
const LanguageBreakEngine *lbe = NULL;
UErrorCode status = U_ZERO_ERROR;
- static UMutex gBreakEngineMutex = U_MUTEX_INITIALIZER;
+ static UMutex gBreakEngineMutex;
Mutex m(&gBreakEngineMutex);
if (fEngines == NULL) {
diff --git a/deps/icu-small/source/common/brkiter.cpp b/deps/icu-small/source/common/brkiter.cpp
index 23e0cc3c15..2fc4c345c7 100644
--- a/deps/icu-small/source/common/brkiter.cpp
+++ b/deps/icu-small/source/common/brkiter.cpp
@@ -277,7 +277,7 @@ ICUBreakIteratorService::~ICUBreakIteratorService() {}
// defined in ucln_cmn.h
U_NAMESPACE_END
-static icu::UInitOnce gInitOnceBrkiter;
+static icu::UInitOnce gInitOnceBrkiter = U_INITONCE_INITIALIZER;
static icu::ICULocaleService* gService = NULL;
diff --git a/deps/icu-small/source/common/bytesinkutil.h b/deps/icu-small/source/common/bytesinkutil.h
index 69e4cbcd26..6808fbe677 100644
--- a/deps/icu-small/source/common/bytesinkutil.h
+++ b/deps/icu-small/source/common/bytesinkutil.h
@@ -59,7 +59,7 @@ private:
ByteSink &sink, uint32_t options, Edits *edits);
};
-class CharStringByteSink : public ByteSink {
+class U_COMMON_API CharStringByteSink : public ByteSink {
public:
CharStringByteSink(CharString* dest);
~CharStringByteSink() override;
diff --git a/deps/icu-small/source/common/characterproperties.cpp b/deps/icu-small/source/common/characterproperties.cpp
index 5a57364375..7b50a4e205 100644
--- a/deps/icu-small/source/common/characterproperties.cpp
+++ b/deps/icu-small/source/common/characterproperties.cpp
@@ -38,8 +38,8 @@ UBool U_CALLCONV characterproperties_cleanup();
constexpr int32_t NUM_INCLUSIONS = UPROPS_SRC_COUNT + UCHAR_INT_LIMIT - UCHAR_INT_START;
struct Inclusion {
- UnicodeSet *fSet;
- UInitOnce fInitOnce;
+ UnicodeSet *fSet = nullptr;
+ UInitOnce fInitOnce = U_INITONCE_INITIALIZER;
};
Inclusion gInclusions[NUM_INCLUSIONS]; // cached getInclusions()
@@ -47,10 +47,7 @@ UnicodeSet *sets[UCHAR_BINARY_LIMIT] = {};
UCPMap *maps[UCHAR_INT_LIMIT - UCHAR_INT_START] = {};
-icu::UMutex *cpMutex() {
- static icu::UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+icu::UMutex cpMutex;
//----------------------------------------------------------------
// Inclusions list
@@ -361,7 +358,7 @@ u_getBinaryPropertySet(UProperty property, UErrorCode *pErrorCode) {
*pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
return nullptr;
}
- Mutex m(cpMutex());
+ Mutex m(&cpMutex);
UnicodeSet *set = sets[property];
if (set == nullptr) {
sets[property] = set = makeSet(property, *pErrorCode);
@@ -377,7 +374,7 @@ u_getIntPropertyMap(UProperty property, UErrorCode *pErrorCode) {
*pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
return nullptr;
}
- Mutex m(cpMutex());
+ Mutex m(&cpMutex);
UCPMap *map = maps[property - UCHAR_INT_START];
if (map == nullptr) {
maps[property - UCHAR_INT_START] = map = makeMap(property, *pErrorCode);
diff --git a/deps/icu-small/source/common/charstr.cpp b/deps/icu-small/source/common/charstr.cpp
index 852cc53945..dda29dac63 100644
--- a/deps/icu-small/source/common/charstr.cpp
+++ b/deps/icu-small/source/common/charstr.cpp
@@ -35,6 +35,17 @@ CharString& CharString::operator=(CharString&& src) U_NOEXCEPT {
return *this;
}
+char *CharString::cloneData(UErrorCode &errorCode) const {
+ if (U_FAILURE(errorCode)) { return nullptr; }
+ char *p = static_cast<char *>(uprv_malloc(len + 1));
+ if (p == nullptr) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ return nullptr;
+ }
+ uprv_memcpy(p, buffer.getAlias(), len + 1);
+ return p;
+}
+
CharString &CharString::copyFrom(const CharString &s, UErrorCode &errorCode) {
if(U_SUCCESS(errorCode) && this!=&s && ensureCapacity(s.len+1, 0, errorCode)) {
len=s.len;
@@ -52,6 +63,18 @@ int32_t CharString::lastIndexOf(char c) const {
return -1;
}
+bool CharString::contains(StringPiece s) const {
+ if (s.empty()) { return false; }
+ const char *p = buffer.getAlias();
+ int32_t lastStart = len - s.length();
+ for (int32_t i = 0; i <= lastStart; ++i) {
+ if (uprv_memcmp(p + i, s.data(), s.length()) == 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
CharString &CharString::truncate(int32_t newLength) {
if(newLength<0) {
newLength=0;
diff --git a/deps/icu-small/source/common/charstr.h b/deps/icu-small/source/common/charstr.h
index 1a97e01988..23b950ed6e 100644
--- a/deps/icu-small/source/common/charstr.h
+++ b/deps/icu-small/source/common/charstr.h
@@ -82,10 +82,24 @@ public:
const char *data() const { return buffer.getAlias(); }
char *data() { return buffer.getAlias(); }
+ /**
+ * Allocates length()+1 chars and copies the NUL-terminated data().
+ * The caller must uprv_free() the result.
+ */
+ char *cloneData(UErrorCode &errorCode) const;
+
+ bool operator==(StringPiece other) const {
+ return len == other.length() && (len == 0 || uprv_memcmp(data(), other.data(), len) == 0);
+ }
+ bool operator!=(StringPiece other) const {
+ return !operator==(other);
+ }
/** @return last index of c, or -1 if c is not in this string */
int32_t lastIndexOf(char c) const;
+ bool contains(StringPiece s) const;
+
CharString &clear() { len=0; buffer[0]=0; return *this; }
CharString &truncate(int32_t newLength);
diff --git a/deps/icu-small/source/common/cmemory.h b/deps/icu-small/source/common/cmemory.h
index f501b20a14..b24bd0ead2 100644
--- a/deps/icu-small/source/common/cmemory.h
+++ b/deps/icu-small/source/common/cmemory.h
@@ -65,37 +65,36 @@ U_CAPI void * U_EXPORT2
uprv_calloc(size_t num, size_t size) U_MALLOC_ATTR U_ALLOC_SIZE_ATTR2(1,2);
/**
- * This should align the memory properly on any machine.
- * This is very useful for the safeClone functions.
- */
-typedef union {
- long t1;
- double t2;
- void *t3;
-} UAlignedMemory;
-
-/**
* Get the least significant bits of a pointer (a memory address).
* For example, with a mask of 3, the macro gets the 2 least significant bits,
* which will be 0 if the pointer is 32-bit (4-byte) aligned.
*
- * ptrdiff_t is the most appropriate integer type to cast to.
- * size_t should work too, since on most (or all?) platforms it has the same
- * width as ptrdiff_t.
+ * uintptr_t is the most appropriate integer type to cast to.
*/
-#define U_POINTER_MASK_LSB(ptr, mask) (((ptrdiff_t)(char *)(ptr)) & (mask))
+#define U_POINTER_MASK_LSB(ptr, mask) ((uintptr_t)(ptr) & (mask))
/**
- * Get the amount of bytes that a pointer is off by from
- * the previous UAlignedMemory-aligned pointer.
- */
-#define U_ALIGNMENT_OFFSET(ptr) U_POINTER_MASK_LSB(ptr, sizeof(UAlignedMemory) - 1)
-
-/**
- * Get the amount of bytes to add to a pointer
- * in order to get the next UAlignedMemory-aligned address.
+ * Create & return an instance of "type" in statically allocated storage.
+ * e.g.
+ * static std::mutex *myMutex = STATIC_NEW(std::mutex);
+ * To destroy an object created in this way, invoke the destructor explicitly, e.g.
+ * myMutex->~mutex();
+ * DO NOT use delete.
+ * DO NOT use with class UMutex, which has specific support for static instances.
+ *
+ * STATIC_NEW is intended for use when
+ * - We want a static (or global) object.
+ * - We don't want it to ever be destructed, or to explicitly control destruction,
+ * to avoid use-after-destruction problems.
+ * - We want to avoid an ordinary heap allocated object,
+ * to avoid the possibility of memory allocation failures, and
+ * to avoid memory leak reports, from valgrind, for example.
+ * This is defined as a macro rather than a template function because each invocation
+ * must define distinct static storage for the object being returned.
*/
-#define U_ALIGNMENT_OFFSET_UP(ptr) (sizeof(UAlignedMemory) - U_ALIGNMENT_OFFSET(ptr))
+#define STATIC_NEW(type) [] () { \
+ alignas(type) static char storage[sizeof(type)]; \
+ return new(storage) type();} ()
/**
* Heap clean up function, called from u_cleanup()
diff --git a/deps/icu-small/source/common/edits.cpp b/deps/icu-small/source/common/edits.cpp
index 00a8d601a1..95f0c19a72 100644
--- a/deps/icu-small/source/common/edits.cpp
+++ b/deps/icu-small/source/common/edits.cpp
@@ -243,7 +243,7 @@ UBool Edits::growArray() {
return TRUE;
}
-UBool Edits::copyErrorTo(UErrorCode &outErrorCode) {
+UBool Edits::copyErrorTo(UErrorCode &outErrorCode) const {
if (U_FAILURE(outErrorCode)) { return TRUE; }
if (U_SUCCESS(errorCode_)) { return FALSE; }
outErrorCode = errorCode_;
diff --git a/deps/icu-small/source/common/filteredbrk.cpp b/deps/icu-small/source/common/filteredbrk.cpp
index 162b38de5d..ae7cf5270a 100644
--- a/deps/icu-small/source/common/filteredbrk.cpp
+++ b/deps/icu-small/source/common/filteredbrk.cpp
@@ -173,7 +173,7 @@ public:
status = U_SAFECLONE_ALLOCATED_WARNING;
return clone();
}
- virtual BreakIterator* clone(void) const { return new SimpleFilteredSentenceBreakIterator(*this); }
+ virtual SimpleFilteredSentenceBreakIterator* clone() const { return new SimpleFilteredSentenceBreakIterator(*this); }
virtual UClassID getDynamicClassID(void) const { return NULL; }
virtual UBool operator==(const BreakIterator& o) const { if(this==&o) return true; return false; }
diff --git a/deps/icu-small/source/common/localebuilder.cpp b/deps/icu-small/source/common/localebuilder.cpp
index fe931fcf75..1dd8131e58 100644
--- a/deps/icu-small/source/common/localebuilder.cpp
+++ b/deps/icu-small/source/common/localebuilder.cpp
@@ -157,13 +157,18 @@ _isKeywordValue(const char* key, const char* value, int32_t value_len)
}
static void
-_copyExtensions(const Locale& from, Locale* to, bool validate, UErrorCode& errorCode)
+_copyExtensions(const Locale& from, icu::StringEnumeration *keywords,
+ Locale& to, bool validate, UErrorCode& errorCode)
{
if (U_FAILURE(errorCode)) { return; }
- LocalPointer<icu::StringEnumeration> iter(from.createKeywords(errorCode));
- if (U_FAILURE(errorCode) || iter.isNull()) { return; }
+ LocalPointer<icu::StringEnumeration> ownedKeywords;
+ if (keywords == nullptr) {
+ ownedKeywords.adoptInstead(from.createKeywords(errorCode));
+ if (U_FAILURE(errorCode) || ownedKeywords.isNull()) { return; }
+ keywords = ownedKeywords.getAlias();
+ }
const char* key;
- while ((key = iter->next(nullptr, errorCode)) != nullptr) {
+ while ((key = keywords->next(nullptr, errorCode)) != nullptr) {
CharString value;
CharStringByteSink sink(&value);
from.getKeywordValue(key, sink, errorCode);
@@ -176,34 +181,34 @@ _copyExtensions(const Locale& from, Locale* to, bool validate, UErrorCode& error
errorCode = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
- to->setKeywordValue(key, value.data(), errorCode);
+ to.setKeywordValue(key, value.data(), errorCode);
if (U_FAILURE(errorCode)) { return; }
}
}
void static
-_clearUAttributesAndKeyType(Locale* locale, UErrorCode& errorCode)
+_clearUAttributesAndKeyType(Locale& locale, UErrorCode& errorCode)
{
// Clear Unicode attributes
- locale->setKeywordValue(kAttributeKey, "", errorCode);
+ locale.setKeywordValue(kAttributeKey, "", errorCode);
// Clear all Unicode keyword values
- LocalPointer<icu::StringEnumeration> iter(locale->createUnicodeKeywords(errorCode));
+ LocalPointer<icu::StringEnumeration> iter(locale.createUnicodeKeywords(errorCode));
if (U_FAILURE(errorCode) || iter.isNull()) { return; }
const char* key;
while ((key = iter->next(nullptr, errorCode)) != nullptr) {
- locale->setUnicodeKeywordValue(key, nullptr, errorCode);
+ locale.setUnicodeKeywordValue(key, nullptr, errorCode);
}
}
static void
-_setUnicodeExtensions(Locale* locale, const CharString& value, UErrorCode& errorCode)
+_setUnicodeExtensions(Locale& locale, const CharString& value, UErrorCode& errorCode)
{
// Add the unicode extensions to extensions_
CharString locale_str("und-u-", errorCode);
locale_str.append(value, errorCode);
_copyExtensions(
- Locale::forLanguageTag(locale_str.data(), errorCode),
+ Locale::forLanguageTag(locale_str.data(), errorCode), nullptr,
locale, false, errorCode);
}
@@ -235,10 +240,10 @@ LocaleBuilder& LocaleBuilder::setExtension(char key, StringPiece value)
status_);
return *this;
}
- _clearUAttributesAndKeyType(extensions_, status_);
+ _clearUAttributesAndKeyType(*extensions_, status_);
if (U_FAILURE(status_)) { return *this; }
if (!value.empty()) {
- _setUnicodeExtensions(extensions_, value_str, status_);
+ _setUnicodeExtensions(*extensions_, value_str, status_);
}
return *this;
}
@@ -401,6 +406,24 @@ Locale makeBogusLocale() {
return bogus;
}
+void LocaleBuilder::copyExtensionsFrom(const Locale& src, UErrorCode& errorCode)
+{
+ if (U_FAILURE(errorCode)) { return; }
+ LocalPointer<icu::StringEnumeration> keywords(src.createKeywords(errorCode));
+ if (U_FAILURE(errorCode) || keywords.isNull() || keywords->count(errorCode) == 0) {
+ // Error, or no extensions to copy.
+ return;
+ }
+ if (extensions_ == nullptr) {
+ extensions_ = new Locale();
+ if (extensions_ == nullptr) {
+ status_ = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ }
+ _copyExtensions(src, keywords.getAlias(), *extensions_, false, errorCode);
+}
+
Locale LocaleBuilder::build(UErrorCode& errorCode)
{
if (U_FAILURE(errorCode)) {
@@ -425,7 +448,7 @@ Locale LocaleBuilder::build(UErrorCode& errorCode)
}
Locale product(locale_str.data());
if (extensions_ != nullptr) {
- _copyExtensions(*extensions_, &product, true, errorCode);
+ _copyExtensions(*extensions_, nullptr, product, true, errorCode);
}
if (U_FAILURE(errorCode)) {
return makeBogusLocale();
@@ -433,4 +456,13 @@ Locale LocaleBuilder::build(UErrorCode& errorCode)
return product;
}
+UBool LocaleBuilder::copyErrorTo(UErrorCode &outErrorCode) const {
+ if (U_FAILURE(outErrorCode)) {
+ // Do not overwrite the older error code
+ return TRUE;
+ }
+ outErrorCode = status_;
+ return U_FAILURE(outErrorCode);
+}
+
U_NAMESPACE_END
diff --git a/deps/icu-small/source/common/localematcher.cpp b/deps/icu-small/source/common/localematcher.cpp
new file mode 100644
index 0000000000..d975fe759b
--- /dev/null
+++ b/deps/icu-small/source/common/localematcher.cpp
@@ -0,0 +1,720 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+
+// localematcher.cpp
+// created: 2019may08 Markus W. Scherer
+
+#ifndef __LOCMATCHER_H__
+#define __LOCMATCHER_H__
+
+#include "unicode/utypes.h"
+#include "unicode/localebuilder.h"
+#include "unicode/localematcher.h"
+#include "unicode/locid.h"
+#include "unicode/stringpiece.h"
+#include "unicode/uobject.h"
+#include "cstring.h"
+#include "localeprioritylist.h"
+#include "loclikelysubtags.h"
+#include "locdistance.h"
+#include "lsr.h"
+#include "uassert.h"
+#include "uhash.h"
+#include "uvector.h"
+
+#define UND_LSR LSR("und", "", "")
+
+/**
+ * Indicator for the lifetime of desired-locale objects passed into the LocaleMatcher.
+ *
+ * @draft ICU 65
+ */
+enum ULocMatchLifetime {
+ /**
+ * Locale objects are temporary.
+ * The matcher will make a copy of a locale that will be used beyond one function call.
+ *
+ * @draft ICU 65
+ */
+ ULOCMATCH_TEMPORARY_LOCALES,
+ /**
+ * Locale objects are stored at least as long as the matcher is used.
+ * The matcher will keep only a pointer to a locale that will be used beyond one function call,
+ * avoiding a copy.
+ *
+ * @draft ICU 65
+ */
+ ULOCMATCH_STORED_LOCALES // TODO: permanent? cached? clone?
+};
+#ifndef U_IN_DOXYGEN
+typedef enum ULocMatchLifetime ULocMatchLifetime;
+#endif
+
+U_NAMESPACE_BEGIN
+
+LocaleMatcher::Result::Result(LocaleMatcher::Result &&src) U_NOEXCEPT :
+ desiredLocale(src.desiredLocale),
+ supportedLocale(src.supportedLocale),
+ desiredIndex(src.desiredIndex),
+ supportedIndex(src.supportedIndex),
+ desiredIsOwned(src.desiredIsOwned) {
+ if (desiredIsOwned) {
+ src.desiredLocale = nullptr;
+ src.desiredIndex = -1;
+ src.desiredIsOwned = FALSE;
+ }
+}
+
+LocaleMatcher::Result::~Result() {
+ if (desiredIsOwned) {
+ delete desiredLocale;
+ }
+}
+
+LocaleMatcher::Result &LocaleMatcher::Result::operator=(LocaleMatcher::Result &&src) U_NOEXCEPT {
+ this->~Result();
+
+ desiredLocale = src.desiredLocale;
+ supportedLocale = src.supportedLocale;
+ desiredIndex = src.desiredIndex;
+ supportedIndex = src.supportedIndex;
+ desiredIsOwned = src.desiredIsOwned;
+
+ if (desiredIsOwned) {
+ src.desiredLocale = nullptr;
+ src.desiredIndex = -1;
+ src.desiredIsOwned = FALSE;
+ }
+ return *this;
+}
+
+Locale LocaleMatcher::Result::makeResolvedLocale(UErrorCode &errorCode) const {
+ if (U_FAILURE(errorCode) || supportedLocale == nullptr) {
+ return Locale::getRoot();
+ }
+ const Locale *bestDesired = getDesiredLocale();
+ if (bestDesired == nullptr || *supportedLocale == *bestDesired) {
+ return *supportedLocale;
+ }
+ LocaleBuilder b;
+ b.setLocale(*supportedLocale);
+
+ // Copy the region from bestDesired, if there is one.
+ const char *region = bestDesired->getCountry();
+ if (*region != 0) {
+ b.setRegion(region);
+ }
+
+ // Copy the variants from bestDesired, if there are any.
+ // Note that this will override any supportedLocale variants.
+ // For example, "sco-ulster-fonipa" + "...-fonupa" => "sco-fonupa" (replacing ulster).
+ const char *variants = bestDesired->getVariant();
+ if (*variants != 0) {
+ b.setVariant(variants);
+ }
+
+ // Copy the extensions from bestDesired, if there are any.
+ // C++ note: The following note, copied from Java, may not be true,
+ // as long as C++ copies by legacy ICU keyword, not by extension singleton.
+ // Note that this will override any supportedLocale extensions.
+ // For example, "th-u-nu-latn-ca-buddhist" + "...-u-nu-native" => "th-u-nu-native"
+ // (replacing calendar).
+ b.copyExtensionsFrom(*bestDesired, errorCode);
+ return b.build(errorCode);
+}
+
+LocaleMatcher::Builder::Builder(LocaleMatcher::Builder &&src) U_NOEXCEPT :
+ errorCode_(src.errorCode_),
+ supportedLocales_(src.supportedLocales_),
+ thresholdDistance_(src.thresholdDistance_),
+ demotion_(src.demotion_),
+ defaultLocale_(src.defaultLocale_),
+ favor_(src.favor_) {
+ src.supportedLocales_ = nullptr;
+ src.defaultLocale_ = nullptr;
+}
+
+LocaleMatcher::Builder::~Builder() {
+ delete supportedLocales_;
+ delete defaultLocale_;
+}
+
+LocaleMatcher::Builder &LocaleMatcher::Builder::operator=(LocaleMatcher::Builder &&src) U_NOEXCEPT {
+ this->~Builder();
+
+ errorCode_ = src.errorCode_;
+ supportedLocales_ = src.supportedLocales_;
+ thresholdDistance_ = src.thresholdDistance_;
+ demotion_ = src.demotion_;
+ defaultLocale_ = src.defaultLocale_;
+ favor_ = src.favor_;
+
+ src.supportedLocales_ = nullptr;
+ src.defaultLocale_ = nullptr;
+ return *this;
+}
+
+void LocaleMatcher::Builder::clearSupportedLocales() {
+ if (supportedLocales_ != nullptr) {
+ supportedLocales_->removeAllElements();
+ }
+}
+
+bool LocaleMatcher::Builder::ensureSupportedLocaleVector() {
+ if (U_FAILURE(errorCode_)) { return false; }
+ if (supportedLocales_ != nullptr) { return true; }
+ supportedLocales_ = new UVector(uprv_deleteUObject, nullptr, errorCode_);
+ if (U_FAILURE(errorCode_)) { return false; }
+ if (supportedLocales_ == nullptr) {
+ errorCode_ = U_MEMORY_ALLOCATION_ERROR;
+ return false;
+ }
+ return true;
+}
+
+LocaleMatcher::Builder &LocaleMatcher::Builder::setSupportedLocalesFromListString(
+ StringPiece locales) {
+ LocalePriorityList list(locales, errorCode_);
+ if (U_FAILURE(errorCode_)) { return *this; }
+ clearSupportedLocales();
+ if (!ensureSupportedLocaleVector()) { return *this; }
+ int32_t length = list.getLengthIncludingRemoved();
+ for (int32_t i = 0; i < length; ++i) {
+ Locale *locale = list.orphanLocaleAt(i);
+ if (locale == nullptr) { continue; }
+ supportedLocales_->addElement(locale, errorCode_);
+ if (U_FAILURE(errorCode_)) {
+ delete locale;
+ break;
+ }
+ }
+ return *this;
+}
+
+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_->addElement(clone, errorCode_);
+ if (U_FAILURE(errorCode_)) {
+ delete clone;
+ break;
+ }
+ }
+ 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_->addElement(clone, errorCode_);
+ if (U_FAILURE(errorCode_)) {
+ delete clone;
+ }
+ return *this;
+}
+
+LocaleMatcher::Builder &LocaleMatcher::Builder::setDefaultLocale(const Locale *defaultLocale) {
+ if (U_FAILURE(errorCode_)) { return *this; }
+ Locale *clone = nullptr;
+ if (defaultLocale != nullptr) {
+ clone = defaultLocale->clone();
+ if (clone == nullptr) {
+ errorCode_ = U_MEMORY_ALLOCATION_ERROR;
+ return *this;
+ }
+ }
+ delete defaultLocale_;
+ defaultLocale_ = clone;
+ return *this;
+}
+
+LocaleMatcher::Builder &LocaleMatcher::Builder::setFavorSubtag(ULocMatchFavorSubtag subtag) {
+ if (U_FAILURE(errorCode_)) { return *this; }
+ favor_ = subtag;
+ return *this;
+}
+
+LocaleMatcher::Builder &LocaleMatcher::Builder::setDemotionPerDesiredLocale(ULocMatchDemotion demotion) {
+ if (U_FAILURE(errorCode_)) { return *this; }
+ demotion_ = demotion;
+ return *this;
+}
+
+#if 0
+/**
+ * <i>Internal only!</i>
+ *
+ * @param thresholdDistance the thresholdDistance to set, with -1 = default
+ * @return this Builder object
+ * @internal
+ * @deprecated This API is ICU internal only.
+ */
+@Deprecated
+LocaleMatcher::Builder &LocaleMatcher::Builder::internalSetThresholdDistance(int32_t thresholdDistance) {
+ if (U_FAILURE(errorCode_)) { return *this; }
+ if (thresholdDistance > 100) {
+ thresholdDistance = 100;
+ }
+ thresholdDistance_ = thresholdDistance;
+ return *this;
+}
+#endif
+
+UBool LocaleMatcher::Builder::copyErrorTo(UErrorCode &outErrorCode) const {
+ if (U_FAILURE(outErrorCode)) { return TRUE; }
+ if (U_SUCCESS(errorCode_)) { return FALSE; }
+ outErrorCode = errorCode_;
+ return TRUE;
+}
+
+LocaleMatcher LocaleMatcher::Builder::build(UErrorCode &errorCode) const {
+ if (U_SUCCESS(errorCode) && U_FAILURE(errorCode_)) {
+ errorCode = errorCode_;
+ }
+ return LocaleMatcher(*this, errorCode);
+}
+
+namespace {
+
+LSR getMaximalLsrOrUnd(const XLikelySubtags &likelySubtags, const Locale &locale,
+ UErrorCode &errorCode) {
+ if (U_FAILURE(errorCode) || locale.isBogus() || *locale.getName() == 0 /* "und" */) {
+ return UND_LSR;
+ } else {
+ return likelySubtags.makeMaximizedLsrFrom(locale, errorCode);
+ }
+}
+
+int32_t hashLSR(const UHashTok token) {
+ const LSR *lsr = static_cast<const LSR *>(token.pointer);
+ return lsr->hashCode;
+}
+
+UBool compareLSRs(const UHashTok t1, const UHashTok t2) {
+ const LSR *lsr1 = static_cast<const LSR *>(t1.pointer);
+ const LSR *lsr2 = static_cast<const LSR *>(t2.pointer);
+ return *lsr1 == *lsr2;
+}
+
+bool putIfAbsent(UHashtable *lsrToIndex, const LSR &lsr, int32_t i, UErrorCode &errorCode) {
+ if (U_FAILURE(errorCode)) { return false; }
+ U_ASSERT(i > 0);
+ int32_t index = uhash_geti(lsrToIndex, &lsr);
+ if (index != 0) {
+ return false;
+ } else {
+ uhash_puti(lsrToIndex, const_cast<LSR *>(&lsr), i, &errorCode);
+ return U_SUCCESS(errorCode);
+ }
+}
+
+} // namespace
+
+LocaleMatcher::LocaleMatcher(const Builder &builder, UErrorCode &errorCode) :
+ likelySubtags(*XLikelySubtags::getSingleton(errorCode)),
+ localeDistance(*LocaleDistance::getSingleton(errorCode)),
+ thresholdDistance(builder.thresholdDistance_),
+ demotionPerDesiredLocale(0),
+ favorSubtag(builder.favor_),
+ supportedLocales(nullptr), lsrs(nullptr), supportedLocalesLength(0),
+ supportedLsrToIndex(nullptr),
+ supportedLSRs(nullptr), supportedIndexes(nullptr), supportedLSRsLength(0),
+ ownedDefaultLocale(nullptr), defaultLocale(nullptr), defaultLocaleIndex(-1) {
+ if (U_FAILURE(errorCode)) { return; }
+ if (thresholdDistance < 0) {
+ thresholdDistance = localeDistance.getDefaultScriptDistance();
+ }
+ supportedLocalesLength = builder.supportedLocales_ != nullptr ?
+ builder.supportedLocales_->size() : 0;
+ const Locale *def = builder.defaultLocale_;
+ int32_t idef = -1;
+ if (supportedLocalesLength > 0) {
+ // Store the supported locales in input order,
+ // so that when different types are used (e.g., language tag strings)
+ // we can return those by parallel index.
+ supportedLocales = static_cast<const Locale **>(
+ uprv_malloc(supportedLocalesLength * sizeof(const Locale *)));
+ // Supported LRSs in input order.
+ // In C++, we store these permanently to simplify ownership management
+ // in the hash tables. Duplicate LSRs (if any) are unused overhead.
+ lsrs = new LSR[supportedLocalesLength];
+ if (supportedLocales == nullptr || lsrs == nullptr) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ // If the constructor fails partway, we need null pointers for destructibility.
+ uprv_memset(supportedLocales, 0, supportedLocalesLength * sizeof(const Locale *));
+ // Also find the first supported locale whose LSR is
+ // the same as that for the default locale.
+ LSR builderDefaultLSR;
+ const LSR *defLSR = nullptr;
+ if (def != nullptr) {
+ builderDefaultLSR = getMaximalLsrOrUnd(likelySubtags, *def, errorCode);
+ if (U_FAILURE(errorCode)) { return; }
+ defLSR = &builderDefaultLSR;
+ }
+ for (int32_t i = 0; i < supportedLocalesLength; ++i) {
+ const Locale &locale = *static_cast<Locale *>(builder.supportedLocales_->elementAt(i));
+ supportedLocales[i] = locale.clone();
+ if (supportedLocales[i] == nullptr) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ const Locale &supportedLocale = *supportedLocales[i];
+ LSR &lsr = lsrs[i] = getMaximalLsrOrUnd(likelySubtags, supportedLocale, errorCode);
+ lsr.setHashCode();
+ if (U_FAILURE(errorCode)) { return; }
+ if (idef < 0 && defLSR != nullptr && lsr == *defLSR) {
+ idef = i;
+ defLSR = &lsr; // owned pointer to put into supportedLsrToIndex
+ if (*def == supportedLocale) {
+ def = &supportedLocale; // owned pointer to keep
+ }
+ }
+ }
+
+ // We need an unordered map from LSR to first supported locale with that LSR,
+ // and an ordered list of (LSR, supported index).
+ // We insert the supported locales in the following order:
+ // 1. Default locale, if it is supported.
+ // 2. Priority locales (aka "paradigm locales") in builder order.
+ // 3. Remaining locales in builder order.
+ // In Java, we use a LinkedHashMap for both map & ordered lists.
+ // In C++, we use separate structures.
+ // We over-allocate arrays of LSRs and indexes for simplicity.
+ // We reserve slots at the array starts for the default and paradigm locales,
+ // plus enough for all supported locales.
+ // If there are few paradigm locales and few duplicate supported LSRs,
+ // then the amount of wasted space is small.
+ supportedLsrToIndex = uhash_openSize(hashLSR, compareLSRs, uhash_compareLong,
+ supportedLocalesLength, &errorCode);
+ if (U_FAILURE(errorCode)) { return; }
+ int32_t paradigmLimit = 1 + localeDistance.getParadigmLSRsLength();
+ int32_t suppLSRsCapacity = paradigmLimit + supportedLocalesLength;
+ supportedLSRs = static_cast<const LSR **>(
+ uprv_malloc(suppLSRsCapacity * sizeof(const LSR *)));
+ supportedIndexes = static_cast<int32_t *>(
+ uprv_malloc(suppLSRsCapacity * sizeof(int32_t)));
+ if (supportedLSRs == nullptr || supportedIndexes == nullptr) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ int32_t paradigmIndex = 0;
+ int32_t otherIndex = paradigmLimit;
+ if (idef >= 0) {
+ uhash_puti(supportedLsrToIndex, const_cast<LSR *>(defLSR), idef + 1, &errorCode);
+ supportedLSRs[0] = defLSR;
+ supportedIndexes[0] = idef;
+ paradigmIndex = 1;
+ }
+ for (int32_t i = 0; i < supportedLocalesLength; ++i) {
+ if (i == idef) { continue; }
+ const Locale &locale = *supportedLocales[i];
+ const LSR &lsr = lsrs[i];
+ if (defLSR == nullptr) {
+ U_ASSERT(i == 0);
+ def = &locale;
+ defLSR = &lsr;
+ idef = 0;
+ uhash_puti(supportedLsrToIndex, const_cast<LSR *>(&lsr), 0 + 1, &errorCode);
+ supportedLSRs[0] = &lsr;
+ supportedIndexes[0] = 0;
+ paradigmIndex = 1;
+ } else if (idef >= 0 && lsr == *defLSR) {
+ // lsr == *defLSR means that this supported locale is
+ // a duplicate of the default locale.
+ // Either an explicit default locale is supported, and we added it before the loop,
+ // or there is no explicit default locale, and this is
+ // a duplicate of the first supported locale.
+ // In both cases, idef >= 0 now, so otherwise we can skip the comparison.
+ // For a duplicate, putIfAbsent() is a no-op, so nothing to do.
+ } else {
+ if (putIfAbsent(supportedLsrToIndex, lsr, i + 1, errorCode)) {
+ if (localeDistance.isParadigmLSR(lsr)) {
+ supportedLSRs[paradigmIndex] = &lsr;
+ supportedIndexes[paradigmIndex++] = i;
+ } else {
+ supportedLSRs[otherIndex] = &lsr;
+ supportedIndexes[otherIndex++] = i;
+ }
+ }
+ }
+ if (U_FAILURE(errorCode)) { return; }
+ }
+ // Squeeze out unused array slots.
+ if (paradigmIndex < paradigmLimit && paradigmLimit < otherIndex) {
+ uprv_memmove(supportedLSRs + paradigmIndex, supportedLSRs + paradigmLimit,
+ (otherIndex - paradigmLimit) * sizeof(const LSR *));
+ uprv_memmove(supportedIndexes + paradigmIndex, supportedIndexes + paradigmLimit,
+ (otherIndex - paradigmLimit) * sizeof(int32_t));
+ }
+ supportedLSRsLength = otherIndex - (paradigmLimit - paradigmIndex);
+ }
+
+ if (def != nullptr && (idef < 0 || def != supportedLocales[idef])) {
+ ownedDefaultLocale = def->clone();
+ if (ownedDefaultLocale == nullptr) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ def = ownedDefaultLocale;
+ }
+ defaultLocale = def;
+ defaultLocaleIndex = idef;
+
+ if (builder.demotion_ == ULOCMATCH_DEMOTION_REGION) {
+ demotionPerDesiredLocale = localeDistance.getDefaultDemotionPerDesiredLocale();
+ }
+}
+
+LocaleMatcher::LocaleMatcher(LocaleMatcher &&src) U_NOEXCEPT :
+ likelySubtags(src.likelySubtags),
+ localeDistance(src.localeDistance),
+ thresholdDistance(src.thresholdDistance),
+ demotionPerDesiredLocale(src.demotionPerDesiredLocale),
+ favorSubtag(src.favorSubtag),
+ supportedLocales(src.supportedLocales), lsrs(src.lsrs),
+ supportedLocalesLength(src.supportedLocalesLength),
+ supportedLsrToIndex(src.supportedLsrToIndex),
+ supportedLSRs(src.supportedLSRs),
+ supportedIndexes(src.supportedIndexes),
+ supportedLSRsLength(src.supportedLSRsLength),
+ ownedDefaultLocale(src.ownedDefaultLocale), defaultLocale(src.defaultLocale),
+ defaultLocaleIndex(src.defaultLocaleIndex) {
+ src.supportedLocales = nullptr;
+ src.lsrs = nullptr;
+ src.supportedLocalesLength = 0;
+ src.supportedLsrToIndex = nullptr;
+ src.supportedLSRs = nullptr;
+ src.supportedIndexes = nullptr;
+ src.supportedLSRsLength = 0;
+ src.ownedDefaultLocale = nullptr;
+ src.defaultLocale = nullptr;
+ src.defaultLocaleIndex = -1;
+}
+
+LocaleMatcher::~LocaleMatcher() {
+ for (int32_t i = 0; i < supportedLocalesLength; ++i) {
+ delete supportedLocales[i];
+ }
+ uprv_free(supportedLocales);
+ delete[] lsrs;
+ uhash_close(supportedLsrToIndex);
+ uprv_free(supportedLSRs);
+ uprv_free(supportedIndexes);
+ delete ownedDefaultLocale;
+}
+
+LocaleMatcher &LocaleMatcher::operator=(LocaleMatcher &&src) U_NOEXCEPT {
+ this->~LocaleMatcher();
+
+ thresholdDistance = src.thresholdDistance;
+ demotionPerDesiredLocale = src.demotionPerDesiredLocale;
+ favorSubtag = src.favorSubtag;
+ supportedLocales = src.supportedLocales;
+ lsrs = src.lsrs;
+ supportedLocalesLength = src.supportedLocalesLength;
+ supportedLsrToIndex = src.supportedLsrToIndex;
+ supportedLSRs = src.supportedLSRs;
+ supportedIndexes = src.supportedIndexes;
+ supportedLSRsLength = src.supportedLSRsLength;
+ ownedDefaultLocale = src.ownedDefaultLocale;
+ defaultLocale = src.defaultLocale;
+ defaultLocaleIndex = src.defaultLocaleIndex;
+
+ src.supportedLocales = nullptr;
+ src.lsrs = nullptr;
+ src.supportedLocalesLength = 0;
+ src.supportedLsrToIndex = nullptr;
+ src.supportedLSRs = nullptr;
+ src.supportedIndexes = nullptr;
+ src.supportedLSRsLength = 0;
+ src.ownedDefaultLocale = nullptr;
+ src.defaultLocale = nullptr;
+ src.defaultLocaleIndex = -1;
+ return *this;
+}
+
+class LocaleLsrIterator {
+public:
+ LocaleLsrIterator(const XLikelySubtags &likelySubtags, Locale::Iterator &locales,
+ ULocMatchLifetime lifetime) :
+ likelySubtags(likelySubtags), locales(locales), lifetime(lifetime) {}
+
+ ~LocaleLsrIterator() {
+ if (lifetime == ULOCMATCH_TEMPORARY_LOCALES) {
+ delete remembered;
+ }
+ }
+
+ bool hasNext() const {
+ return locales.hasNext();
+ }
+
+ LSR next(UErrorCode &errorCode) {
+ current = &locales.next();
+ return getMaximalLsrOrUnd(likelySubtags, *current, errorCode);
+ }
+
+ void rememberCurrent(int32_t desiredIndex, UErrorCode &errorCode) {
+ if (U_FAILURE(errorCode)) { return; }
+ bestDesiredIndex = desiredIndex;
+ if (lifetime == ULOCMATCH_STORED_LOCALES) {
+ remembered = current;
+ } else {
+ // ULOCMATCH_TEMPORARY_LOCALES
+ delete remembered;
+ remembered = new Locale(*current);
+ if (remembered == nullptr) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ }
+ }
+ }
+
+ const Locale *orphanRemembered() {
+ const Locale *rem = remembered;
+ remembered = nullptr;
+ return rem;
+ }
+
+ int32_t getBestDesiredIndex() const {
+ return bestDesiredIndex;
+ }
+
+private:
+ const XLikelySubtags &likelySubtags;
+ Locale::Iterator &locales;
+ ULocMatchLifetime lifetime;
+ const Locale *current = nullptr, *remembered = nullptr;
+ int32_t bestDesiredIndex = -1;
+};
+
+const Locale *LocaleMatcher::getBestMatch(const Locale &desiredLocale, UErrorCode &errorCode) const {
+ if (U_FAILURE(errorCode)) { return nullptr; }
+ int32_t suppIndex = getBestSuppIndex(
+ getMaximalLsrOrUnd(likelySubtags, desiredLocale, errorCode),
+ nullptr, errorCode);
+ return U_SUCCESS(errorCode) && suppIndex >= 0 ? supportedLocales[suppIndex] : defaultLocale;
+}
+
+const Locale *LocaleMatcher::getBestMatch(Locale::Iterator &desiredLocales,
+ UErrorCode &errorCode) const {
+ if (U_FAILURE(errorCode)) { return nullptr; }
+ if (!desiredLocales.hasNext()) {
+ return defaultLocale;
+ }
+ LocaleLsrIterator lsrIter(likelySubtags, desiredLocales, ULOCMATCH_TEMPORARY_LOCALES);
+ int32_t suppIndex = getBestSuppIndex(lsrIter.next(errorCode), &lsrIter, errorCode);
+ return U_SUCCESS(errorCode) && suppIndex >= 0 ? supportedLocales[suppIndex] : defaultLocale;
+}
+
+const Locale *LocaleMatcher::getBestMatchForListString(
+ StringPiece desiredLocaleList, UErrorCode &errorCode) const {
+ LocalePriorityList list(desiredLocaleList, errorCode);
+ LocalePriorityList::Iterator iter = list.iterator();
+ return getBestMatch(iter, errorCode);
+}
+
+LocaleMatcher::Result LocaleMatcher::getBestMatchResult(
+ const Locale &desiredLocale, UErrorCode &errorCode) const {
+ if (U_FAILURE(errorCode)) {
+ return Result(nullptr, defaultLocale, -1, defaultLocaleIndex, FALSE);
+ }
+ int32_t suppIndex = getBestSuppIndex(
+ getMaximalLsrOrUnd(likelySubtags, desiredLocale, errorCode),
+ nullptr, errorCode);
+ if (U_FAILURE(errorCode) || suppIndex < 0) {
+ return Result(nullptr, defaultLocale, -1, defaultLocaleIndex, FALSE);
+ } else {
+ return Result(&desiredLocale, supportedLocales[suppIndex], 0, suppIndex, FALSE);
+ }
+}
+
+LocaleMatcher::Result LocaleMatcher::getBestMatchResult(
+ Locale::Iterator &desiredLocales, UErrorCode &errorCode) const {
+ if (U_FAILURE(errorCode) || !desiredLocales.hasNext()) {
+ return Result(nullptr, defaultLocale, -1, defaultLocaleIndex, FALSE);
+ }
+ LocaleLsrIterator lsrIter(likelySubtags, desiredLocales, ULOCMATCH_TEMPORARY_LOCALES);
+ int32_t suppIndex = getBestSuppIndex(lsrIter.next(errorCode), &lsrIter, errorCode);
+ if (U_FAILURE(errorCode) || suppIndex < 0) {
+ return Result(nullptr, defaultLocale, -1, defaultLocaleIndex, FALSE);
+ } else {
+ return Result(lsrIter.orphanRemembered(), supportedLocales[suppIndex],
+ lsrIter.getBestDesiredIndex(), suppIndex, TRUE);
+ }
+}
+
+int32_t LocaleMatcher::getBestSuppIndex(LSR desiredLSR, LocaleLsrIterator *remainingIter,
+ UErrorCode &errorCode) const {
+ if (U_FAILURE(errorCode)) { return -1; }
+ int32_t desiredIndex = 0;
+ int32_t bestSupportedLsrIndex = -1;
+ for (int32_t bestDistance = thresholdDistance;;) {
+ // Quick check for exact maximized LSR.
+ // Returns suppIndex+1 where 0 means not found.
+ if (supportedLsrToIndex != nullptr) {
+ desiredLSR.setHashCode();
+ int32_t index = uhash_geti(supportedLsrToIndex, &desiredLSR);
+ if (index != 0) {
+ int32_t suppIndex = index - 1;
+ if (remainingIter != nullptr) {
+ remainingIter->rememberCurrent(desiredIndex, errorCode);
+ }
+ return suppIndex;
+ }
+ }
+ int32_t bestIndexAndDistance = localeDistance.getBestIndexAndDistance(
+ desiredLSR, supportedLSRs, supportedLSRsLength, bestDistance, favorSubtag);
+ if (bestIndexAndDistance >= 0) {
+ bestDistance = bestIndexAndDistance & 0xff;
+ if (remainingIter != nullptr) {
+ remainingIter->rememberCurrent(desiredIndex, errorCode);
+ if (U_FAILURE(errorCode)) { return -1; }
+ }
+ bestSupportedLsrIndex = bestIndexAndDistance >= 0 ? bestIndexAndDistance >> 8 : -1;
+ }
+ if ((bestDistance -= demotionPerDesiredLocale) <= 0) {
+ break;
+ }
+ if (remainingIter == nullptr || !remainingIter->hasNext()) {
+ break;
+ }
+ desiredLSR = remainingIter->next(errorCode);
+ if (U_FAILURE(errorCode)) { return -1; }
+ ++desiredIndex;
+ }
+ if (bestSupportedLsrIndex < 0) {
+ // no good match
+ return -1;
+ }
+ return supportedIndexes[bestSupportedLsrIndex];
+}
+
+double LocaleMatcher::internalMatch(const Locale &desired, const Locale &supported, UErrorCode &errorCode) const {
+ // Returns the inverse of the distance: That is, 1-distance(desired, supported).
+ LSR suppLSR = getMaximalLsrOrUnd(likelySubtags, supported, errorCode);
+ if (U_FAILURE(errorCode)) { return 0; }
+ const LSR *pSuppLSR = &suppLSR;
+ int32_t distance = localeDistance.getBestIndexAndDistance(
+ getMaximalLsrOrUnd(likelySubtags, desired, errorCode),
+ &pSuppLSR, 1,
+ thresholdDistance, favorSubtag) & 0xff;
+ return (100 - distance) / 100.0;
+}
+
+U_NAMESPACE_END
+
+#endif // __LOCMATCHER_H__
diff --git a/deps/icu-small/source/common/localeprioritylist.cpp b/deps/icu-small/source/common/localeprioritylist.cpp
new file mode 100644
index 0000000000..06442fb46a
--- /dev/null
+++ b/deps/icu-small/source/common/localeprioritylist.cpp
@@ -0,0 +1,239 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+
+// localeprioritylist.cpp
+// created: 2019jul11 Markus W. Scherer
+
+#include "unicode/utypes.h"
+#include "unicode/localpointer.h"
+#include "unicode/locid.h"
+#include "unicode/stringpiece.h"
+#include "unicode/uobject.h"
+#include "charstr.h"
+#include "cmemory.h"
+#include "localeprioritylist.h"
+#include "uarrsort.h"
+#include "uassert.h"
+#include "uhash.h"
+
+U_NAMESPACE_BEGIN
+
+namespace {
+
+int32_t hashLocale(const UHashTok token) {
+ auto *locale = static_cast<const Locale *>(token.pointer);
+ return locale->hashCode();
+}
+
+UBool compareLocales(const UHashTok t1, const UHashTok t2) {
+ auto *l1 = static_cast<const Locale *>(t1.pointer);
+ auto *l2 = static_cast<const Locale *>(t2.pointer);
+ return *l1 == *l2;
+}
+
+constexpr int32_t WEIGHT_ONE = 1000;
+
+struct LocaleAndWeight {
+ Locale *locale;
+ int32_t weight; // 0..1000 = 0.0..1.0
+ int32_t index; // force stable sort
+
+ int32_t compare(const LocaleAndWeight &other) const {
+ int32_t diff = other.weight - weight; // descending: other-this
+ if (diff != 0) { return diff; }
+ return index - other.index;
+ }
+};
+
+int32_t U_CALLCONV
+compareLocaleAndWeight(const void * /*context*/, const void *left, const void *right) {
+ return static_cast<const LocaleAndWeight *>(left)->
+ compare(*static_cast<const LocaleAndWeight *>(right));
+}
+
+const char *skipSpaces(const char *p, const char *limit) {
+ while (p < limit && *p == ' ') { ++p; }
+ return p;
+}
+
+int32_t findTagLength(const char *p, const char *limit) {
+ // Look for accept-language delimiters.
+ // Leave other validation up to the Locale constructor.
+ const char *q;
+ for (q = p; q < limit; ++q) {
+ char c = *q;
+ if (c == ' ' || c == ',' || c == ';') { break; }
+ }
+ return static_cast<int32_t>(q - p);
+}
+
+/**
+ * Parses and returns a qvalue weight in millis.
+ * Advances p to after the parsed substring.
+ * Returns a negative value if parsing fails.
+ */
+int32_t parseWeight(const char *&p, const char *limit) {
+ p = skipSpaces(p, limit);
+ char c;
+ if (p == limit || ((c = *p) != '0' && c != '1')) { return -1; }
+ int32_t weight = (c - '0') * 1000;
+ if (++p == limit || *p != '.') { return weight; }
+ int32_t multiplier = 100;
+ while (++p != limit && '0' <= (c = *p) && c <= '9') {
+ c -= '0';
+ if (multiplier > 0) {
+ weight += c * multiplier;
+ multiplier /= 10;
+ } else if (multiplier == 0) {
+ // round up
+ if (c >= 5) { ++weight; }
+ multiplier = -1;
+ } // else ignore further fraction digits
+ }
+ return weight <= WEIGHT_ONE ? weight : -1; // bad if > 1.0
+}
+
+} // namespace
+
+/**
+ * Nothing but a wrapper over a MaybeStackArray of LocaleAndWeight.
+ *
+ * This wrapper exists (and is not in an anonymous namespace)
+ * so that we can forward-declare it in the header file and
+ * don't have to expose the MaybeStackArray specialization and
+ * the LocaleAndWeight to code (like the test) that #includes localeprioritylist.h.
+ * Also, otherwise we would have to do a platform-specific
+ * template export declaration of some kind for the MaybeStackArray specialization
+ * to be properly exported from the common DLL.
+ */
+struct LocaleAndWeightArray : public UMemory {
+ MaybeStackArray<LocaleAndWeight, 20> array;
+};
+
+LocalePriorityList::LocalePriorityList(StringPiece s, UErrorCode &errorCode) {
+ if (U_FAILURE(errorCode)) { return; }
+ list = new LocaleAndWeightArray();
+ if (list == nullptr) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ const char *p = s.data();
+ const char *limit = p + s.length();
+ while ((p = skipSpaces(p, limit)) != limit) {
+ if (*p == ',') { // empty range field
+ ++p;
+ continue;
+ }
+ int32_t tagLength = findTagLength(p, limit);
+ if (tagLength == 0) {
+ errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+ return;
+ }
+ CharString tag(p, tagLength, errorCode);
+ if (U_FAILURE(errorCode)) { return; }
+ Locale locale = Locale(tag.data());
+ if (locale.isBogus()) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ int32_t weight = WEIGHT_ONE;
+ if ((p = skipSpaces(p + tagLength, limit)) != limit && *p == ';') {
+ if ((p = skipSpaces(p + 1, limit)) == limit || *p != 'q' ||
+ (p = skipSpaces(p + 1, limit)) == limit || *p != '=' ||
+ (++p, (weight = parseWeight(p, limit)) < 0)) {
+ errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+ return;
+ }
+ p = skipSpaces(p, limit);
+ }
+ if (p != limit && *p != ',') { // trailing junk
+ errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+ return;
+ }
+ add(locale, weight, errorCode);
+ if (p == limit) { break; }
+ ++p;
+ }
+ sort(errorCode);
+}
+
+LocalePriorityList::~LocalePriorityList() {
+ if (list != nullptr) {
+ for (int32_t i = 0; i < listLength; ++i) {
+ delete list->array[i].locale;
+ }
+ delete list;
+ }
+ uhash_close(map);
+}
+
+const Locale *LocalePriorityList::localeAt(int32_t i) const {
+ return list->array[i].locale;
+}
+
+Locale *LocalePriorityList::orphanLocaleAt(int32_t i) {
+ if (list == nullptr) { return nullptr; }
+ LocaleAndWeight &lw = list->array[i];
+ Locale *l = lw.locale;
+ lw.locale = nullptr;
+ return l;
+}
+
+bool LocalePriorityList::add(const Locale &locale, int32_t weight, UErrorCode &errorCode) {
+ if (U_FAILURE(errorCode)) { return false; }
+ if (map == nullptr) {
+ if (weight <= 0) { return true; } // do not add q=0
+ map = uhash_open(hashLocale, compareLocales, uhash_compareLong, &errorCode);
+ if (U_FAILURE(errorCode)) { return false; }
+ }
+ LocalPointer<Locale> clone;
+ int32_t index = uhash_geti(map, &locale);
+ if (index != 0) {
+ // Duplicate: Remove the old item and append it anew.
+ LocaleAndWeight &lw = list->array[index - 1];
+ clone.adoptInstead(lw.locale);
+ lw.locale = nullptr;
+ lw.weight = 0;
+ ++numRemoved;
+ }
+ if (weight <= 0) { // do not add q=0
+ if (index != 0) {
+ // Not strictly necessary but cleaner.
+ uhash_removei(map, &locale);
+ }
+ return true;
+ }
+ if (clone.isNull()) {
+ clone.adoptInstead(locale.clone());
+ if (clone.isNull() || (clone->isBogus() && !locale.isBogus())) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ return false;
+ }
+ }
+ if (listLength == list->array.getCapacity()) {
+ int32_t newCapacity = listLength < 50 ? 100 : 4 * listLength;
+ if (list->array.resize(newCapacity, listLength) == nullptr) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ return false;
+ }
+ }
+ uhash_puti(map, clone.getAlias(), listLength + 1, &errorCode);
+ if (U_FAILURE(errorCode)) { return false; }
+ LocaleAndWeight &lw = list->array[listLength];
+ lw.locale = clone.orphan();
+ lw.weight = weight;
+ lw.index = listLength++;
+ if (weight < WEIGHT_ONE) { hasWeights = true; }
+ U_ASSERT(uhash_count(map) == getLength());
+ return true;
+}
+
+void LocalePriorityList::sort(UErrorCode &errorCode) {
+ // Sort by descending weights if there is a mix of weights.
+ // The comparator forces a stable sort via the item index.
+ if (U_FAILURE(errorCode) || getLength() <= 1 || !hasWeights) { return; }
+ uprv_sortArray(list->array.getAlias(), listLength, sizeof(LocaleAndWeight),
+ compareLocaleAndWeight, nullptr, FALSE, &errorCode);
+}
+
+U_NAMESPACE_END
diff --git a/deps/icu-small/source/common/localeprioritylist.h b/deps/icu-small/source/common/localeprioritylist.h
new file mode 100644
index 0000000000..80ca38a7b5
--- /dev/null
+++ b/deps/icu-small/source/common/localeprioritylist.h
@@ -0,0 +1,115 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+
+// localeprioritylist.h
+// created: 2019jul11 Markus W. Scherer
+
+#ifndef __LOCALEPRIORITYLIST_H__
+#define __LOCALEPRIORITYLIST_H__
+
+#include "unicode/utypes.h"
+#include "unicode/locid.h"
+#include "unicode/stringpiece.h"
+#include "unicode/uobject.h"
+
+struct UHashtable;
+
+U_NAMESPACE_BEGIN
+
+struct LocaleAndWeightArray;
+
+/**
+ * Parses a list of locales from an accept-language string.
+ * We are a bit more lenient than the spec:
+ * We accept extra whitespace in more places, empty range fields,
+ * and any number of qvalue fraction digits.
+ *
+ * https://tools.ietf.org/html/rfc2616#section-14.4
+ * 14.4 Accept-Language
+ *
+ * Accept-Language = "Accept-Language" ":"
+ * 1#( language-range [ ";" "q" "=" qvalue ] )
+ * language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )
+ *
+ * Each language-range MAY be given an associated quality value which
+ * represents an estimate of the user's preference for the languages
+ * specified by that range. The quality value defaults to "q=1". For
+ * example,
+ *
+ * Accept-Language: da, en-gb;q=0.8, en;q=0.7
+ *
+ * https://tools.ietf.org/html/rfc2616#section-3.9
+ * 3.9 Quality Values
+ *
+ * HTTP content negotiation (section 12) uses short "floating point"
+ * numbers to indicate the relative importance ("weight") of various
+ * negotiable parameters. A weight is normalized to a real number in
+ * the range 0 through 1, where 0 is the minimum and 1 the maximum
+ * value. If a parameter has a quality value of 0, then content with
+ * this parameter is `not acceptable' for the client. HTTP/1.1
+ * applications MUST NOT generate more than three digits after the
+ * decimal point. User configuration of these values SHOULD also be
+ * limited in this fashion.
+ *
+ * qvalue = ( "0" [ "." 0*3DIGIT ] )
+ * | ( "1" [ "." 0*3("0") ] )
+ */
+class U_COMMON_API LocalePriorityList : public UMemory {
+public:
+ class Iterator : public Locale::Iterator {
+ public:
+ UBool hasNext() const override { return count < length; }
+
+ const Locale &next() override {
+ for(;;) {
+ const Locale *locale = list.localeAt(index++);
+ if (locale != nullptr) {
+ ++count;
+ return *locale;
+ }
+ }
+ }
+
+ private:
+ friend class LocalePriorityList;
+
+ Iterator(const LocalePriorityList &list) : list(list), length(list.getLength()) {}
+
+ const LocalePriorityList &list;
+ int32_t index = 0;
+ int32_t count = 0;
+ const int32_t length;
+ };
+
+ LocalePriorityList(StringPiece s, UErrorCode &errorCode);
+
+ ~LocalePriorityList();
+
+ int32_t getLength() const { return listLength - numRemoved; }
+
+ int32_t getLengthIncludingRemoved() const { return listLength; }
+
+ Iterator iterator() const { return Iterator(*this); }
+
+ const Locale *localeAt(int32_t i) const;
+
+ Locale *orphanLocaleAt(int32_t i);
+
+private:
+ LocalePriorityList(const LocalePriorityList &) = delete;
+ LocalePriorityList &operator=(const LocalePriorityList &) = delete;
+
+ bool add(const Locale &locale, int32_t weight, UErrorCode &errorCode);
+
+ void sort(UErrorCode &errorCode);
+
+ LocaleAndWeightArray *list = nullptr;
+ int32_t listLength = 0;
+ int32_t numRemoved = 0;
+ bool hasWeights = false; // other than 1.0
+ UHashtable *map = nullptr;
+};
+
+U_NAMESPACE_END
+
+#endif // __LOCALEPRIORITYLIST_H__
diff --git a/deps/icu-small/source/common/locavailable.cpp b/deps/icu-small/source/common/locavailable.cpp
index 1e608ffb9e..ad9d2ca8c7 100644
--- a/deps/icu-small/source/common/locavailable.cpp
+++ b/deps/icu-small/source/common/locavailable.cpp
@@ -19,11 +19,13 @@
* that then do not depend on resource bundle code and res_index bundles.
*/
+#include "unicode/errorcode.h"
#include "unicode/utypes.h"
#include "unicode/locid.h"
#include "unicode/uloc.h"
#include "unicode/ures.h"
#include "cmemory.h"
+#include "cstring.h"
#include "ucln_cmn.h"
#include "uassert.h"
#include "umutex.h"
@@ -95,84 +97,174 @@ U_NAMESPACE_USE
/* ### Constants **************************************************/
-/* These strings describe the resources we attempt to load from
- the locale ResourceBundle data file.*/
-static const char _kIndexLocaleName[] = "res_index";
-static const char _kIndexTag[] = "InstalledLocales";
+namespace {
-static char** _installedLocales = NULL;
-static int32_t _installedLocalesCount = 0;
-static icu::UInitOnce _installedLocalesInitOnce;
+// Enough capacity for the two lists in the res_index.res file
+const char** gAvailableLocaleNames[2] = {};
+int32_t gAvailableLocaleCounts[2] = {};
+icu::UInitOnce ginstalledLocalesInitOnce = U_INITONCE_INITIALIZER;
-/* ### Get available **************************************************/
+class AvailableLocalesSink : public ResourceSink {
+ public:
+ void put(const char *key, ResourceValue &value, UBool /*noFallback*/, UErrorCode &status) U_OVERRIDE {
+ ResourceTable resIndexTable = value.getTable(status);
+ if (U_FAILURE(status)) {
+ return;
+ }
+ for (int32_t i = 0; resIndexTable.getKeyAndValue(i, key, value); ++i) {
+ ULocAvailableType type;
+ if (uprv_strcmp(key, "InstalledLocales") == 0) {
+ type = ULOC_AVAILABLE_DEFAULT;
+ } else if (uprv_strcmp(key, "AliasLocales") == 0) {
+ type = ULOC_AVAILABLE_ONLY_LEGACY_ALIASES;
+ } else {
+ // CLDRVersion, etc.
+ continue;
+ }
+ ResourceTable availableLocalesTable = value.getTable(status);
+ if (U_FAILURE(status)) {
+ return;
+ }
+ gAvailableLocaleCounts[type] = availableLocalesTable.getSize();
+ gAvailableLocaleNames[type] = static_cast<const char**>(
+ uprv_malloc(gAvailableLocaleCounts[type] * sizeof(const char*)));
+ if (gAvailableLocaleNames[type] == nullptr) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ for (int32_t j = 0; availableLocalesTable.getKeyAndValue(j, key, value); ++j) {
+ gAvailableLocaleNames[type][j] = key;
+ }
+ }
+ }
+};
-static UBool U_CALLCONV uloc_cleanup(void) {
- char ** temp;
+class AvailableLocalesStringEnumeration : public StringEnumeration {
+ public:
+ AvailableLocalesStringEnumeration(ULocAvailableType type) : fType(type) {
+ }
+
+ const char* next(int32_t *resultLength, UErrorCode&) override {
+ ULocAvailableType actualType = fType;
+ int32_t actualIndex = fIndex++;
+
+ // If the "combined" list was requested, resolve that now
+ if (fType == ULOC_AVAILABLE_WITH_LEGACY_ALIASES) {
+ int32_t defaultLocalesCount = gAvailableLocaleCounts[ULOC_AVAILABLE_DEFAULT];
+ if (actualIndex < defaultLocalesCount) {
+ actualType = ULOC_AVAILABLE_DEFAULT;
+ } else {
+ actualIndex -= defaultLocalesCount;
+ actualType = ULOC_AVAILABLE_ONLY_LEGACY_ALIASES;
+ }
+ }
+
+ // Return the requested string
+ int32_t count = gAvailableLocaleCounts[actualType];
+ const char* result;
+ if (actualIndex < count) {
+ result = gAvailableLocaleNames[actualType][actualIndex];
+ if (resultLength != nullptr) {
+ *resultLength = static_cast<int32_t>(uprv_strlen(result));
+ }
+ } else {
+ result = nullptr;
+ if (resultLength != nullptr) {
+ *resultLength = 0;
+ }
+ }
+ return result;
+ }
+
+ void reset(UErrorCode&) override {
+ fIndex = 0;
+ }
+
+ int32_t count(UErrorCode&) const override {
+ if (fType == ULOC_AVAILABLE_WITH_LEGACY_ALIASES) {
+ return gAvailableLocaleCounts[ULOC_AVAILABLE_DEFAULT]
+ + gAvailableLocaleCounts[ULOC_AVAILABLE_ONLY_LEGACY_ALIASES];
+ } else {
+ return gAvailableLocaleCounts[fType];
+ }
+ }
- if (_installedLocales) {
- temp = _installedLocales;
- _installedLocales = NULL;
+ private:
+ ULocAvailableType fType;
+ int32_t fIndex = 0;
+};
- _installedLocalesCount = 0;
- _installedLocalesInitOnce.reset();
+/* ### Get available **************************************************/
- uprv_free(temp);
+static UBool U_CALLCONV uloc_cleanup(void) {
+ for (int32_t i = 0; i < UPRV_LENGTHOF(gAvailableLocaleNames); i++) {
+ uprv_free(gAvailableLocaleNames[i]);
+ gAvailableLocaleNames[i] = nullptr;
+ gAvailableLocaleCounts[i] = 0;
}
+ ginstalledLocalesInitOnce.reset();
return TRUE;
}
// Load Installed Locales. This function will be called exactly once
// via the initOnce mechanism.
-static void U_CALLCONV loadInstalledLocales() {
- UErrorCode status = U_ZERO_ERROR;
- int32_t i = 0;
- int32_t localeCount;
-
- U_ASSERT(_installedLocales == NULL);
- U_ASSERT(_installedLocalesCount == 0);
+static void U_CALLCONV loadInstalledLocales(UErrorCode& status) {
+ ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
- _installedLocalesCount = 0;
+ icu::LocalUResourceBundlePointer rb(ures_openDirect(NULL, "res_index", &status));
+ AvailableLocalesSink sink;
+ ures_getAllItemsWithFallback(rb.getAlias(), "", sink, status);
+}
- icu::LocalUResourceBundlePointer indexLocale(ures_openDirect(NULL, _kIndexLocaleName, &status));
- icu::StackUResourceBundle installed;
+void _load_installedLocales(UErrorCode& status) {
+ umtx_initOnce(ginstalledLocalesInitOnce, &loadInstalledLocales, status);
+}
- ures_getByKey(indexLocale.getAlias(), _kIndexTag, installed.getAlias(), &status);
+} // namespace
- if(U_SUCCESS(status)) {
- localeCount = ures_getSize(installed.getAlias());
- _installedLocales = (char **) uprv_malloc(sizeof(char*) * (localeCount+1));
- if (_installedLocales != NULL) {
- ures_resetIterator(installed.getAlias());
- while(ures_hasNext(installed.getAlias())) {
- ures_getNextString(installed.getAlias(), NULL, (const char **)&_installedLocales[i++], &status);
- }
- _installedLocales[i] = NULL;
- _installedLocalesCount = localeCount;
- ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
- }
+U_CAPI const char* U_EXPORT2
+uloc_getAvailable(int32_t offset) {
+ icu::ErrorCode status;
+ _load_installedLocales(status);
+ if (status.isFailure()) {
+ return nullptr;
+ }
+ if (offset > gAvailableLocaleCounts[0]) {
+ // *status = U_ILLEGAL_ARGUMENT_ERROR;
+ return nullptr;
}
+ return gAvailableLocaleNames[0][offset];
}
-static void _load_installedLocales()
-{
- umtx_initOnce(_installedLocalesInitOnce, &loadInstalledLocales);
+U_CAPI int32_t U_EXPORT2
+uloc_countAvailable() {
+ icu::ErrorCode status;
+ _load_installedLocales(status);
+ if (status.isFailure()) {
+ return 0;
+ }
+ return gAvailableLocaleCounts[0];
}
-U_CAPI const char* U_EXPORT2
-uloc_getAvailable(int32_t offset)
-{
-
- _load_installedLocales();
-
- if (offset > _installedLocalesCount)
- return NULL;
- return _installedLocales[offset];
+U_CAPI UEnumeration* U_EXPORT2
+uloc_openAvailableByType(ULocAvailableType type, UErrorCode* status) {
+ if (U_FAILURE(*status)) {
+ return nullptr;
+ }
+ if (type < 0 || type >= ULOC_AVAILABLE_COUNT) {
+ *status = U_ILLEGAL_ARGUMENT_ERROR;
+ return nullptr;
+ }
+ _load_installedLocales(*status);
+ if (U_FAILURE(*status)) {
+ return nullptr;
+ }
+ LocalPointer<AvailableLocalesStringEnumeration> result(
+ new AvailableLocalesStringEnumeration(type), *status);
+ if (U_FAILURE(*status)) {
+ return nullptr;
+ }
+ return uenum_openFromStringEnumeration(result.orphan(), status);
}
-U_CAPI int32_t U_EXPORT2
-uloc_countAvailable()
-{
- _load_installedLocales();
- return _installedLocalesCount;
-}
diff --git a/deps/icu-small/source/common/locbased.h b/deps/icu-small/source/common/locbased.h
index 6db6a41dc4..9163bd11cf 100644
--- a/deps/icu-small/source/common/locbased.h
+++ b/deps/icu-small/source/common/locbased.h
@@ -22,7 +22,7 @@
* `actualLocale' of size ULOC_FULLNAME_CAPACITY
*/
#define U_LOCALE_BASED(varname, objname) \
- LocaleBased varname((objname).validLocale, (objname).actualLocale);
+ LocaleBased varname((objname).validLocale, (objname).actualLocale)
U_NAMESPACE_BEGIN
diff --git a/deps/icu-small/source/common/locdistance.cpp b/deps/icu-small/source/common/locdistance.cpp
new file mode 100644
index 0000000000..800d0eacf2
--- /dev/null
+++ b/deps/icu-small/source/common/locdistance.cpp
@@ -0,0 +1,364 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+
+// locdistance.cpp
+// created: 2019may08 Markus W. Scherer
+
+#include "unicode/utypes.h"
+#include "unicode/bytestrie.h"
+#include "unicode/localematcher.h"
+#include "unicode/locid.h"
+#include "unicode/uobject.h"
+#include "unicode/ures.h"
+#include "cstring.h"
+#include "locdistance.h"
+#include "loclikelysubtags.h"
+#include "uassert.h"
+#include "ucln_cmn.h"
+#include "uinvchar.h"
+#include "umutex.h"
+
+U_NAMESPACE_BEGIN
+
+namespace {
+
+/**
+ * Bit flag used on the last character of a subtag in the trie.
+ * Must be set consistently by the builder and the lookup code.
+ */
+constexpr int32_t END_OF_SUBTAG = 0x80;
+/** Distance value bit flag, set by the builder. */
+constexpr int32_t DISTANCE_SKIP_SCRIPT = 0x80;
+/** Distance value bit flag, set by trieNext(). */
+constexpr int32_t DISTANCE_IS_FINAL = 0x100;
+constexpr int32_t DISTANCE_IS_FINAL_OR_SKIP_SCRIPT = DISTANCE_IS_FINAL | DISTANCE_SKIP_SCRIPT;
+
+constexpr int32_t ABOVE_THRESHOLD = 100;
+
+// Indexes into array of distances.
+enum {
+ IX_DEF_LANG_DISTANCE,
+ IX_DEF_SCRIPT_DISTANCE,
+ IX_DEF_REGION_DISTANCE,
+ IX_MIN_REGION_DISTANCE,
+ IX_LIMIT
+};
+
+LocaleDistance *gLocaleDistance = nullptr;
+UInitOnce gInitOnce = U_INITONCE_INITIALIZER;
+
+UBool U_CALLCONV cleanup() {
+ delete gLocaleDistance;
+ gLocaleDistance = nullptr;
+ gInitOnce.reset();
+ return TRUE;
+}
+
+} // namespace
+
+void U_CALLCONV LocaleDistance::initLocaleDistance(UErrorCode &errorCode) {
+ // This function is invoked only via umtx_initOnce().
+ U_ASSERT(gLocaleDistance == nullptr);
+ const XLikelySubtags &likely = *XLikelySubtags::getSingleton(errorCode);
+ if (U_FAILURE(errorCode)) { return; }
+ const LocaleDistanceData &data = likely.getDistanceData();
+ if (data.distanceTrieBytes == nullptr ||
+ data.regionToPartitions == nullptr || data.partitions == nullptr ||
+ // ok if no paradigms
+ data.distances == nullptr) {
+ errorCode = U_MISSING_RESOURCE_ERROR;
+ return;
+ }
+ gLocaleDistance = new LocaleDistance(data);
+ if (gLocaleDistance == nullptr) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ ucln_common_registerCleanup(UCLN_COMMON_LOCALE_DISTANCE, cleanup);
+}
+
+const LocaleDistance *LocaleDistance::getSingleton(UErrorCode &errorCode) {
+ if (U_FAILURE(errorCode)) { return nullptr; }
+ umtx_initOnce(gInitOnce, &LocaleDistance::initLocaleDistance, errorCode);
+ return gLocaleDistance;
+}
+
+LocaleDistance::LocaleDistance(const LocaleDistanceData &data) :
+ trie(data.distanceTrieBytes),
+ regionToPartitionsIndex(data.regionToPartitions), partitionArrays(data.partitions),
+ paradigmLSRs(data.paradigms), paradigmLSRsLength(data.paradigmsLength),
+ defaultLanguageDistance(data.distances[IX_DEF_LANG_DISTANCE]),
+ defaultScriptDistance(data.distances[IX_DEF_SCRIPT_DISTANCE]),
+ defaultRegionDistance(data.distances[IX_DEF_REGION_DISTANCE]),
+ minRegionDistance(data.distances[IX_MIN_REGION_DISTANCE]) {
+ // For the default demotion value, use the
+ // default region distance between unrelated Englishes.
+ // Thus, unless demotion is turned off,
+ // a mere region difference for one desired locale
+ // is as good as a perfect match for the next following desired locale.
+ // As of CLDR 36, we have <languageMatch desired="en_*_*" supported="en_*_*" distance="5"/>.
+ LSR en("en", "Latn", "US");
+ LSR enGB("en", "Latn", "GB");
+ const LSR *p_enGB = &enGB;
+ defaultDemotionPerDesiredLocale = getBestIndexAndDistance(en, &p_enGB, 1,
+ 50, ULOCMATCH_FAVOR_LANGUAGE) & 0xff;
+}
+
+int32_t LocaleDistance::getBestIndexAndDistance(
+ const LSR &desired,
+ const LSR **supportedLSRs, int32_t supportedLSRsLength,
+ int32_t threshold, ULocMatchFavorSubtag favorSubtag) const {
+ BytesTrie iter(trie);
+ // Look up the desired language only once for all supported LSRs.
+ // Its "distance" is either a match point value of 0, or a non-match negative value.
+ // Note: The data builder verifies that there are no <*, supported> or <desired, *> rules.
+ int32_t desLangDistance = trieNext(iter, desired.language, false);
+ uint64_t desLangState = desLangDistance >= 0 && supportedLSRsLength > 1 ? iter.getState64() : 0;
+ // Index of the supported LSR with the lowest distance.
+ int32_t bestIndex = -1;
+ for (int32_t slIndex = 0; slIndex < supportedLSRsLength; ++slIndex) {
+ const LSR &supported = *supportedLSRs[slIndex];
+ bool star = false;
+ int32_t distance = desLangDistance;
+ if (distance >= 0) {
+ U_ASSERT((distance & DISTANCE_IS_FINAL) == 0);
+ if (slIndex != 0) {
+ iter.resetToState64(desLangState);
+ }
+ distance = trieNext(iter, supported.language, true);
+ }
+ // Note: The data builder verifies that there are no rules with "any" (*) language and
+ // real (non *) script or region subtags.
+ // This means that if the lookup for either language fails we can use
+ // the default distances without further lookups.
+ int32_t flags;
+ if (distance >= 0) {
+ flags = distance & DISTANCE_IS_FINAL_OR_SKIP_SCRIPT;
+ distance &= ~DISTANCE_IS_FINAL_OR_SKIP_SCRIPT;
+ } else { // <*, *>
+ if (uprv_strcmp(desired.language, supported.language) == 0) {
+ distance = 0;
+ } else {
+ distance = defaultLanguageDistance;
+ }
+ flags = 0;
+ star = true;
+ }
+ U_ASSERT(0 <= distance && distance <= 100);
+ // We implement "favor subtag" by reducing the language subtag distance
+ // (unscientifically reducing it to a quarter of the normal value),
+ // so that the script distance is relatively more important.
+ // For example, given a default language distance of 80, we reduce it to 20,
+ // which is below the default threshold of 50, which is the default script distance.
+ if (favorSubtag == ULOCMATCH_FAVOR_SCRIPT) {
+ distance >>= 2;
+ }
+ if (distance >= threshold) {
+ continue;
+ }
+
+ int32_t scriptDistance;
+ if (star || flags != 0) {
+ if (uprv_strcmp(desired.script, supported.script) == 0) {
+ scriptDistance = 0;
+ } else {
+ scriptDistance = defaultScriptDistance;
+ }
+ } else {
+ scriptDistance = getDesSuppScriptDistance(iter, iter.getState64(),
+ desired.script, supported.script);
+ flags = scriptDistance & DISTANCE_IS_FINAL;
+ scriptDistance &= ~DISTANCE_IS_FINAL;
+ }
+ distance += scriptDistance;
+ if (distance >= threshold) {
+ continue;
+ }
+
+ if (uprv_strcmp(desired.region, supported.region) == 0) {
+ // regionDistance = 0
+ } else if (star || (flags & DISTANCE_IS_FINAL) != 0) {
+ distance += defaultRegionDistance;
+ } else {
+ int32_t remainingThreshold = threshold - distance;
+ if (minRegionDistance >= remainingThreshold) {
+ continue;
+ }
+
+ // From here on we know the regions are not equal.
+ // Map each region to zero or more partitions. (zero = one non-matching string)
+ // (Each array of single-character partition strings is encoded as one string.)
+ // If either side has more than one, then we find the maximum distance.
+ // This could be optimized by adding some more structure, but probably not worth it.
+ distance += getRegionPartitionsDistance(
+ iter, iter.getState64(),
+ partitionsForRegion(desired),
+ partitionsForRegion(supported),
+ remainingThreshold);
+ }
+ if (distance < threshold) {
+ if (distance == 0) {
+ return slIndex << 8;
+ }
+ bestIndex = slIndex;
+ threshold = distance;
+ }
+ }
+ return bestIndex >= 0 ? (bestIndex << 8) | threshold : 0xffffff00 | ABOVE_THRESHOLD;
+}
+
+int32_t LocaleDistance::getDesSuppScriptDistance(
+ BytesTrie &iter, uint64_t startState, const char *desired, const char *supported) {
+ // Note: The data builder verifies that there are no <*, supported> or <desired, *> rules.
+ int32_t distance = trieNext(iter, desired, false);
+ if (distance >= 0) {
+ distance = trieNext(iter, supported, true);
+ }
+ if (distance < 0) {
+ UStringTrieResult result = iter.resetToState64(startState).next(u'*'); // <*, *>
+ U_ASSERT(USTRINGTRIE_HAS_VALUE(result));
+ if (uprv_strcmp(desired, supported) == 0) {
+ distance = 0; // same script
+ } else {
+ distance = iter.getValue();
+ U_ASSERT(distance >= 0);
+ }
+ if (result == USTRINGTRIE_FINAL_VALUE) {
+ distance |= DISTANCE_IS_FINAL;
+ }
+ }
+ return distance;
+}
+
+int32_t LocaleDistance::getRegionPartitionsDistance(
+ BytesTrie &iter, uint64_t startState,
+ const char *desiredPartitions, const char *supportedPartitions, int32_t threshold) {
+ char desired = *desiredPartitions++;
+ char supported = *supportedPartitions++;
+ U_ASSERT(desired != 0 && supported != 0);
+ // See if we have single desired/supported partitions, from NUL-terminated
+ // partition strings without explicit length.
+ bool suppLengthGt1 = *supportedPartitions != 0; // gt1: more than 1 character
+ // equivalent to: if (desLength == 1 && suppLength == 1)
+ if (*desiredPartitions == 0 && !suppLengthGt1) {
+ // Fastpath for single desired/supported partitions.
+ UStringTrieResult result = iter.next(uprv_invCharToAscii(desired) | END_OF_SUBTAG);
+ if (USTRINGTRIE_HAS_NEXT(result)) {
+ result = iter.next(uprv_invCharToAscii(supported) | END_OF_SUBTAG);
+ if (USTRINGTRIE_HAS_VALUE(result)) {
+ return iter.getValue();
+ }
+ }
+ return getFallbackRegionDistance(iter, startState);
+ }
+
+ const char *supportedStart = supportedPartitions - 1; // for restart of inner loop
+ int32_t regionDistance = 0;
+ // Fall back to * only once, not for each pair of partition strings.
+ bool star = false;
+ for (;;) {
+ // Look up each desired-partition string only once,
+ // not for each (desired, supported) pair.
+ UStringTrieResult result = iter.next(uprv_invCharToAscii(desired) | END_OF_SUBTAG);
+ if (USTRINGTRIE_HAS_NEXT(result)) {
+ uint64_t desState = suppLengthGt1 ? iter.getState64() : 0;
+ for (;;) {
+ result = iter.next(uprv_invCharToAscii(supported) | END_OF_SUBTAG);
+ int32_t d;
+ if (USTRINGTRIE_HAS_VALUE(result)) {
+ d = iter.getValue();
+ } else if (star) {
+ d = 0;
+ } else {
+ d = getFallbackRegionDistance(iter, startState);
+ star = true;
+ }
+ if (d >= threshold) {
+ return d;
+ } else if (regionDistance < d) {
+ regionDistance = d;
+ }
+ if ((supported = *supportedPartitions++) != 0) {
+ iter.resetToState64(desState);
+ } else {
+ break;
+ }
+ }
+ } else if (!star) {
+ int32_t d = getFallbackRegionDistance(iter, startState);
+ if (d >= threshold) {
+ return d;
+ } else if (regionDistance < d) {
+ regionDistance = d;
+ }
+ star = true;
+ }
+ if ((desired = *desiredPartitions++) != 0) {
+ iter.resetToState64(startState);
+ supportedPartitions = supportedStart;
+ supported = *supportedPartitions++;
+ } else {
+ break;
+ }
+ }
+ return regionDistance;
+}
+
+int32_t LocaleDistance::getFallbackRegionDistance(BytesTrie &iter, uint64_t startState) {
+#if U_DEBUG
+ UStringTrieResult result =
+#endif
+ iter.resetToState64(startState).next(u'*'); // <*, *>
+ U_ASSERT(USTRINGTRIE_HAS_VALUE(result));
+ int32_t distance = iter.getValue();
+ U_ASSERT(distance >= 0);
+ return distance;
+}
+
+int32_t LocaleDistance::trieNext(BytesTrie &iter, const char *s, bool wantValue) {
+ uint8_t c;
+ if ((c = *s) == 0) {
+ return -1; // no empty subtags in the distance data
+ }
+ for (;;) {
+ c = uprv_invCharToAscii(c);
+ // EBCDIC: If *s is not an invariant character,
+ // then c is now 0 and will simply not match anything, which is harmless.
+ uint8_t next = *++s;
+ if (next != 0) {
+ if (!USTRINGTRIE_HAS_NEXT(iter.next(c))) {
+ return -1;
+ }
+ } else {
+ // last character of this subtag
+ UStringTrieResult result = iter.next(c | END_OF_SUBTAG);
+ if (wantValue) {
+ if (USTRINGTRIE_HAS_VALUE(result)) {
+ int32_t value = iter.getValue();
+ if (result == USTRINGTRIE_FINAL_VALUE) {
+ value |= DISTANCE_IS_FINAL;
+ }
+ return value;
+ }
+ } else {
+ if (USTRINGTRIE_HAS_NEXT(result)) {
+ return 0;
+ }
+ }
+ return -1;
+ }
+ c = next;
+ }
+}
+
+UBool LocaleDistance::isParadigmLSR(const LSR &lsr) const {
+ // Linear search for a very short list (length 6 as of 2019).
+ // If there are many paradigm LSRs we should use a hash set.
+ U_ASSERT(paradigmLSRsLength <= 15);
+ for (int32_t i = 0; i < paradigmLSRsLength; ++i) {
+ if (lsr == paradigmLSRs[i]) { return true; }
+ }
+ return false;
+}
+
+U_NAMESPACE_END
diff --git a/deps/icu-small/source/common/locdistance.h b/deps/icu-small/source/common/locdistance.h
new file mode 100644
index 0000000000..7439f51c56
--- /dev/null
+++ b/deps/icu-small/source/common/locdistance.h
@@ -0,0 +1,109 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+
+// locdistance.h
+// created: 2019may08 Markus W. Scherer
+
+#ifndef __LOCDISTANCE_H__
+#define __LOCDISTANCE_H__
+
+#include "unicode/utypes.h"
+#include "unicode/bytestrie.h"
+#include "unicode/localematcher.h"
+#include "unicode/locid.h"
+#include "unicode/uobject.h"
+#include "lsr.h"
+
+U_NAMESPACE_BEGIN
+
+struct LocaleDistanceData;
+
+/**
+ * Offline-built data for LocaleMatcher.
+ * Mostly but not only the data for mapping locales to their maximized forms.
+ */
+class LocaleDistance final : public UMemory {
+public:
+ static const LocaleDistance *getSingleton(UErrorCode &errorCode);
+
+ /**
+ * Finds the supported LSR with the smallest distance from the desired one.
+ * Equivalent LSR subtags must be normalized into a canonical form.
+ *
+ * <p>Returns the index of the lowest-distance supported LSR in bits 31..8
+ * (negative if none has a distance below the threshold),
+ * and its distance (0..ABOVE_THRESHOLD) in bits 7..0.
+ */
+ int32_t getBestIndexAndDistance(const LSR &desired,
+ const LSR **supportedLSRs, int32_t supportedLSRsLength,
+ int32_t threshold, ULocMatchFavorSubtag favorSubtag) const;
+
+ int32_t getParadigmLSRsLength() const { return paradigmLSRsLength; }
+
+ UBool isParadigmLSR(const LSR &lsr) const;
+
+ int32_t getDefaultScriptDistance() const {
+ return defaultScriptDistance;
+ }
+
+ int32_t getDefaultDemotionPerDesiredLocale() const {
+ return defaultDemotionPerDesiredLocale;
+ }
+
+private:
+ LocaleDistance(const LocaleDistanceData &data);
+ LocaleDistance(const LocaleDistance &other) = delete;
+ LocaleDistance &operator=(const LocaleDistance &other) = delete;
+
+ static void initLocaleDistance(UErrorCode &errorCode);
+
+ static int32_t getDesSuppScriptDistance(BytesTrie &iter, uint64_t startState,
+ const char *desired, const char *supported);
+
+ static int32_t getRegionPartitionsDistance(
+ BytesTrie &iter, uint64_t startState,
+ const char *desiredPartitions, const char *supportedPartitions,
+ int32_t threshold);
+
+ static int32_t getFallbackRegionDistance(BytesTrie &iter, uint64_t startState);
+
+ static int32_t trieNext(BytesTrie &iter, const char *s, bool wantValue);
+
+ const char *partitionsForRegion(const LSR &lsr) const {
+ // ill-formed region -> one non-matching string
+ int32_t pIndex = regionToPartitionsIndex[lsr.regionIndex];
+ return partitionArrays[pIndex];
+ }
+
+ int32_t getDefaultRegionDistance() const {
+ return defaultRegionDistance;
+ }
+
+ // The trie maps each dlang+slang+dscript+sscript+dregion+sregion
+ // (encoded in ASCII with bit 7 set on the last character of each subtag) to a distance.
+ // There is also a trie value for each subsequence of whole subtags.
+ // One '*' is used for a (desired, supported) pair of "und", "Zzzz"/"", or "ZZ"/"".
+ BytesTrie trie;
+
+ /**
+ * Maps each region to zero or more single-character partitions.
+ */
+ const uint8_t *regionToPartitionsIndex;
+ const char **partitionArrays;
+
+ /**
+ * Used to get the paradigm region for a cluster, if there is one.
+ */
+ const LSR *paradigmLSRs;
+ int32_t paradigmLSRsLength;
+
+ int32_t defaultLanguageDistance;
+ int32_t defaultScriptDistance;
+ int32_t defaultRegionDistance;
+ int32_t minRegionDistance;
+ int32_t defaultDemotionPerDesiredLocale;
+};
+
+U_NAMESPACE_END
+
+#endif // __LOCDISTANCE_H__
diff --git a/deps/icu-small/source/common/locdspnm.cpp b/deps/icu-small/source/common/locdspnm.cpp
index da35be9e76..43334f5196 100644
--- a/deps/icu-small/source/common/locdspnm.cpp
+++ b/deps/icu-small/source/common/locdspnm.cpp
@@ -291,6 +291,7 @@ class LocaleDisplayNamesImpl : public LocaleDisplayNames {
UnicodeString formatCloseParen;
UnicodeString formatReplaceCloseParen;
UDisplayContext nameLength;
+ UDisplayContext substitute;
// Constants for capitalization context usage types.
enum CapContextUsage {
@@ -337,7 +338,7 @@ public:
UnicodeString& result) const;
private:
UnicodeString& localeIdName(const char* localeId,
- UnicodeString& result) const;
+ UnicodeString& result, bool substitute) const;
UnicodeString& appendWithSep(UnicodeString& buffer, const UnicodeString& src) const;
UnicodeString& adjustForUsageAndContext(CapContextUsage usage, UnicodeString& result) const;
UnicodeString& scriptDisplayName(const char* script, UnicodeString& result, UBool skipAdjust) const;
@@ -359,6 +360,7 @@ LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
, capitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
, capitalizationBrkIter(NULL)
, nameLength(UDISPCTX_LENGTH_FULL)
+ , substitute(UDISPCTX_SUBSTITUTE)
{
initialize();
}
@@ -371,6 +373,7 @@ LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
, capitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
, capitalizationBrkIter(NULL)
, nameLength(UDISPCTX_LENGTH_FULL)
+ , substitute(UDISPCTX_SUBSTITUTE)
{
while (length-- > 0) {
UDisplayContext value = *contexts++;
@@ -385,6 +388,9 @@ LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
case UDISPCTX_TYPE_DISPLAY_LENGTH:
nameLength = value;
break;
+ case UDISPCTX_TYPE_SUBSTITUTE_HANDLING:
+ substitute = value;
+ break;
default:
break;
}
@@ -535,6 +541,8 @@ LocaleDisplayNamesImpl::getContext(UDisplayContextType type) const {
return capitalizationContext;
case UDISPCTX_TYPE_DISPLAY_LENGTH:
return nameLength;
+ case UDISPCTX_TYPE_SUBSTITUTE_HANDLING:
+ return substitute;
default:
break;
}
@@ -549,7 +557,7 @@ LocaleDisplayNamesImpl::adjustForUsageAndContext(CapContextUsage usage,
if ( result.length() > 0 && u_islower(result.char32At(0)) && capitalizationBrkIter!= NULL &&
( capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE || fCapitalization[usage] ) ) {
// note fCapitalization[usage] won't be set unless capitalizationContext is UI_LIST_OR_MENU or STANDALONE
- static UMutex capitalizationBrkIterLock = U_MUTEX_INITIALIZER;
+ static UMutex capitalizationBrkIterLock;
Mutex lock(&capitalizationBrkIterLock);
result.toTitle(capitalizationBrkIter, locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
}
@@ -583,7 +591,7 @@ LocaleDisplayNamesImpl::localeDisplayName(const Locale& loc,
do { // loop construct is so we can break early out of search
if (hasScript && hasCountry) {
ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, "_", country, (char *)0);
- localeIdName(buffer, resultName);
+ localeIdName(buffer, resultName, false);
if (!resultName.isBogus()) {
hasScript = FALSE;
hasCountry = FALSE;
@@ -592,7 +600,7 @@ LocaleDisplayNamesImpl::localeDisplayName(const Locale& loc,
}
if (hasScript) {
ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, (char *)0);
- localeIdName(buffer, resultName);
+ localeIdName(buffer, resultName, false);
if (!resultName.isBogus()) {
hasScript = FALSE;
break;
@@ -600,7 +608,7 @@ LocaleDisplayNamesImpl::localeDisplayName(const Locale& loc,
}
if (hasCountry) {
ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", country, (char*)0);
- localeIdName(buffer, resultName);
+ localeIdName(buffer, resultName, false);
if (!resultName.isBogus()) {
hasCountry = FALSE;
break;
@@ -609,7 +617,11 @@ LocaleDisplayNamesImpl::localeDisplayName(const Locale& loc,
} while (FALSE);
}
if (resultName.isBogus() || resultName.isEmpty()) {
- localeIdName(lang, resultName);
+ localeIdName(lang, resultName, substitute == UDISPCTX_SUBSTITUTE);
+ if (resultName.isBogus()) {
+ result.setToBogus();
+ return result;
+ }
}
UnicodeString resultRemainder;
@@ -617,13 +629,28 @@ LocaleDisplayNamesImpl::localeDisplayName(const Locale& loc,
UErrorCode status = U_ZERO_ERROR;
if (hasScript) {
- resultRemainder.append(scriptDisplayName(script, temp, TRUE));
+ UnicodeString script_str = scriptDisplayName(script, temp, TRUE);
+ if (script_str.isBogus()) {
+ result.setToBogus();
+ return result;
+ }
+ resultRemainder.append(script_str);
}
if (hasCountry) {
- appendWithSep(resultRemainder, regionDisplayName(country, temp, TRUE));
+ UnicodeString region_str = regionDisplayName(country, temp, TRUE);
+ if (region_str.isBogus()) {
+ result.setToBogus();
+ return result;
+ }
+ appendWithSep(resultRemainder, region_str);
}
if (hasVariant) {
- appendWithSep(resultRemainder, variantDisplayName(variant, temp, TRUE));
+ UnicodeString variant_str = variantDisplayName(variant, temp, TRUE);
+ if (variant_str.isBogus()) {
+ result.setToBogus();
+ return result;
+ }
+ appendWithSep(resultRemainder, variant_str);
}
resultRemainder.findAndReplace(formatOpenParen, formatReplaceOpenParen);
resultRemainder.findAndReplace(formatCloseParen, formatReplaceCloseParen);
@@ -689,14 +716,18 @@ LocaleDisplayNamesImpl::localeDisplayName(const char* localeId,
// private
UnicodeString&
LocaleDisplayNamesImpl::localeIdName(const char* localeId,
- UnicodeString& result) const {
+ UnicodeString& result, bool substitute) const {
if (nameLength == UDISPCTX_LENGTH_SHORT) {
langData.getNoFallback("Languages%short", localeId, result);
if (!result.isBogus()) {
return result;
}
}
- return langData.getNoFallback("Languages", localeId, result);
+ if (substitute) {
+ return langData.get("Languages", localeId, result);
+ } else {
+ return langData.getNoFallback("Languages", localeId, result);
+ }
}
UnicodeString&
@@ -706,12 +737,16 @@ LocaleDisplayNamesImpl::languageDisplayName(const char* lang,
return result = UnicodeString(lang, -1, US_INV);
}
if (nameLength == UDISPCTX_LENGTH_SHORT) {
- langData.get("Languages%short", lang, result);
+ langData.getNoFallback("Languages%short", lang, result);
if (!result.isBogus()) {
return adjustForUsageAndContext(kCapContextUsageLanguage, result);
}
}
- langData.get("Languages", lang, result);
+ if (substitute == UDISPCTX_SUBSTITUTE) {
+ langData.get("Languages", lang, result);
+ } else {
+ langData.getNoFallback("Languages", lang, result);
+ }
return adjustForUsageAndContext(kCapContextUsageLanguage, result);
}
@@ -720,12 +755,16 @@ LocaleDisplayNamesImpl::scriptDisplayName(const char* script,
UnicodeString& result,
UBool skipAdjust) const {
if (nameLength == UDISPCTX_LENGTH_SHORT) {
- langData.get("Scripts%short", script, result);
+ langData.getNoFallback("Scripts%short", script, result);
if (!result.isBogus()) {
return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageScript, result);
}
}
- langData.get("Scripts", script, result);
+ if (substitute == UDISPCTX_SUBSTITUTE) {
+ langData.get("Scripts", script, result);
+ } else {
+ langData.getNoFallback("Scripts", script, result);
+ }
return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageScript, result);
}
@@ -746,12 +785,16 @@ LocaleDisplayNamesImpl::regionDisplayName(const char* region,
UnicodeString& result,
UBool skipAdjust) const {
if (nameLength == UDISPCTX_LENGTH_SHORT) {
- regionData.get("Countries%short", region, result);
+ regionData.getNoFallback("Countries%short", region, result);
if (!result.isBogus()) {
return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageTerritory, result);
}
}
- regionData.get("Countries", region, result);
+ if (substitute == UDISPCTX_SUBSTITUTE) {
+ regionData.get("Countries", region, result);
+ } else {
+ regionData.getNoFallback("Countries", region, result);
+ }
return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageTerritory, result);
}
@@ -767,7 +810,11 @@ LocaleDisplayNamesImpl::variantDisplayName(const char* variant,
UnicodeString& result,
UBool skipAdjust) const {
// don't have a resource for short variant names
- langData.get("Variants", variant, result);
+ if (substitute == UDISPCTX_SUBSTITUTE) {
+ langData.get("Variants", variant, result);
+ } else {
+ langData.getNoFallback("Variants", variant, result);
+ }
return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageVariant, result);
}
@@ -782,7 +829,11 @@ LocaleDisplayNamesImpl::keyDisplayName(const char* key,
UnicodeString& result,
UBool skipAdjust) const {
// don't have a resource for short key names
- langData.get("Keys", key, result);
+ if (substitute == UDISPCTX_SUBSTITUTE) {
+ langData.get("Keys", key, result);
+ } else {
+ langData.getNoFallback("Keys", key, result);
+ }
return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageKey, result);
}
@@ -802,9 +853,8 @@ LocaleDisplayNamesImpl::keyValueDisplayName(const char* key,
UErrorCode sts = U_ZERO_ERROR;
UnicodeString ustrValue(value, -1, US_INV);
int32_t len;
- UBool isChoice = FALSE;
const UChar *currencyName = ucurr_getName(ustrValue.getTerminatedBuffer(),
- locale.getBaseName(), UCURR_LONG_NAME, &isChoice, &len, &sts);
+ locale.getBaseName(), UCURR_LONG_NAME, nullptr /* isChoiceFormat */, &len, &sts);
if (U_FAILURE(sts)) {
// Return the value as is on failure
result = ustrValue;
@@ -815,12 +865,16 @@ LocaleDisplayNamesImpl::keyValueDisplayName(const char* key,
}
if (nameLength == UDISPCTX_LENGTH_SHORT) {
- langData.get("Types%short", key, value, result);
+ langData.getNoFallback("Types%short", key, value, result);
if (!result.isBogus()) {
return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageKeyValue, result);
}
}
- langData.get("Types", key, value, result);
+ if (substitute == UDISPCTX_SUBSTITUTE) {
+ langData.get("Types", key, value, result);
+ } else {
+ langData.getNoFallback("Types", key, value, result);
+ }
return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageKeyValue, result);
}
diff --git a/deps/icu-small/source/common/locid.cpp b/deps/icu-small/source/common/locid.cpp
index 06986b636a..c6d3f88fc3 100644
--- a/deps/icu-small/source/common/locid.cpp
+++ b/deps/icu-small/source/common/locid.cpp
@@ -38,19 +38,19 @@
#include "unicode/strenum.h"
#include "unicode/stringpiece.h"
#include "unicode/uloc.h"
-#include "putilimp.h"
-#include "mutex.h"
-#include "umutex.h"
-#include "uassert.h"
+
+#include "bytesinkutil.h"
+#include "charstr.h"
#include "cmemory.h"
#include "cstring.h"
+#include "mutex.h"
+#include "putilimp.h"
#include "uassert.h"
+#include "ucln_cmn.h"
#include "uhash.h"
#include "ulocimp.h"
-#include "ucln_cmn.h"
+#include "umutex.h"
#include "ustr_imp.h"
-#include "charstr.h"
-#include "bytesinkutil.h"
U_CDECL_BEGIN
static UBool U_CALLCONV locale_cleanup(void);
@@ -62,10 +62,7 @@ static Locale *gLocaleCache = NULL;
static UInitOnce gLocaleCacheInitOnce = U_INITONCE_INITIALIZER;
// gDefaultLocaleMutex protects all access to gDefaultLocalesHashT and gDefaultLocale.
-static UMutex *gDefaultLocaleMutex() {
- static UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static UMutex gDefaultLocaleMutex;
static UHashtable *gDefaultLocalesHashT = NULL;
static Locale *gDefaultLocale = NULL;
@@ -174,7 +171,7 @@ U_NAMESPACE_BEGIN
Locale *locale_set_default_internal(const char *id, UErrorCode& status) {
// Synchronize this entire function.
- Mutex lock(gDefaultLocaleMutex());
+ Mutex lock(&gDefaultLocaleMutex);
UBool canonicalize = FALSE;
@@ -711,7 +708,7 @@ const Locale& U_EXPORT2
Locale::getDefault()
{
{
- Mutex lock(gDefaultLocaleMutex());
+ Mutex lock(&gDefaultLocaleMutex);
if (gDefaultLocale != NULL) {
return *gDefaultLocale;
}
@@ -1399,5 +1396,7 @@ Locale::getBaseName() const {
return baseName;
}
+Locale::Iterator::~Iterator() = default;
+
//eof
U_NAMESPACE_END
diff --git a/deps/icu-small/source/common/loclikely.cpp b/deps/icu-small/source/common/loclikely.cpp
index 50cc2a65de..3b71708e54 100644
--- a/deps/icu-small/source/common/loclikely.cpp
+++ b/deps/icu-small/source/common/loclikely.cpp
@@ -807,24 +807,24 @@ error:
return FALSE;
}
-#define CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength) \
- { int32_t count = 0; \
- int32_t i; \
- for (i = 0; i < trailingLength; i++) { \
- if (trailing[i] == '-' || trailing[i] == '_') { \
- count = 0; \
- if (count > 8) { \
- goto error; \
- } \
- } else if (trailing[i] == '@') { \
- break; \
- } else if (count > 8) { \
+#define CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength) UPRV_BLOCK_MACRO_BEGIN { \
+ int32_t count = 0; \
+ int32_t i; \
+ for (i = 0; i < trailingLength; i++) { \
+ if (trailing[i] == '-' || trailing[i] == '_') { \
+ count = 0; \
+ if (count > 8) { \
goto error; \
- } else { \
- count++; \
} \
+ } else if (trailing[i] == '@') { \
+ break; \
+ } else if (count > 8) { \
+ goto error; \
+ } else { \
+ count++; \
} \
- }
+ } \
+} UPRV_BLOCK_MACRO_END
static void
_uloc_addLikelySubtags(const char* localeID,
diff --git a/deps/icu-small/source/common/loclikelysubtags.cpp b/deps/icu-small/source/common/loclikelysubtags.cpp
new file mode 100644
index 0000000000..d7f5e124c2
--- /dev/null
+++ b/deps/icu-small/source/common/loclikelysubtags.cpp
@@ -0,0 +1,638 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+
+// loclikelysubtags.cpp
+// created: 2019may08 Markus W. Scherer
+
+#include <utility>
+#include "unicode/utypes.h"
+#include "unicode/bytestrie.h"
+#include "unicode/localpointer.h"
+#include "unicode/locid.h"
+#include "unicode/uobject.h"
+#include "unicode/ures.h"
+#include "charstr.h"
+#include "cstring.h"
+#include "loclikelysubtags.h"
+#include "lsr.h"
+#include "uassert.h"
+#include "ucln_cmn.h"
+#include "uhash.h"
+#include "uinvchar.h"
+#include "umutex.h"
+#include "uresdata.h"
+#include "uresimp.h"
+
+U_NAMESPACE_BEGIN
+
+namespace {
+
+constexpr char PSEUDO_ACCENTS_PREFIX = '\''; // -XA, -PSACCENT
+constexpr char PSEUDO_BIDI_PREFIX = '+'; // -XB, -PSBIDI
+constexpr char PSEUDO_CRACKED_PREFIX = ','; // -XC, -PSCRACK
+
+/**
+ * Stores NUL-terminated strings with duplicate elimination.
+ * Checks for unique UTF-16 string pointers and converts to invariant characters.
+ */
+class UniqueCharStrings {
+public:
+ UniqueCharStrings(UErrorCode &errorCode) : strings(nullptr) {
+ uhash_init(&map, uhash_hashUChars, uhash_compareUChars, uhash_compareLong, &errorCode);
+ if (U_FAILURE(errorCode)) { return; }
+ strings = new CharString();
+ if (strings == nullptr) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ }
+ }
+ ~UniqueCharStrings() {
+ uhash_close(&map);
+ delete strings;
+ }
+
+ /** Returns/orphans the CharString that contains all strings. */
+ CharString *orphanCharStrings() {
+ CharString *result = strings;
+ strings = nullptr;
+ return result;
+ }
+
+ /** Adds a string and returns a unique number for it. */
+ int32_t add(const UnicodeString &s, UErrorCode &errorCode) {
+ if (U_FAILURE(errorCode)) { return 0; }
+ if (isFrozen) {
+ errorCode = U_NO_WRITE_PERMISSION;
+ return 0;
+ }
+ // The string points into the resource bundle.
+ const char16_t *p = s.getBuffer();
+ int32_t oldIndex = uhash_geti(&map, p);
+ if (oldIndex != 0) { // found duplicate
+ return oldIndex;
+ }
+ // Explicit NUL terminator for the previous string.
+ // The strings object is also terminated with one implicit NUL.
+ strings->append(0, errorCode);
+ int32_t newIndex = strings->length();
+ strings->appendInvariantChars(s, errorCode);
+ uhash_puti(&map, const_cast<char16_t *>(p), newIndex, &errorCode);
+ return newIndex;
+ }
+
+ void freeze() { isFrozen = true; }
+
+ /**
+ * Returns a string pointer for its unique number, if this object is frozen.
+ * Otherwise nullptr.
+ */
+ const char *get(int32_t i) const {
+ U_ASSERT(isFrozen);
+ return isFrozen && i > 0 ? strings->data() + i : nullptr;
+ }
+
+private:
+ UHashtable map;
+ CharString *strings;
+ bool isFrozen = false;
+};
+
+} // namespace
+
+LocaleDistanceData::LocaleDistanceData(LocaleDistanceData &&data) :
+ distanceTrieBytes(data.distanceTrieBytes),
+ regionToPartitions(data.regionToPartitions),
+ partitions(data.partitions),
+ paradigms(data.paradigms), paradigmsLength(data.paradigmsLength),
+ distances(data.distances) {
+ data.partitions = nullptr;
+ data.paradigms = nullptr;
+}
+
+LocaleDistanceData::~LocaleDistanceData() {
+ uprv_free(partitions);
+ delete[] paradigms;
+}
+
+// TODO(ICU-20777): Rename to just LikelySubtagsData.
+struct XLikelySubtagsData {
+ UResourceBundle *langInfoBundle = nullptr;
+ UniqueCharStrings strings;
+ CharStringMap languageAliases;
+ CharStringMap regionAliases;
+ const uint8_t *trieBytes = nullptr;
+ LSR *lsrs = nullptr;
+ int32_t lsrsLength = 0;
+
+ LocaleDistanceData distanceData;
+
+ XLikelySubtagsData(UErrorCode &errorCode) : strings(errorCode) {}
+
+ ~XLikelySubtagsData() {
+ ures_close(langInfoBundle);
+ delete[] lsrs;
+ }
+
+ void load(UErrorCode &errorCode) {
+ langInfoBundle = ures_openDirect(nullptr, "langInfo", &errorCode);
+ if (U_FAILURE(errorCode)) { return; }
+ StackUResourceBundle stackTempBundle;
+ ResourceDataValue value;
+ ures_getValueWithFallback(langInfoBundle, "likely", stackTempBundle.getAlias(),
+ value, errorCode);
+ ResourceTable likelyTable = value.getTable(errorCode);
+ if (U_FAILURE(errorCode)) { return; }
+
+ // Read all strings in the resource bundle and convert them to invariant char *.
+ LocalMemory<int32_t> languageIndexes, regionIndexes, lsrSubtagIndexes;
+ int32_t languagesLength = 0, regionsLength = 0, lsrSubtagsLength = 0;
+ if (!readStrings(likelyTable, "languageAliases", value,
+ languageIndexes, languagesLength, errorCode) ||
+ !readStrings(likelyTable, "regionAliases", value,
+ regionIndexes, regionsLength, errorCode) ||
+ !readStrings(likelyTable, "lsrs", value,
+ lsrSubtagIndexes,lsrSubtagsLength, errorCode)) {
+ return;
+ }
+ if ((languagesLength & 1) != 0 ||
+ (regionsLength & 1) != 0 ||
+ (lsrSubtagsLength % 3) != 0) {
+ errorCode = U_INVALID_FORMAT_ERROR;
+ return;
+ }
+ if (lsrSubtagsLength == 0) {
+ errorCode = U_MISSING_RESOURCE_ERROR;
+ return;
+ }
+
+ if (!likelyTable.findValue("trie", value)) {
+ errorCode = U_MISSING_RESOURCE_ERROR;
+ return;
+ }
+ int32_t length;
+ trieBytes = value.getBinary(length, errorCode);
+ if (U_FAILURE(errorCode)) { return; }
+
+ // Also read distance/matcher data if available,
+ // to open & keep only one resource bundle pointer
+ // and to use one single UniqueCharStrings.
+ UErrorCode matchErrorCode = U_ZERO_ERROR;
+ ures_getValueWithFallback(langInfoBundle, "match", stackTempBundle.getAlias(),
+ value, matchErrorCode);
+ LocalMemory<int32_t> partitionIndexes, paradigmSubtagIndexes;
+ int32_t partitionsLength = 0, paradigmSubtagsLength = 0;
+ if (U_SUCCESS(matchErrorCode)) {
+ ResourceTable matchTable = value.getTable(errorCode);
+ if (U_FAILURE(errorCode)) { return; }
+
+ if (matchTable.findValue("trie", value)) {
+ distanceData.distanceTrieBytes = value.getBinary(length, errorCode);
+ if (U_FAILURE(errorCode)) { return; }
+ }
+
+ if (matchTable.findValue("regionToPartitions", value)) {
+ distanceData.regionToPartitions = value.getBinary(length, errorCode);
+ if (U_FAILURE(errorCode)) { return; }
+ if (length < LSR::REGION_INDEX_LIMIT) {
+ errorCode = U_INVALID_FORMAT_ERROR;
+ return;
+ }
+ }
+
+ if (!readStrings(matchTable, "partitions", value,
+ partitionIndexes, partitionsLength, errorCode) ||
+ !readStrings(matchTable, "paradigms", value,
+ paradigmSubtagIndexes, paradigmSubtagsLength, errorCode)) {
+ return;
+ }
+ if ((paradigmSubtagsLength % 3) != 0) {
+ errorCode = U_INVALID_FORMAT_ERROR;
+ return;
+ }
+
+ if (matchTable.findValue("distances", value)) {
+ distanceData.distances = value.getIntVector(length, errorCode);
+ if (U_FAILURE(errorCode)) { return; }
+ if (length < 4) { // LocaleDistance IX_LIMIT
+ errorCode = U_INVALID_FORMAT_ERROR;
+ return;
+ }
+ }
+ } else if (matchErrorCode == U_MISSING_RESOURCE_ERROR) {
+ // ok for likely subtags
+ } else { // error other than missing resource
+ errorCode = matchErrorCode;
+ return;
+ }
+
+ // Fetch & store invariant-character versions of strings
+ // only after we have collected and de-duplicated all of them.
+ strings.freeze();
+
+ languageAliases = CharStringMap(languagesLength / 2, errorCode);
+ for (int32_t i = 0; i < languagesLength; i += 2) {
+ languageAliases.put(strings.get(languageIndexes[i]),
+ strings.get(languageIndexes[i + 1]), errorCode);
+ }
+
+ regionAliases = CharStringMap(regionsLength / 2, errorCode);
+ for (int32_t i = 0; i < regionsLength; i += 2) {
+ regionAliases.put(strings.get(regionIndexes[i]),
+ strings.get(regionIndexes[i + 1]), errorCode);
+ }
+ if (U_FAILURE(errorCode)) { return; }
+
+ lsrsLength = lsrSubtagsLength / 3;
+ lsrs = new LSR[lsrsLength];
+ if (lsrs == nullptr) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ for (int32_t i = 0, j = 0; i < lsrSubtagsLength; i += 3, ++j) {
+ lsrs[j] = LSR(strings.get(lsrSubtagIndexes[i]),
+ strings.get(lsrSubtagIndexes[i + 1]),
+ strings.get(lsrSubtagIndexes[i + 2]));
+ }
+
+ if (partitionsLength > 0) {
+ distanceData.partitions = static_cast<const char **>(
+ uprv_malloc(partitionsLength * sizeof(const char *)));
+ if (distanceData.partitions == nullptr) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ for (int32_t i = 0; i < partitionsLength; ++i) {
+ distanceData.partitions[i] = strings.get(partitionIndexes[i]);
+ }
+ }
+
+ if (paradigmSubtagsLength > 0) {
+ distanceData.paradigmsLength = paradigmSubtagsLength / 3;
+ LSR *paradigms = new LSR[distanceData.paradigmsLength];
+ if (paradigms == nullptr) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ for (int32_t i = 0, j = 0; i < paradigmSubtagsLength; i += 3, ++j) {
+ paradigms[j] = LSR(strings.get(paradigmSubtagIndexes[i]),
+ strings.get(paradigmSubtagIndexes[i + 1]),
+ strings.get(paradigmSubtagIndexes[i + 2]));
+ }
+ distanceData.paradigms = paradigms;
+ }
+ }
+
+private:
+ bool readStrings(const ResourceTable &table, const char *key, ResourceValue &value,
+ LocalMemory<int32_t> &indexes, int32_t &length, UErrorCode &errorCode) {
+ if (table.findValue(key, value)) {
+ ResourceArray stringArray = value.getArray(errorCode);
+ if (U_FAILURE(errorCode)) { return false; }
+ length = stringArray.getSize();
+ if (length == 0) { return true; }
+ int32_t *rawIndexes = indexes.allocateInsteadAndCopy(length);
+ if (rawIndexes == nullptr) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ return false;
+ }
+ for (int i = 0; i < length; ++i) {
+ stringArray.getValue(i, value); // returns TRUE because i < length
+ rawIndexes[i] = strings.add(value.getUnicodeString(errorCode), errorCode);
+ if (U_FAILURE(errorCode)) { return false; }
+ }
+ }
+ return true;
+ }
+};
+
+namespace {
+
+XLikelySubtags *gLikelySubtags = nullptr;
+UInitOnce gInitOnce = U_INITONCE_INITIALIZER;
+
+UBool U_CALLCONV cleanup() {
+ delete gLikelySubtags;
+ gLikelySubtags = nullptr;
+ gInitOnce.reset();
+ return TRUE;
+}
+
+} // namespace
+
+void U_CALLCONV XLikelySubtags::initLikelySubtags(UErrorCode &errorCode) {
+ // This function is invoked only via umtx_initOnce().
+ U_ASSERT(gLikelySubtags == nullptr);
+ XLikelySubtagsData data(errorCode);
+ data.load(errorCode);
+ if (U_FAILURE(errorCode)) { return; }
+ gLikelySubtags = new XLikelySubtags(data);
+ if (gLikelySubtags == nullptr) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ ucln_common_registerCleanup(UCLN_COMMON_LIKELY_SUBTAGS, cleanup);
+}
+
+const XLikelySubtags *XLikelySubtags::getSingleton(UErrorCode &errorCode) {
+ if (U_FAILURE(errorCode)) { return nullptr; }
+ umtx_initOnce(gInitOnce, &XLikelySubtags::initLikelySubtags, errorCode);
+ return gLikelySubtags;
+}
+
+XLikelySubtags::XLikelySubtags(XLikelySubtagsData &data) :
+ langInfoBundle(data.langInfoBundle),
+ strings(data.strings.orphanCharStrings()),
+ languageAliases(std::move(data.languageAliases)),
+ regionAliases(std::move(data.regionAliases)),
+ trie(data.trieBytes),
+ lsrs(data.lsrs),
+#if U_DEBUG
+ lsrsLength(data.lsrsLength),
+#endif
+ distanceData(std::move(data.distanceData)) {
+ data.langInfoBundle = nullptr;
+ data.lsrs = nullptr;
+
+ // Cache the result of looking up language="und" encoded as "*", and "und-Zzzz" ("**").
+ UStringTrieResult result = trie.next(u'*');
+ U_ASSERT(USTRINGTRIE_HAS_NEXT(result));
+ trieUndState = trie.getState64();
+ result = trie.next(u'*');
+ U_ASSERT(USTRINGTRIE_HAS_NEXT(result));
+ trieUndZzzzState = trie.getState64();
+ result = trie.next(u'*');
+ U_ASSERT(USTRINGTRIE_HAS_VALUE(result));
+ defaultLsrIndex = trie.getValue();
+ trie.reset();
+
+ for (char16_t c = u'a'; c <= u'z'; ++c) {
+ result = trie.next(c);
+ if (result == USTRINGTRIE_NO_VALUE) {
+ trieFirstLetterStates[c - u'a'] = trie.getState64();
+ }
+ trie.reset();
+ }
+}
+
+XLikelySubtags::~XLikelySubtags() {
+ ures_close(langInfoBundle);
+ delete strings;
+ delete[] lsrs;
+}
+
+LSR XLikelySubtags::makeMaximizedLsrFrom(const Locale &locale, UErrorCode &errorCode) const {
+ const char *name = locale.getName();
+ if (uprv_isAtSign(name[0]) && name[1] == 'x' && name[2] == '=') { // name.startsWith("@x=")
+ // Private use language tag x-subtag-subtag...
+ return LSR(name, "", "");
+ }
+ return makeMaximizedLsr(locale.getLanguage(), locale.getScript(), locale.getCountry(),
+ locale.getVariant(), errorCode);
+}
+
+namespace {
+
+const char *getCanonical(const CharStringMap &aliases, const char *alias) {
+ const char *canonical = aliases.get(alias);
+ return canonical == nullptr ? alias : canonical;
+}
+
+} // namespace
+
+LSR XLikelySubtags::makeMaximizedLsr(const char *language, const char *script, const char *region,
+ const char *variant, UErrorCode &errorCode) const {
+ // Handle pseudolocales like en-XA, ar-XB, fr-PSCRACK.
+ // They should match only themselves,
+ // not other locales with what looks like the same language and script subtags.
+ char c1;
+ if (region[0] == 'X' && (c1 = region[1]) != 0 && region[2] == 0) {
+ switch (c1) {
+ case 'A':
+ return LSR(PSEUDO_ACCENTS_PREFIX, language, script, region, errorCode);
+ case 'B':
+ return LSR(PSEUDO_BIDI_PREFIX, language, script, region, errorCode);
+ case 'C':
+ return LSR(PSEUDO_CRACKED_PREFIX, language, script, region, errorCode);
+ default: // normal locale
+ break;
+ }
+ }
+
+ if (variant[0] == 'P' && variant[1] == 'S') {
+ if (uprv_strcmp(variant, "PSACCENT") == 0) {
+ return LSR(PSEUDO_ACCENTS_PREFIX, language, script,
+ *region == 0 ? "XA" : region, errorCode);
+ } else if (uprv_strcmp(variant, "PSBIDI") == 0) {
+ return LSR(PSEUDO_BIDI_PREFIX, language, script,
+ *region == 0 ? "XB" : region, errorCode);
+ } else if (uprv_strcmp(variant, "PSCRACK") == 0) {
+ return LSR(PSEUDO_CRACKED_PREFIX, language, script,
+ *region == 0 ? "XC" : region, errorCode);
+ }
+ // else normal locale
+ }
+
+ language = getCanonical(languageAliases, language);
+ // (We have no script mappings.)
+ region = getCanonical(regionAliases, region);
+ return maximize(language, script, region);
+}
+
+LSR XLikelySubtags::maximize(const char *language, const char *script, const char *region) const {
+ if (uprv_strcmp(language, "und") == 0) {
+ language = "";
+ }
+ if (uprv_strcmp(script, "Zzzz") == 0) {
+ script = "";
+ }
+ if (uprv_strcmp(region, "ZZ") == 0) {
+ region = "";
+ }
+ if (*script != 0 && *region != 0 && *language != 0) {
+ return LSR(language, script, region); // already maximized
+ }
+
+ uint32_t retainOldMask = 0;
+ BytesTrie iter(trie);
+ uint64_t state;
+ int32_t value;
+ // Small optimization: Array lookup for first language letter.
+ int32_t c0;
+ if (0 <= (c0 = uprv_lowerOrdinal(language[0])) && c0 <= 25 &&
+ language[1] != 0 && // language.length() >= 2
+ (state = trieFirstLetterStates[c0]) != 0) {
+ value = trieNext(iter.resetToState64(state), language, 1);
+ } else {
+ value = trieNext(iter, language, 0);
+ }
+ if (value >= 0) {
+ if (*language != 0) {
+ retainOldMask |= 4;
+ }
+ state = iter.getState64();
+ } else {
+ retainOldMask |= 4;
+ iter.resetToState64(trieUndState); // "und" ("*")
+ state = 0;
+ }
+
+ if (value > 0) {
+ // Intermediate or final value from just language.
+ if (value == SKIP_SCRIPT) {
+ value = 0;
+ }
+ if (*script != 0) {
+ retainOldMask |= 2;
+ }
+ } else {
+ value = trieNext(iter, script, 0);
+ if (value >= 0) {
+ if (*script != 0) {
+ retainOldMask |= 2;
+ }
+ state = iter.getState64();
+ } else {
+ retainOldMask |= 2;
+ if (state == 0) {
+ iter.resetToState64(trieUndZzzzState); // "und-Zzzz" ("**")
+ } else {
+ iter.resetToState64(state);
+ value = trieNext(iter, "", 0);
+ U_ASSERT(value >= 0);
+ state = iter.getState64();
+ }
+ }
+ }
+
+ if (value > 0) {
+ // Final value from just language or language+script.
+ if (*region != 0) {
+ retainOldMask |= 1;
+ }
+ } else {
+ value = trieNext(iter, region, 0);
+ if (value >= 0) {
+ if (*region != 0) {
+ retainOldMask |= 1;
+ }
+ } else {
+ retainOldMask |= 1;
+ if (state == 0) {
+ value = defaultLsrIndex;
+ } else {
+ iter.resetToState64(state);
+ value = trieNext(iter, "", 0);
+ U_ASSERT(value > 0);
+ }
+ }
+ }
+ U_ASSERT(value < lsrsLength);
+ const LSR &result = lsrs[value];
+
+ if (*language == 0) {
+ language = "und";
+ }
+
+ if (retainOldMask == 0) {
+ // Quickly return a copy of the lookup-result LSR
+ // without new allocation of the subtags.
+ return LSR(result.language, result.script, result.region);
+ }
+ if ((retainOldMask & 4) == 0) {
+ language = result.language;
+ }
+ if ((retainOldMask & 2) == 0) {
+ script = result.script;
+ }
+ if ((retainOldMask & 1) == 0) {
+ region = result.region;
+ }
+ return LSR(language, script, region);
+}
+
+int32_t XLikelySubtags::trieNext(BytesTrie &iter, const char *s, int32_t i) {
+ UStringTrieResult result;
+ uint8_t c;
+ if ((c = s[i]) == 0) {
+ result = iter.next(u'*');
+ } else {
+ for (;;) {
+ c = uprv_invCharToAscii(c);
+ // EBCDIC: If s[i] is not an invariant character,
+ // then c is now 0 and will simply not match anything, which is harmless.
+ uint8_t next = s[++i];
+ if (next != 0) {
+ if (!USTRINGTRIE_HAS_NEXT(iter.next(c))) {
+ return -1;
+ }
+ } else {
+ // last character of this subtag
+ result = iter.next(c | 0x80);
+ break;
+ }
+ c = next;
+ }
+ }
+ switch (result) {
+ case USTRINGTRIE_NO_MATCH: return -1;
+ case USTRINGTRIE_NO_VALUE: return 0;
+ case USTRINGTRIE_INTERMEDIATE_VALUE:
+ U_ASSERT(iter.getValue() == SKIP_SCRIPT);
+ return SKIP_SCRIPT;
+ case USTRINGTRIE_FINAL_VALUE: return iter.getValue();
+ default: return -1;
+ }
+}
+
+// TODO(ICU-20777): Switch Locale/uloc_ likely-subtags API from the old code
+// in loclikely.cpp to this new code, including activating this
+// minimizeSubtags() function. The LocaleMatcher does not minimize.
+#if 0
+LSR XLikelySubtags::minimizeSubtags(const char *languageIn, const char *scriptIn,
+ const char *regionIn, ULocale.Minimize fieldToFavor,
+ UErrorCode &errorCode) const {
+ LSR result = maximize(languageIn, scriptIn, regionIn);
+
+ // We could try just a series of checks, like:
+ // LSR result2 = addLikelySubtags(languageIn, "", "");
+ // if result.equals(result2) return result2;
+ // However, we can optimize 2 of the cases:
+ // (languageIn, "", "")
+ // (languageIn, "", regionIn)
+
+ // value00 = lookup(result.language, "", "")
+ BytesTrie iter = new BytesTrie(trie);
+ int value = trieNext(iter, result.language, 0);
+ U_ASSERT(value >= 0);
+ if (value == 0) {
+ value = trieNext(iter, "", 0);
+ U_ASSERT(value >= 0);
+ if (value == 0) {
+ value = trieNext(iter, "", 0);
+ }
+ }
+ U_ASSERT(value > 0);
+ LSR value00 = lsrs[value];
+ boolean favorRegionOk = false;
+ if (result.script.equals(value00.script)) { //script is default
+ if (result.region.equals(value00.region)) {
+ return new LSR(result.language, "", "");
+ } else if (fieldToFavor == ULocale.Minimize.FAVOR_REGION) {
+ return new LSR(result.language, "", result.region);
+ } else {
+ favorRegionOk = true;
+ }
+ }
+
+ // The last case is not as easy to optimize.
+ // Maybe do later, but for now use the straightforward code.
+ LSR result2 = maximize(languageIn, scriptIn, "");
+ if (result2.equals(result)) {
+ return new LSR(result.language, result.script, "");
+ } else if (favorRegionOk) {
+ return new LSR(result.language, "", result.region);
+ }
+ return result;
+}
+#endif
+
+U_NAMESPACE_END
diff --git a/deps/icu-small/source/common/loclikelysubtags.h b/deps/icu-small/source/common/loclikelysubtags.h
new file mode 100644
index 0000000000..8c8a08ac5e
--- /dev/null
+++ b/deps/icu-small/source/common/loclikelysubtags.h
@@ -0,0 +1,143 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+
+// loclikelysubtags.h
+// created: 2019may08 Markus W. Scherer
+
+#ifndef __LOCLIKELYSUBTAGS_H__
+#define __LOCLIKELYSUBTAGS_H__
+
+#include <utility>
+#include "unicode/utypes.h"
+#include "unicode/bytestrie.h"
+#include "unicode/locid.h"
+#include "unicode/uobject.h"
+#include "unicode/ures.h"
+#include "lsr.h"
+#include "uhash.h"
+
+U_NAMESPACE_BEGIN
+
+struct XLikelySubtagsData;
+
+/**
+ * Map of const char * keys & values.
+ * Stores pointers as is: Does not own/copy/adopt/release strings.
+ */
+class CharStringMap final : public UMemory {
+public:
+ /** Constructs an unusable non-map. */
+ CharStringMap() : map(nullptr) {}
+ CharStringMap(int32_t size, UErrorCode &errorCode) {
+ map = uhash_openSize(uhash_hashChars, uhash_compareChars, uhash_compareChars,
+ size, &errorCode);
+ }
+ CharStringMap(CharStringMap &&other) U_NOEXCEPT : map(other.map) {
+ other.map = nullptr;
+ }
+ CharStringMap(const CharStringMap &other) = delete;
+ ~CharStringMap() {
+ uhash_close(map);
+ }
+
+ CharStringMap &operator=(CharStringMap &&other) U_NOEXCEPT {
+ map = other.map;
+ other.map = nullptr;
+ return *this;
+ }
+ CharStringMap &operator=(const CharStringMap &other) = delete;
+
+ const char *get(const char *key) const { return static_cast<const char *>(uhash_get(map, key)); }
+ void put(const char *key, const char *value, UErrorCode &errorCode) {
+ uhash_put(map, const_cast<char *>(key), const_cast<char *>(value), &errorCode);
+ }
+
+private:
+ UHashtable *map;
+};
+
+struct LocaleDistanceData {
+ LocaleDistanceData() = default;
+ LocaleDistanceData(LocaleDistanceData &&data);
+ ~LocaleDistanceData();
+
+ const uint8_t *distanceTrieBytes = nullptr;
+ const uint8_t *regionToPartitions = nullptr;
+ const char **partitions = nullptr;
+ const LSR *paradigms = nullptr;
+ int32_t paradigmsLength = 0;
+ const int32_t *distances = nullptr;
+
+private:
+ LocaleDistanceData &operator=(const LocaleDistanceData &) = delete;
+};
+
+// TODO(ICU-20777): Rename to just LikelySubtags.
+class XLikelySubtags final : public UMemory {
+public:
+ ~XLikelySubtags();
+
+ static constexpr int32_t SKIP_SCRIPT = 1;
+
+ // VisibleForTesting
+ static const XLikelySubtags *getSingleton(UErrorCode &errorCode);
+
+ // VisibleForTesting
+ LSR makeMaximizedLsrFrom(const Locale &locale, UErrorCode &errorCode) const;
+
+ // TODO(ICU-20777): Switch Locale/uloc_ likely-subtags API from the old code
+ // in loclikely.cpp to this new code, including activating this
+ // minimizeSubtags() function. The LocaleMatcher does not minimize.
+#if 0
+ LSR minimizeSubtags(const char *languageIn, const char *scriptIn, const char *regionIn,
+ ULocale.Minimize fieldToFavor, UErrorCode &errorCode) const;
+#endif
+
+ // visible for LocaleDistance
+ const LocaleDistanceData &getDistanceData() const { return distanceData; }
+
+private:
+ XLikelySubtags(XLikelySubtagsData &data);
+ XLikelySubtags(const XLikelySubtags &other) = delete;
+ XLikelySubtags &operator=(const XLikelySubtags &other) = delete;
+
+ static void initLikelySubtags(UErrorCode &errorCode);
+
+ LSR makeMaximizedLsr(const char *language, const char *script, const char *region,
+ const char *variant, UErrorCode &errorCode) const;
+
+ /**
+ * Raw access to addLikelySubtags. Input must be in canonical format, eg "en", not "eng" or "EN".
+ */
+ LSR maximize(const char *language, const char *script, const char *region) const;
+
+ static int32_t trieNext(BytesTrie &iter, const char *s, int32_t i);
+
+ UResourceBundle *langInfoBundle;
+ // We could store the strings by value, except that if there were few enough strings,
+ // moving the contents could copy it to a different array,
+ // invalidating the pointers stored in the maps.
+ CharString *strings;
+ CharStringMap languageAliases;
+ CharStringMap regionAliases;
+
+ // The trie maps each lang+script+region (encoded in ASCII) to an index into lsrs.
+ // There is also a trie value for each intermediate lang and lang+script.
+ // '*' is used instead of "und", "Zzzz"/"" and "ZZ"/"".
+ BytesTrie trie;
+ uint64_t trieUndState;
+ uint64_t trieUndZzzzState;
+ int32_t defaultLsrIndex;
+ uint64_t trieFirstLetterStates[26];
+ const LSR *lsrs;
+#if U_DEBUG
+ int32_t lsrsLength;
+#endif
+
+ // distance/matcher data: see comment in XLikelySubtagsData::load()
+ LocaleDistanceData distanceData;
+};
+
+U_NAMESPACE_END
+
+#endif // __LOCLIKELYSUBTAGS_H__
diff --git a/deps/icu-small/source/common/lsr.cpp b/deps/icu-small/source/common/lsr.cpp
new file mode 100644
index 0000000000..0c28eeda1b
--- /dev/null
+++ b/deps/icu-small/source/common/lsr.cpp
@@ -0,0 +1,101 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+
+// lsr.cpp
+// created: 2019may08 Markus W. Scherer
+
+#include "unicode/utypes.h"
+#include "charstr.h"
+#include "cmemory.h"
+#include "cstring.h"
+#include "lsr.h"
+#include "uinvchar.h"
+#include "ustr_imp.h"
+
+U_NAMESPACE_BEGIN
+
+LSR::LSR(char prefix, const char *lang, const char *scr, const char *r, UErrorCode &errorCode) :
+ language(nullptr), script(nullptr), region(r),
+ regionIndex(indexForRegion(region)) {
+ if (U_SUCCESS(errorCode)) {
+ CharString langScript;
+ langScript.append(prefix, errorCode).append(lang, errorCode).append('\0', errorCode);
+ int32_t scriptOffset = langScript.length();
+ langScript.append(prefix, errorCode).append(scr, errorCode);
+ owned = langScript.cloneData(errorCode);
+ if (U_SUCCESS(errorCode)) {
+ language = owned;
+ script = owned + scriptOffset;
+ }
+ }
+}
+
+LSR::LSR(LSR &&other) U_NOEXCEPT :
+ language(other.language), script(other.script), region(other.region), owned(other.owned),
+ regionIndex(other.regionIndex), hashCode(other.hashCode) {
+ if (owned != nullptr) {
+ other.language = other.script = "";
+ other.owned = nullptr;
+ other.hashCode = 0;
+ }
+}
+
+void LSR::deleteOwned() {
+ uprv_free(owned);
+}
+
+LSR &LSR::operator=(LSR &&other) U_NOEXCEPT {
+ this->~LSR();
+ language = other.language;
+ script = other.script;
+ region = other.region;
+ regionIndex = other.regionIndex;
+ owned = other.owned;
+ hashCode = other.hashCode;
+ if (owned != nullptr) {
+ other.language = other.script = "";
+ other.owned = nullptr;
+ other.hashCode = 0;
+ }
+ return *this;
+}
+
+UBool LSR::operator==(const LSR &other) const {
+ return
+ uprv_strcmp(language, other.language) == 0 &&
+ uprv_strcmp(script, other.script) == 0 &&
+ regionIndex == other.regionIndex &&
+ // Compare regions if both are ill-formed (and their indexes are 0).
+ (regionIndex > 0 || uprv_strcmp(region, other.region) == 0);
+}
+
+int32_t LSR::indexForRegion(const char *region) {
+ int32_t c = region[0];
+ int32_t a = c - '0';
+ if (0 <= a && a <= 9) { // digits: "419"
+ int32_t b = region[1] - '0';
+ if (b < 0 || 9 < b) { return 0; }
+ c = region[2] - '0';
+ if (c < 0 || 9 < c || region[3] != 0) { return 0; }
+ return (10 * a + b) * 10 + c + 1;
+ } else { // letters: "DE"
+ a = uprv_upperOrdinal(c);
+ if (a < 0 || 25 < a) { return 0; }
+ int32_t b = uprv_upperOrdinal(region[1]);
+ if (b < 0 || 25 < b || region[2] != 0) { return 0; }
+ return 26 * a + b + 1001;
+ }
+ return 0;
+}
+
+LSR &LSR::setHashCode() {
+ if (hashCode == 0) {
+ hashCode =
+ (ustr_hashCharsN(language, static_cast<int32_t>(uprv_strlen(language))) * 37 +
+ ustr_hashCharsN(script, static_cast<int32_t>(uprv_strlen(script)))) * 37 +
+ regionIndex;
+ }
+ return *this;
+}
+
+U_NAMESPACE_END
diff --git a/deps/icu-small/source/common/lsr.h b/deps/icu-small/source/common/lsr.h
new file mode 100644
index 0000000000..db6cf938f4
--- /dev/null
+++ b/deps/icu-small/source/common/lsr.h
@@ -0,0 +1,72 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+
+// lsr.h
+// created: 2019may08 Markus W. Scherer
+
+#ifndef __LSR_H__
+#define __LSR_H__
+
+#include "unicode/utypes.h"
+#include "unicode/uobject.h"
+#include "cstring.h"
+
+U_NAMESPACE_BEGIN
+
+struct LSR final : public UMemory {
+ static constexpr int32_t REGION_INDEX_LIMIT = 1001 + 26 * 26;
+
+ const char *language;
+ const char *script;
+ const char *region;
+ char *owned = nullptr;
+ /** Index for region, 0 if ill-formed. @see indexForRegion */
+ int32_t regionIndex = 0;
+ /** Only set for LSRs that will be used in a hash table. */
+ int32_t hashCode = 0;
+
+ LSR() : language("und"), script(""), region("") {}
+
+ /** Constructor which aliases all subtag pointers. */
+ LSR(const char *lang, const char *scr, const char *r) :
+ language(lang), script(scr), region(r),
+ regionIndex(indexForRegion(region)) {}
+ /**
+ * Constructor which prepends the prefix to the language and script,
+ * copies those into owned memory, and aliases the region.
+ */
+ LSR(char prefix, const char *lang, const char *scr, const char *r, UErrorCode &errorCode);
+ LSR(LSR &&other) U_NOEXCEPT;
+ LSR(const LSR &other) = delete;
+ inline ~LSR() {
+ // Pure inline code for almost all instances.
+ if (owned != nullptr) {
+ deleteOwned();
+ }
+ }
+
+ LSR &operator=(LSR &&other) U_NOEXCEPT;
+ LSR &operator=(const LSR &other) = delete;
+
+ /**
+ * Returns a positive index (>0) for a well-formed region code.
+ * Do not rely on a particular region->index mapping; it may change.
+ * Returns 0 for ill-formed strings.
+ */
+ static int32_t indexForRegion(const char *region);
+
+ UBool operator==(const LSR &other) const;
+
+ inline UBool operator!=(const LSR &other) const {
+ return !operator==(other);
+ }
+
+ LSR &setHashCode();
+
+private:
+ void deleteOwned();
+};
+
+U_NAMESPACE_END
+
+#endif // __LSR_H__
diff --git a/deps/icu-small/source/common/mutex.h b/deps/icu-small/source/common/mutex.h
index 5223397bbc..44b1f90ba0 100644
--- a/deps/icu-small/source/common/mutex.h
+++ b/deps/icu-small/source/common/mutex.h
@@ -28,50 +28,48 @@
U_NAMESPACE_BEGIN
-//----------------------------------------------------------------------------
-// Code within that accesses shared static or global data should
-// should instantiate a Mutex object while doing so. You should make your own
-// private mutex where possible.
-
-// For example:
-//
-// UMutex myMutex = U_MUTEX_INITIALIZER;
-//
-// void Function(int arg1, int arg2)
-// {
-// static Object* foo; // Shared read-write object
-// Mutex mutex(&myMutex); // or no args for the global lock
-// foo->Method();
-// // When 'mutex' goes out of scope and gets destroyed here, the lock is released
-// }
-//
-// Note: Do NOT use the form 'Mutex mutex();' as that merely forward-declares a function
-// returning a Mutex. This is a common mistake which silently slips through the
-// compiler!!
-//
+/**
+ * Mutex is a helper class for convenient locking and unlocking of a UMutex.
+ *
+ * Creating a local scope Mutex will lock a UMutex, holding the lock until the Mutex
+ * goes out of scope.
+ *
+ * If no UMutex is specified, the ICU global mutex is implied.
+ *
+ * For example:
+ *
+ * static UMutex myMutex;
+ *
+ * void Function(int arg1, int arg2)
+ * {
+ * static Object* foo; // Shared read-write object
+ * Mutex mutex(&myMutex); // or no args for the global lock
+ * foo->Method();
+ * // When 'mutex' goes out of scope and gets destroyed here, the lock is released
+ * }
+ *
+ * Note: Do NOT use the form 'Mutex mutex();' as that merely forward-declares a function
+ * returning a Mutex. This is a common mistake which silently slips through the
+ * compiler!!
+ */
class U_COMMON_API Mutex : public UMemory {
public:
- inline Mutex(UMutex *mutex = NULL);
- inline ~Mutex();
+ Mutex(UMutex *mutex = nullptr) : fMutex(mutex) {
+ umtx_lock(fMutex);
+ }
+ ~Mutex() {
+ umtx_unlock(fMutex);
+ }
-private:
- UMutex *fMutex;
+ Mutex(const Mutex &other) = delete; // forbid assigning of this class
+ Mutex &operator=(const Mutex &other) = delete; // forbid copying of this class
+ void *operator new(size_t s) = delete; // forbid heap allocation. Locals only.
- Mutex(const Mutex &other); // forbid copying of this class
- Mutex &operator=(const Mutex &other); // forbid copying of this class
+private:
+ UMutex *fMutex;
};
-inline Mutex::Mutex(UMutex *mutex)
- : fMutex(mutex)
-{
- umtx_lock(fMutex);
-}
-
-inline Mutex::~Mutex()
-{
- umtx_unlock(fMutex);
-}
U_NAMESPACE_END
diff --git a/deps/icu-small/source/common/normalizer2impl.h b/deps/icu-small/source/common/normalizer2impl.h
index 7ecdef6d9c..cf3015ea88 100644
--- a/deps/icu-small/source/common/normalizer2impl.h
+++ b/deps/icu-small/source/common/normalizer2impl.h
@@ -245,9 +245,7 @@ private:
*/
class U_COMMON_API Normalizer2Impl : public UObject {
public:
- Normalizer2Impl() : normTrie(NULL), fCanonIterData(NULL) {
- fCanonIterDataInitOnce.reset();
- }
+ Normalizer2Impl() : normTrie(NULL), fCanonIterData(NULL) { }
virtual ~Normalizer2Impl();
void init(const int32_t *inIndexes, const UCPTrie *inTrie,
@@ -723,7 +721,7 @@ private:
const uint16_t *extraData; // mappings and/or compositions for yesYes, yesNo & noNo characters
const uint8_t *smallFCD; // [0x100] one bit per 32 BMP code points, set if any FCD!=0
- UInitOnce fCanonIterDataInitOnce;
+ UInitOnce fCanonIterDataInitOnce = U_INITONCE_INITIALIZER;
CanonIterData *fCanonIterData;
};
diff --git a/deps/icu-small/source/common/putil.cpp b/deps/icu-small/source/common/putil.cpp
index e105befc3f..207350f8f2 100644
--- a/deps/icu-small/source/common/putil.cpp
+++ b/deps/icu-small/source/common/putil.cpp
@@ -249,7 +249,7 @@ static UDate getUTCtime_real() {
}
static UDate getUTCtime_fake() {
- static UMutex fakeClockMutex = U_MUTEX_INTIALIZER;
+ static UMutex fakeClockMutex;
umtx_lock(&fakeClockMutex);
if(!fakeClock_set) {
UDate real = getUTCtime_real();
@@ -1315,11 +1315,10 @@ uprv_pathIsAbsolute(const char *path)
# endif
#endif
-#if U_PLATFORM_HAS_WINUWP_API != 0
+#if defined(ICU_DATA_DIR_WINDOWS)
// Helper function to get the ICU Data Directory under the Windows directory location.
static BOOL U_CALLCONV getIcuDataDirectoryUnderWindowsDirectory(char* directoryBuffer, UINT bufferLength)
{
-#if defined(ICU_DATA_DIR_WINDOWS)
wchar_t windowsPath[MAX_PATH];
char windowsPathUtf8[MAX_PATH];
@@ -1346,7 +1345,6 @@ static BOOL U_CALLCONV getIcuDataDirectoryUnderWindowsDirectory(char* directoryB
}
}
}
-#endif
return FALSE;
}
@@ -1380,9 +1378,9 @@ static void U_CALLCONV dataDirectoryInitFn() {
*/
# if !defined(ICU_NO_USER_DATA_OVERRIDE) && !UCONFIG_NO_FILE_IO
/* First try to get the environment variable */
-# if U_PLATFORM_HAS_WINUWP_API == 0 // Windows UWP does not support getenv
+# if U_PLATFORM_HAS_WINUWP_API == 0 // Windows UWP does not support getenv
path=getenv("ICU_DATA");
-# endif
+# endif
# endif
/* ICU_DATA_DIR may be set as a compile option.
@@ -1411,7 +1409,7 @@ static void U_CALLCONV dataDirectoryInitFn() {
}
#endif
-#if U_PLATFORM_HAS_WINUWP_API != 0 && defined(ICU_DATA_DIR_WINDOWS)
+#if defined(ICU_DATA_DIR_WINDOWS)
char datadir_path_buffer[MAX_PATH];
if (getIcuDataDirectoryUnderWindowsDirectory(datadir_path_buffer, UPRV_LENGTHOF(datadir_path_buffer))) {
path = datadir_path_buffer;
@@ -1461,12 +1459,17 @@ static void U_CALLCONV TimeZoneDataDirInitFn(UErrorCode &status) {
const char *dir = "";
-#if U_PLATFORM_HAS_WINUWP_API != 0
- // The UWP version does not support the environment variable setting, but can possibly pick them up from the Windows directory.
+#if U_PLATFORM_HAS_WINUWP_API == 1
+// The UWP version does not support the environment variable setting.
+
+# if defined(ICU_DATA_DIR_WINDOWS)
+ // When using the Windows system data, we can possibly pick up time zone data from the Windows directory.
char datadir_path_buffer[MAX_PATH];
if (getIcuDataDirectoryUnderWindowsDirectory(datadir_path_buffer, UPRV_LENGTHOF(datadir_path_buffer))) {
dir = datadir_path_buffer;
}
+# endif
+
#else
dir = getenv("ICU_TIMEZONE_FILES_DIR");
#endif // U_PLATFORM_HAS_WINUWP_API
@@ -1560,6 +1563,10 @@ static const char *uprv_getPOSIXIDForCategory(int category)
{
/* Nothing worked. Give it a nice POSIX default value. */
posixID = "en_US_POSIX";
+ // Note: this test will not catch 'C.UTF-8',
+ // that will be handled in uprv_getDefaultLocaleID().
+ // Leave this mapping here for the uprv_getPOSIXIDForDefaultCodepage()
+ // caller which expects to see "en_US_POSIX" in many branches.
}
return posixID;
}
@@ -1631,8 +1638,8 @@ The leftmost codepage (.xxx) wins.
}
// Copy the ID into owned memory.
- // Over-allocate in case we replace "@" with "__".
- char *correctedPOSIXLocale = static_cast<char *>(uprv_malloc(uprv_strlen(posixID) + 1 + 1));
+ // Over-allocate in case we replace "C" with "en_US_POSIX" (+10), + null termination
+ char *correctedPOSIXLocale = static_cast<char *>(uprv_malloc(uprv_strlen(posixID) + 10 + 1));
if (correctedPOSIXLocale == nullptr) {
return nullptr;
}
@@ -1641,9 +1648,16 @@ The leftmost codepage (.xxx) wins.
char *limit;
if ((limit = uprv_strchr(correctedPOSIXLocale, '.')) != nullptr) {
*limit = 0;
- if ((limit = uprv_strchr(correctedPOSIXLocale, '@')) != nullptr) {
- *limit = 0;
- }
+ }
+ if ((limit = uprv_strchr(correctedPOSIXLocale, '@')) != nullptr) {
+ *limit = 0;
+ }
+
+ if ((uprv_strcmp("C", correctedPOSIXLocale) == 0) // no @ variant
+ || (uprv_strcmp("POSIX", correctedPOSIXLocale) == 0)) {
+ // Raw input was C.* or POSIX.*, Give it a nice POSIX default value.
+ // (The "C"/"POSIX" case is handled in uprv_getPOSIXIDForCategory())
+ uprv_strcpy(correctedPOSIXLocale, "en_US_POSIX");
}
/* Note that we scan the *uncorrected* ID. */
@@ -1668,7 +1682,7 @@ The leftmost codepage (.xxx) wins.
if ((q = uprv_strchr(p, '.')) != nullptr) {
/* How big will the resulting string be? */
int32_t len = (int32_t)(uprv_strlen(correctedPOSIXLocale) + (q-p));
- uprv_strncat(correctedPOSIXLocale, p, q-p);
+ uprv_strncat(correctedPOSIXLocale, p, q-p); // do not include charset
correctedPOSIXLocale[len] = 0;
}
else {
@@ -2053,7 +2067,7 @@ int_getDefaultCodepage()
static char codepage[64];
DWORD codepageNumber = 0;
-#if U_PLATFORM_HAS_WINUWP_API > 0
+#if U_PLATFORM_HAS_WINUWP_API == 1
// UWP doesn't have a direct API to get the default ACP as Microsoft would rather
// have folks use Unicode than a "system" code page, however this is the same
// codepage as the system default locale codepage. (FWIW, the system locale is
diff --git a/deps/icu-small/source/common/putilimp.h b/deps/icu-small/source/common/putilimp.h
index f9c13d8e1b..2e9fbcc483 100644
--- a/deps/icu-small/source/common/putilimp.h
+++ b/deps/icu-small/source/common/putilimp.h
@@ -179,76 +179,6 @@ typedef size_t uintptr_t;
/** @} */
/*===========================================================================*/
-/** @{ GCC built in functions for atomic memory operations */
-/*===========================================================================*/
-
-/**
- * \def U_HAVE_GCC_ATOMICS
- * @internal
- */
-#ifdef U_HAVE_GCC_ATOMICS
- /* Use the predefined value. */
-#elif U_PLATFORM == U_PF_MINGW
- #define U_HAVE_GCC_ATOMICS 0
-#elif U_GCC_MAJOR_MINOR >= 404 || defined(__clang__)
- /* TODO: Intel icc and IBM xlc on AIX also support gcc atomics. (Intel originated them.)
- * Add them for these compilers.
- * Note: Clang sets __GNUC__ defines for version 4.2, so misses the 4.4 test here.
- */
-# define U_HAVE_GCC_ATOMICS 1
-#else
-# define U_HAVE_GCC_ATOMICS 0
-#endif
-
-/** @} */
-
-/**
- * \def U_HAVE_STD_ATOMICS
- * Defines whether to use the C++11 std::atomic functions.
- * If false, ICU will fall back to compiler or platform specific alternatives.
- * Note: support for these fall back options for atomics will be removed in a future version
- * of ICU, and the use of C++ 11 atomics will be required.
- * @internal
- */
-#ifdef U_HAVE_STD_ATOMICS
- /* Use the predefined value. */
-#else
-# define U_HAVE_STD_ATOMICS 1
-#endif
-
-/**
- * \def U_HAVE_CLANG_ATOMICS
- * Defines whether Clang c11 style built-in atomics are available.
- * These are used in preference to gcc atomics when both are available.
- */
-#ifdef U_HAVE_CLANG_ATOMICS
- /* Use the predefined value. */
-#elif __has_builtin(__c11_atomic_load) && \
- __has_builtin(__c11_atomic_store) && \
- __has_builtin(__c11_atomic_fetch_add) && \
- __has_builtin(__c11_atomic_fetch_sub)
-# define U_HAVE_CLANG_ATOMICS 1
-#else
-# define U_HAVE_CLANG_ATOMICS 0
-#endif
-
-
-/**
- * \def U_HAVE_STD_MUTEX
- * Defines whether to use the C++11 std::mutex functions.
- * If false, ICU will fall back to compiler or platform specific alternatives.
- * std::mutex is preferred, and used by default unless this setting is overridden.
- * Note: support for other options for mutexes will be removed in a future version
- * of ICU, and the use of std::mutex will be required.
- * @internal
- */
-#ifdef U_HAVE_STD_MUTEX
- /* Use the predefined value. */
-#else
-# define U_HAVE_STD_MUTEX 1
-#endif
-
-/*===========================================================================*/
/** @{ Programs used by ICU code */
/*===========================================================================*/
diff --git a/deps/icu-small/source/common/rbbi.cpp b/deps/icu-small/source/common/rbbi.cpp
index 3b116ffaf6..01dae48de4 100644
--- a/deps/icu-small/source/common/rbbi.cpp
+++ b/deps/icu-small/source/common/rbbi.cpp
@@ -323,8 +323,8 @@ void RuleBasedBreakIterator::init(UErrorCode &status) {
// Virtual function: does the right thing with subclasses.
//
//-----------------------------------------------------------------------------
-BreakIterator*
-RuleBasedBreakIterator::clone(void) const {
+RuleBasedBreakIterator*
+RuleBasedBreakIterator::clone() const {
return new RuleBasedBreakIterator(*this);
}
@@ -352,7 +352,7 @@ RuleBasedBreakIterator::operator==(const BreakIterator& that) const {
// or have a different iteration position.
// Note that fText's position is always the same as the break iterator's position.
return FALSE;
- };
+ }
if (!(fPosition == that2.fPosition &&
fRuleStatusIndex == that2.fRuleStatusIndex &&
@@ -1079,10 +1079,8 @@ const uint8_t *RuleBasedBreakIterator::getBinaryRules(uint32_t &length) {
}
-BreakIterator * RuleBasedBreakIterator::createBufferClone(void * /*stackBuffer*/,
- int32_t &bufferSize,
- UErrorCode &status)
-{
+RuleBasedBreakIterator *RuleBasedBreakIterator::createBufferClone(
+ void * /*stackBuffer*/, int32_t &bufferSize, UErrorCode &status) {
if (U_FAILURE(status)){
return NULL;
}
diff --git a/deps/icu-small/source/common/rbbi_cache.cpp b/deps/icu-small/source/common/rbbi_cache.cpp
index 17ee232080..4f9e83360a 100644
--- a/deps/icu-small/source/common/rbbi_cache.cpp
+++ b/deps/icu-small/source/common/rbbi_cache.cpp
@@ -519,7 +519,7 @@ UBool RuleBasedBreakIterator::BreakCache::populatePreceding(UErrorCode &status)
// The initial handleNext() only advanced by a single code point. Go again.
position = fBI->handleNext(); // Safe rules identify safe pairs.
}
- };
+ }
positionStatusIdx = fBI->fRuleStatusIndex;
}
} while (position >= fromPosition);
diff --git a/deps/icu-small/source/common/resbund.cpp b/deps/icu-small/source/common/resbund.cpp
index 00dbf6f8fe..5ec7541b4d 100644
--- a/deps/icu-small/source/common/resbund.cpp
+++ b/deps/icu-small/source/common/resbund.cpp
@@ -51,6 +51,7 @@
#include "unicode/utypes.h"
#include "unicode/resbund.h"
+#include "cmemory.h"
#include "mutex.h"
#include "uassert.h"
#include "umutex.h"
@@ -377,7 +378,7 @@ void ResourceBundle::getVersion(UVersionInfo versionInfo) const {
}
const Locale &ResourceBundle::getLocale(void) const {
- static UMutex gLocaleLock = U_MUTEX_INITIALIZER;
+ static UMutex gLocaleLock;
Mutex lock(&gLocaleLock);
if (fLocale != NULL) {
return *fLocale;
diff --git a/deps/icu-small/source/common/resource.h b/deps/icu-small/source/common/resource.h
index 3dbff785ef..5199b85888 100644
--- a/deps/icu-small/source/common/resource.h
+++ b/deps/icu-small/source/common/resource.h
@@ -28,6 +28,7 @@
#include "unicode/utypes.h"
#include "unicode/unistr.h"
#include "unicode/ures.h"
+#include "restrace.h"
struct ResourceData;
@@ -47,8 +48,10 @@ public:
ResourceArray() : items16(NULL), items32(NULL), length(0) {}
/** Only for implementation use. @internal */
- ResourceArray(const uint16_t *i16, const uint32_t *i32, int32_t len) :
- items16(i16), items32(i32), length(len) {}
+ ResourceArray(const uint16_t *i16, const uint32_t *i32, int32_t len,
+ const ResourceTracer& traceInfo) :
+ items16(i16), items32(i32), length(len),
+ fTraceInfo(traceInfo) {}
/**
* @return The number of items in the array resource.
@@ -68,6 +71,7 @@ private:
const uint16_t *items16;
const uint32_t *items32;
int32_t length;
+ ResourceTracer fTraceInfo;
};
/**
@@ -80,27 +84,37 @@ public:
/** Only for implementation use. @internal */
ResourceTable(const uint16_t *k16, const int32_t *k32,
- const uint16_t *i16, const uint32_t *i32, int32_t len) :
- keys16(k16), keys32(k32), items16(i16), items32(i32), length(len) {}
+ const uint16_t *i16, const uint32_t *i32, int32_t len,
+ const ResourceTracer& traceInfo) :
+ keys16(k16), keys32(k32), items16(i16), items32(i32), length(len),
+ fTraceInfo(traceInfo) {}
/**
* @return The number of items in the array resource.
*/
int32_t getSize() const { return length; }
/**
- * @param i Array item index.
+ * @param i Table item index.
* @param key Output-only, receives the key of the i'th item.
* @param value Output-only, receives the value of the i'th item.
* @return TRUE if i is non-negative and less than getSize().
*/
UBool getKeyAndValue(int32_t i, const char *&key, ResourceValue &value) const;
+ /**
+ * @param key Key string to find in the table.
+ * @param value Output-only, receives the value of the item with that key.
+ * @return TRUE if the table contains the key.
+ */
+ UBool findValue(const char *key, ResourceValue &value) const;
+
private:
const uint16_t *keys16;
const int32_t *keys32;
const uint16_t *items16;
const uint32_t *items32;
int32_t length;
+ ResourceTracer fTraceInfo;
};
/**
diff --git a/deps/icu-small/source/common/restrace.cpp b/deps/icu-small/source/common/restrace.cpp
new file mode 100644
index 0000000000..5c6498850e
--- /dev/null
+++ b/deps/icu-small/source/common/restrace.cpp
@@ -0,0 +1,130 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#include "unicode/utypes.h"
+
+#if U_ENABLE_TRACING
+
+#include "restrace.h"
+#include "charstr.h"
+#include "cstring.h"
+#include "utracimp.h"
+#include "uresimp.h"
+#include "uassert.h"
+#include "util.h"
+
+U_NAMESPACE_BEGIN
+
+ResourceTracer::~ResourceTracer() = default;
+
+void ResourceTracer::trace(const char* resType) const {
+ U_ASSERT(fResB || fParent);
+ UTRACE_ENTRY(UTRACE_UDATA_RESOURCE);
+ UErrorCode status = U_ZERO_ERROR;
+
+ CharString filePath;
+ getFilePath(filePath, status);
+
+ CharString resPath;
+ getResPath(resPath, status);
+
+ // The longest type ("intvector") is 9 chars
+ const char kSpaces[] = " ";
+ CharString format;
+ format.append(kSpaces, sizeof(kSpaces) - 1 - uprv_strlen(resType), status);
+ format.append("(%s) %s @ %s", status);
+
+ UTRACE_DATA3(UTRACE_VERBOSE,
+ format.data(),
+ resType,
+ filePath.data(),
+ resPath.data());
+ UTRACE_EXIT_STATUS(status);
+}
+
+void ResourceTracer::traceOpen() const {
+ U_ASSERT(fResB);
+ UTRACE_ENTRY(UTRACE_UDATA_BUNDLE);
+ UErrorCode status = U_ZERO_ERROR;
+
+ CharString filePath;
+ UTRACE_DATA1(UTRACE_VERBOSE, "%s", getFilePath(filePath, status).data());
+ UTRACE_EXIT_STATUS(status);
+}
+
+CharString& ResourceTracer::getFilePath(CharString& output, UErrorCode& status) const {
+ if (fResB) {
+ output.append(fResB->fData->fPath, status);
+ output.append('/', status);
+ output.append(fResB->fData->fName, status);
+ output.append(".res", status);
+ } else {
+ fParent->getFilePath(output, status);
+ }
+ return output;
+}
+
+CharString& ResourceTracer::getResPath(CharString& output, UErrorCode& status) const {
+ if (fResB) {
+ output.append('/', status);
+ output.append(fResB->fResPath, status);
+ // removing the trailing /
+ U_ASSERT(output[output.length()-1] == '/');
+ output.truncate(output.length()-1);
+ } else {
+ fParent->getResPath(output, status);
+ }
+ if (fKey) {
+ output.append('/', status);
+ output.append(fKey, status);
+ }
+ if (fIndex != -1) {
+ output.append('[', status);
+ UnicodeString indexString;
+ ICU_Utility::appendNumber(indexString, fIndex);
+ output.appendInvariantChars(indexString, status);
+ output.append(']', status);
+ }
+ return output;
+}
+
+void FileTracer::traceOpen(const char* path, const char* type, const char* name) {
+ if (uprv_strcmp(type, "res") == 0) {
+ traceOpenResFile(path, name);
+ } else {
+ traceOpenDataFile(path, type, name);
+ }
+}
+
+void FileTracer::traceOpenDataFile(const char* path, const char* type, const char* name) {
+ UTRACE_ENTRY(UTRACE_UDATA_DATA_FILE);
+ UErrorCode status = U_ZERO_ERROR;
+
+ CharString filePath;
+ filePath.append(path, status);
+ filePath.append('/', status);
+ filePath.append(name, status);
+ filePath.append('.', status);
+ filePath.append(type, status);
+
+ UTRACE_DATA1(UTRACE_VERBOSE, "%s", filePath.data());
+ UTRACE_EXIT_STATUS(status);
+}
+
+void FileTracer::traceOpenResFile(const char* path, const char* name) {
+ UTRACE_ENTRY(UTRACE_UDATA_RES_FILE);
+ UErrorCode status = U_ZERO_ERROR;
+
+ CharString filePath;
+ filePath.append(path, status);
+ filePath.append('/', status);
+ filePath.append(name, status);
+ filePath.append(".res", status);
+
+ UTRACE_DATA1(UTRACE_VERBOSE, "%s", filePath.data());
+ UTRACE_EXIT_STATUS(status);
+}
+
+U_NAMESPACE_END
+
+#endif // U_ENABLE_TRACING
diff --git a/deps/icu-small/source/common/restrace.h b/deps/icu-small/source/common/restrace.h
new file mode 100644
index 0000000000..ef29eaed57
--- /dev/null
+++ b/deps/icu-small/source/common/restrace.h
@@ -0,0 +1,147 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#ifndef __RESTRACE_H__
+#define __RESTRACE_H__
+
+#include "unicode/utypes.h"
+
+#if U_ENABLE_TRACING
+
+struct UResourceBundle;
+
+U_NAMESPACE_BEGIN
+
+class CharString;
+
+/**
+ * Instances of this class store information used to trace reads from resource
+ * bundles when ICU is built with --enable-tracing.
+ *
+ * All arguments of type const UResourceBundle*, const char*, and
+ * const ResourceTracer& are stored as pointers. The caller must retain
+ * ownership for the lifetime of this ResourceTracer.
+ *
+ * Exported as U_COMMON_API for Windows because it is a value field
+ * in other exported types.
+ */
+class U_COMMON_API ResourceTracer {
+public:
+ ResourceTracer() :
+ fResB(nullptr),
+ fParent(nullptr),
+ fKey(nullptr),
+ fIndex(-1) {}
+
+ ResourceTracer(const UResourceBundle* resB) :
+ fResB(resB),
+ fParent(nullptr),
+ fKey(nullptr),
+ fIndex(-1) {}
+
+ ResourceTracer(const UResourceBundle* resB, const char* key) :
+ fResB(resB),
+ fParent(nullptr),
+ fKey(key),
+ fIndex(-1) {}
+
+ ResourceTracer(const UResourceBundle* resB, int32_t index) :
+ fResB(resB),
+ fParent(nullptr),
+ fKey(nullptr),
+ fIndex(index) {}
+
+ ResourceTracer(const ResourceTracer& parent, const char* key) :
+ fResB(nullptr),
+ fParent(&parent),
+ fKey(key),
+ fIndex(-1) {}
+
+ ResourceTracer(const ResourceTracer& parent, int32_t index) :
+ fResB(nullptr),
+ fParent(&parent),
+ fKey(nullptr),
+ fIndex(index) {}
+
+ ~ResourceTracer();
+
+ void trace(const char* type) const;
+ void traceOpen() const;
+
+ /**
+ * Calls trace() if the resB or parent provided to the constructor was
+ * non-null; otherwise, does nothing.
+ */
+ void maybeTrace(const char* type) const {
+ if (fResB || fParent) {
+ trace(type);
+ }
+ }
+
+private:
+ const UResourceBundle* fResB;
+ const ResourceTracer* fParent;
+ const char* fKey;
+ int32_t fIndex;
+
+ CharString& getFilePath(CharString& output, UErrorCode& status) const;
+
+ CharString& getResPath(CharString& output, UErrorCode& status) const;
+};
+
+/**
+ * This class provides methods to trace data file reads when ICU is built
+ * with --enable-tracing.
+ */
+class FileTracer {
+public:
+ static void traceOpen(const char* path, const char* type, const char* name);
+
+private:
+ static void traceOpenDataFile(const char* path, const char* type, const char* name);
+ static void traceOpenResFile(const char* path, const char* name);
+};
+
+U_NAMESPACE_END
+
+#else // U_ENABLE_TRACING
+
+U_NAMESPACE_BEGIN
+
+/**
+ * Default trivial implementation when --enable-tracing is not used.
+ */
+class U_COMMON_API ResourceTracer {
+public:
+ ResourceTracer() {}
+
+ ResourceTracer(const void*) {}
+
+ ResourceTracer(const void*, const char*) {}
+
+ ResourceTracer(const void*, int32_t) {}
+
+ ResourceTracer(const ResourceTracer&, const char*) {}
+
+ ResourceTracer(const ResourceTracer&, int32_t) {}
+
+ void trace(const char*) const {}
+
+ void traceOpen() const {}
+
+ void maybeTrace(const char*) const {}
+};
+
+/**
+ * Default trivial implementation when --enable-tracing is not used.
+ */
+class FileTracer {
+public:
+ static void traceOpen(const char*, const char*, const char*) {}
+};
+
+U_NAMESPACE_END
+
+#endif // U_ENABLE_TRACING
+
+#endif //__RESTRACE_H__
diff --git a/deps/icu-small/source/common/schriter.cpp b/deps/icu-small/source/common/schriter.cpp
index f852800aaa..17b68aee9d 100644
--- a/deps/icu-small/source/common/schriter.cpp
+++ b/deps/icu-small/source/common/schriter.cpp
@@ -101,7 +101,7 @@ StringCharacterIterator::operator==(const ForwardCharacterIterator& that) const
&& end == realThat.end;
}
-CharacterIterator*
+StringCharacterIterator*
StringCharacterIterator::clone() const {
return new StringCharacterIterator(*this);
}
diff --git a/deps/icu-small/source/common/serv.cpp b/deps/icu-small/source/common/serv.cpp
index 40940740d0..044864b859 100644
--- a/deps/icu-small/source/common/serv.cpp
+++ b/deps/icu-small/source/common/serv.cpp
@@ -333,10 +333,7 @@ U_CDECL_END
******************************************************************
*/
-static UMutex *lock() {
- static UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static UMutex lock;
ICUService::ICUService()
: name()
@@ -361,7 +358,7 @@ ICUService::ICUService(const UnicodeString& newName)
ICUService::~ICUService()
{
{
- Mutex mutex(lock());
+ Mutex mutex(&lock);
clearCaches();
delete factories;
factories = NULL;
@@ -452,7 +449,7 @@ ICUService::getKey(ICUServiceKey& key, UnicodeString* actualReturn, const ICUSer
// if factory is not null, we're calling from within the mutex,
// and since some unix machines don't have reentrant mutexes we
// need to make sure not to try to lock it again.
- XMutex mutex(lock(), factory != NULL);
+ XMutex mutex(&lock, factory != NULL);
if (serviceCache == NULL) {
ncthis->serviceCache = new Hashtable(status);
@@ -618,7 +615,7 @@ ICUService::getVisibleIDs(UVector& result, const UnicodeString* matchID, UErrorC
}
{
- Mutex mutex(lock());
+ Mutex mutex(&lock);
const Hashtable* map = getVisibleIDMap(status);
if (map != NULL) {
ICUServiceKey* fallbackKey = createKey(matchID, status);
@@ -695,7 +692,7 @@ ICUService::getDisplayName(const UnicodeString& id, UnicodeString& result, const
{
{
UErrorCode status = U_ZERO_ERROR;
- Mutex mutex(lock());
+ Mutex mutex(&lock);
const Hashtable* map = getVisibleIDMap(status);
if (map != NULL) {
ICUServiceFactory* f = (ICUServiceFactory*)map->get(id);
@@ -747,7 +744,7 @@ ICUService::getDisplayNames(UVector& result,
result.setDeleter(userv_deleteStringPair);
if (U_SUCCESS(status)) {
ICUService* ncthis = (ICUService*)this; // cast away semantic const
- Mutex mutex(lock());
+ Mutex mutex(&lock);
if (dnCache != NULL && dnCache->locale != locale) {
delete dnCache;
@@ -852,7 +849,7 @@ URegistryKey
ICUService::registerFactory(ICUServiceFactory* factoryToAdopt, UErrorCode& status)
{
if (U_SUCCESS(status) && factoryToAdopt != NULL) {
- Mutex mutex(lock());
+ Mutex mutex(&lock);
if (factories == NULL) {
factories = new UVector(deleteUObject, NULL, status);
@@ -883,7 +880,7 @@ ICUService::unregister(URegistryKey rkey, UErrorCode& status)
ICUServiceFactory *factory = (ICUServiceFactory*)rkey;
UBool result = FALSE;
if (factory != NULL && factories != NULL) {
- Mutex mutex(lock());
+ Mutex mutex(&lock);
if (factories->removeElement(factory)) {
clearCaches();
@@ -903,7 +900,7 @@ void
ICUService::reset()
{
{
- Mutex mutex(lock());
+ Mutex mutex(&lock);
reInitializeFactories();
clearCaches();
}
diff --git a/deps/icu-small/source/common/servls.cpp b/deps/icu-small/source/common/servls.cpp
index 0b1b1b947d..0c2a73d98e 100644
--- a/deps/icu-small/source/common/servls.cpp
+++ b/deps/icu-small/source/common/servls.cpp
@@ -263,7 +263,7 @@ ICULocaleService::validateFallbackLocale() const
{
const Locale& loc = Locale::getDefault();
ICULocaleService* ncThis = (ICULocaleService*)this;
- static UMutex llock = U_MUTEX_INITIALIZER;
+ static UMutex llock;
{
Mutex mutex(&llock);
if (loc != fallbackLocale) {
diff --git a/deps/icu-small/source/common/servnotf.cpp b/deps/icu-small/source/common/servnotf.cpp
index 9b5997bd17..435f36b0d0 100644
--- a/deps/icu-small/source/common/servnotf.cpp
+++ b/deps/icu-small/source/common/servnotf.cpp
@@ -21,10 +21,7 @@ U_NAMESPACE_BEGIN
EventListener::~EventListener() {}
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EventListener)
-static UMutex *notifyLock() {
- static UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static UMutex notifyLock;
ICUNotifier::ICUNotifier(void)
: listeners(NULL)
@@ -33,7 +30,7 @@ ICUNotifier::ICUNotifier(void)
ICUNotifier::~ICUNotifier(void) {
{
- Mutex lmx(notifyLock());
+ Mutex lmx(&notifyLock);
delete listeners;
listeners = NULL;
}
@@ -50,7 +47,7 @@ ICUNotifier::addListener(const EventListener* l, UErrorCode& status)
}
if (acceptsListener(*l)) {
- Mutex lmx(notifyLock());
+ Mutex lmx(&notifyLock);
if (listeners == NULL) {
listeners = new UVector(5, status);
} else {
@@ -83,7 +80,7 @@ ICUNotifier::removeListener(const EventListener *l, UErrorCode& status)
}
{
- Mutex lmx(notifyLock());
+ Mutex lmx(&notifyLock);
if (listeners != NULL) {
// identity equality check
for (int i = 0, e = listeners->size(); i < e; ++i) {
@@ -106,7 +103,7 @@ void
ICUNotifier::notifyChanged(void)
{
if (listeners != NULL) {
- Mutex lmx(notifyLock());
+ Mutex lmx(&notifyLock);
if (listeners != NULL) {
for (int i = 0, e = listeners->size(); i < e; ++i) {
EventListener* el = (EventListener*)listeners->elementAt(i);
diff --git a/deps/icu-small/source/common/uarrsort.cpp b/deps/icu-small/source/common/uarrsort.cpp
index 03c4d4e7fc..6090582164 100644
--- a/deps/icu-small/source/common/uarrsort.cpp
+++ b/deps/icu-small/source/common/uarrsort.cpp
@@ -34,6 +34,10 @@ enum {
STACK_ITEM_SIZE=200
};
+static constexpr int32_t sizeInMaxAlignTs(int32_t sizeInBytes) {
+ return (sizeInBytes + sizeof(max_align_t) - 1) / sizeof(max_align_t);
+}
+
/* UComparator convenience implementations ---------------------------------- */
U_CAPI int32_t U_EXPORT2
@@ -134,25 +138,15 @@ doInsertionSort(char *array, int32_t length, int32_t itemSize,
static void
insertionSort(char *array, int32_t length, int32_t itemSize,
UComparator *cmp, const void *context, UErrorCode *pErrorCode) {
- UAlignedMemory v[STACK_ITEM_SIZE/sizeof(UAlignedMemory)+1];
- void *pv;
- /* allocate an intermediate item variable (v) */
- if(itemSize<=STACK_ITEM_SIZE) {
- pv=v;
- } else {
- pv=uprv_malloc(itemSize);
- if(pv==NULL) {
- *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
- return;
- }
+ icu::MaybeStackArray<max_align_t, sizeInMaxAlignTs(STACK_ITEM_SIZE)> v;
+ if (sizeInMaxAlignTs(itemSize) > v.getCapacity() &&
+ v.resize(sizeInMaxAlignTs(itemSize)) == nullptr) {
+ *pErrorCode = U_MEMORY_ALLOCATION_ERROR;
+ return;
}
- doInsertionSort(array, length, itemSize, cmp, context, pv);
-
- if(pv!=v) {
- uprv_free(pv);
- }
+ doInsertionSort(array, length, itemSize, cmp, context, v.getAlias());
}
/* QuickSort ---------------------------------------------------------------- */
@@ -238,26 +232,16 @@ subQuickSort(char *array, int32_t start, int32_t limit, int32_t itemSize,
static void
quickSort(char *array, int32_t length, int32_t itemSize,
UComparator *cmp, const void *context, UErrorCode *pErrorCode) {
- UAlignedMemory xw[(2*STACK_ITEM_SIZE)/sizeof(UAlignedMemory)+1];
- void *p;
-
/* allocate two intermediate item variables (x and w) */
- if(itemSize<=STACK_ITEM_SIZE) {
- p=xw;
- } else {
- p=uprv_malloc(2*itemSize);
- if(p==NULL) {
- *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
- return;
- }
+ icu::MaybeStackArray<max_align_t, sizeInMaxAlignTs(STACK_ITEM_SIZE) * 2> xw;
+ if(sizeInMaxAlignTs(itemSize)*2 > xw.getCapacity() &&
+ xw.resize(sizeInMaxAlignTs(itemSize) * 2) == nullptr) {
+ *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+ return;
}
- subQuickSort(array, 0, length, itemSize,
- cmp, context, p, (char *)p+itemSize);
-
- if(p!=xw) {
- uprv_free(p);
- }
+ subQuickSort(array, 0, length, itemSize, cmp, context,
+ xw.getAlias(), xw.getAlias() + sizeInMaxAlignTs(itemSize));
}
/* uprv_sortArray() API ----------------------------------------------------- */
diff --git a/deps/icu-small/source/common/ubidiimp.h b/deps/icu-small/source/common/ubidiimp.h
index a5d0727495..9746b2bc10 100644
--- a/deps/icu-small/source/common/ubidiimp.h
+++ b/deps/icu-small/source/common/ubidiimp.h
@@ -198,8 +198,8 @@ typedef struct Run {
/* in a Run, logicalStart will get this bit set if the run level is odd */
#define INDEX_ODD_BIT (1UL<<31)
-#define MAKE_INDEX_ODD_PAIR(index, level) ((index)|((int32_t)(level)<<31))
-#define ADD_ODD_BIT_FROM_LEVEL(x, level) ((x)|=((int32_t)(level)<<31))
+#define MAKE_INDEX_ODD_PAIR(index, level) ((index)|((int32_t)((level)&1)<<31))
+#define ADD_ODD_BIT_FROM_LEVEL(x, level) ((x)|=((int32_t)((level)&1)<<31))
#define REMOVE_ODD_BIT(x) ((x)&=~INDEX_ODD_BIT)
#define GET_INDEX(x) ((x)&~INDEX_ODD_BIT)
@@ -387,41 +387,49 @@ typedef union {
} BidiMemoryForAllocation;
/* Macros for initial checks at function entry */
-#define RETURN_IF_NULL_OR_FAILING_ERRCODE(pErrcode, retvalue) \
- if((pErrcode)==NULL || U_FAILURE(*pErrcode)) return retvalue
-#define RETURN_IF_NOT_VALID_PARA(bidi, errcode, retvalue) \
- if(!IS_VALID_PARA(bidi)) { \
- errcode=U_INVALID_STATE_ERROR; \
- return retvalue; \
- }
-#define RETURN_IF_NOT_VALID_PARA_OR_LINE(bidi, errcode, retvalue) \
- if(!IS_VALID_PARA_OR_LINE(bidi)) { \
- errcode=U_INVALID_STATE_ERROR; \
- return retvalue; \
- }
-#define RETURN_IF_BAD_RANGE(arg, start, limit, errcode, retvalue) \
- if((arg)<(start) || (arg)>=(limit)) { \
- (errcode)=U_ILLEGAL_ARGUMENT_ERROR; \
- return retvalue; \
- }
-
-#define RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrcode) \
- if((pErrcode)==NULL || U_FAILURE(*pErrcode)) return
-#define RETURN_VOID_IF_NOT_VALID_PARA(bidi, errcode) \
- if(!IS_VALID_PARA(bidi)) { \
- errcode=U_INVALID_STATE_ERROR; \
- return; \
- }
-#define RETURN_VOID_IF_NOT_VALID_PARA_OR_LINE(bidi, errcode) \
- if(!IS_VALID_PARA_OR_LINE(bidi)) { \
- errcode=U_INVALID_STATE_ERROR; \
- return; \
- }
-#define RETURN_VOID_IF_BAD_RANGE(arg, start, limit, errcode) \
- if((arg)<(start) || (arg)>=(limit)) { \
- (errcode)=U_ILLEGAL_ARGUMENT_ERROR; \
- return; \
- }
+#define RETURN_IF_NULL_OR_FAILING_ERRCODE(pErrcode, retvalue) UPRV_BLOCK_MACRO_BEGIN { \
+ if((pErrcode)==NULL || U_FAILURE(*pErrcode)) return retvalue; \
+} UPRV_BLOCK_MACRO_END
+#define RETURN_IF_NOT_VALID_PARA(bidi, errcode, retvalue) UPRV_BLOCK_MACRO_BEGIN { \
+ if(!IS_VALID_PARA(bidi)) { \
+ errcode=U_INVALID_STATE_ERROR; \
+ return retvalue; \
+ } \
+} UPRV_BLOCK_MACRO_END
+#define RETURN_IF_NOT_VALID_PARA_OR_LINE(bidi, errcode, retvalue) UPRV_BLOCK_MACRO_BEGIN { \
+ if(!IS_VALID_PARA_OR_LINE(bidi)) { \
+ errcode=U_INVALID_STATE_ERROR; \
+ return retvalue; \
+ } \
+} UPRV_BLOCK_MACRO_END
+#define RETURN_IF_BAD_RANGE(arg, start, limit, errcode, retvalue) UPRV_BLOCK_MACRO_BEGIN { \
+ if((arg)<(start) || (arg)>=(limit)) { \
+ (errcode)=U_ILLEGAL_ARGUMENT_ERROR; \
+ return retvalue; \
+ } \
+} UPRV_BLOCK_MACRO_END
+
+#define RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrcode) UPRV_BLOCK_MACRO_BEGIN { \
+ if((pErrcode)==NULL || U_FAILURE(*pErrcode)) return; \
+} UPRV_BLOCK_MACRO_END
+#define RETURN_VOID_IF_NOT_VALID_PARA(bidi, errcode) UPRV_BLOCK_MACRO_BEGIN { \
+ if(!IS_VALID_PARA(bidi)) { \
+ errcode=U_INVALID_STATE_ERROR; \
+ return; \
+ } \
+} UPRV_BLOCK_MACRO_END
+#define RETURN_VOID_IF_NOT_VALID_PARA_OR_LINE(bidi, errcode) UPRV_BLOCK_MACRO_BEGIN { \
+ if(!IS_VALID_PARA_OR_LINE(bidi)) { \
+ errcode=U_INVALID_STATE_ERROR; \
+ return; \
+ } \
+} UPRV_BLOCK_MACRO_END
+#define RETURN_VOID_IF_BAD_RANGE(arg, start, limit, errcode) UPRV_BLOCK_MACRO_BEGIN { \
+ if((arg)<(start) || (arg)>=(limit)) { \
+ (errcode)=U_ILLEGAL_ARGUMENT_ERROR; \
+ return; \
+ } \
+} UPRV_BLOCK_MACRO_END
/* helper function to (re)allocate memory if allowed */
U_CFUNC UBool
diff --git a/deps/icu-small/source/common/ubiditransform.cpp b/deps/icu-small/source/common/ubiditransform.cpp
index 394df6092d..bb3ce8cb93 100644
--- a/deps/icu-small/source/common/ubiditransform.cpp
+++ b/deps/icu-small/source/common/ubiditransform.cpp
@@ -31,11 +31,11 @@
#define SHAPE_LOGICAL U_SHAPE_TEXT_DIRECTION_LOGICAL
#define SHAPE_VISUAL U_SHAPE_TEXT_DIRECTION_VISUAL_LTR
-#define CHECK_LEN(STR, LEN, ERROR) { \
- if (LEN == 0) return 0; \
- if (LEN < -1) { *(ERROR) = U_ILLEGAL_ARGUMENT_ERROR; return 0; } \
- if (LEN == -1) LEN = u_strlen(STR); \
- }
+#define CHECK_LEN(STR, LEN, ERROR) UPRV_BLOCK_MACRO_BEGIN { \
+ if (LEN == 0) return 0; \
+ if (LEN < -1) { *(ERROR) = U_ILLEGAL_ARGUMENT_ERROR; return 0; } \
+ if (LEN == -1) LEN = u_strlen(STR); \
+} UPRV_BLOCK_MACRO_END
#define MAX_ACTIONS 7
diff --git a/deps/icu-small/source/common/ucase.cpp b/deps/icu-small/source/common/ucase.cpp
index 50c8d20c1f..57a4032790 100644
--- a/deps/icu-small/source/common/ucase.cpp
+++ b/deps/icu-small/source/common/ucase.cpp
@@ -116,7 +116,7 @@ static const uint8_t flagsOffset[256]={
* moved to the last uint16_t of the value, use +1 for beginning of next slot
* @param value (out) int32_t or uint32_t output if hasSlot, otherwise not modified
*/
-#define GET_SLOT_VALUE(excWord, idx, pExc16, value) \
+#define GET_SLOT_VALUE(excWord, idx, pExc16, value) UPRV_BLOCK_MACRO_BEGIN { \
if(((excWord)&UCASE_EXC_DOUBLE_SLOTS)==0) { \
(pExc16)+=SLOT_OFFSET(excWord, idx); \
(value)=*pExc16; \
@@ -124,7 +124,8 @@ static const uint8_t flagsOffset[256]={
(pExc16)+=2*SLOT_OFFSET(excWord, idx); \
(value)=*pExc16++; \
(value)=((value)<<16)|*pExc16; \
- }
+ } \
+} UPRV_BLOCK_MACRO_END
/* simple case mappings ----------------------------------------------------- */
diff --git a/deps/icu-small/source/common/uchar.cpp b/deps/icu-small/source/common/uchar.cpp
index 60fe75c78d..12365fd697 100644
--- a/deps/icu-small/source/common/uchar.cpp
+++ b/deps/icu-small/source/common/uchar.cpp
@@ -40,7 +40,7 @@
/* constants and macros for access to the data ------------------------------ */
/* getting a uint32_t properties word from the data */
-#define GET_PROPS(c, result) ((result)=UTRIE2_GET16(&propsTrie, c));
+#define GET_PROPS(c, result) ((result)=UTRIE2_GET16(&propsTrie, c))
/* API functions ------------------------------------------------------------ */
diff --git a/deps/icu-small/source/common/uchriter.cpp b/deps/icu-small/source/common/uchriter.cpp
index 822168f5c8..bedbabc74c 100644
--- a/deps/icu-small/source/common/uchriter.cpp
+++ b/deps/icu-small/source/common/uchriter.cpp
@@ -89,7 +89,7 @@ UCharCharacterIterator::hashCode() const {
return ustr_hashUCharsN(text, textLength) ^ pos ^ begin ^ end;
}
-CharacterIterator*
+UCharCharacterIterator*
UCharCharacterIterator::clone() const {
return new UCharCharacterIterator(*this);
}
diff --git a/deps/icu-small/source/common/ucln_cmn.cpp b/deps/icu-small/source/common/ucln_cmn.cpp
index d78491df41..ab9d3adbd2 100644
--- a/deps/icu-small/source/common/ucln_cmn.cpp
+++ b/deps/icu-small/source/common/ucln_cmn.cpp
@@ -65,9 +65,20 @@ U_CFUNC void
ucln_common_registerCleanup(ECleanupCommonType type,
cleanupFunc *func)
{
+ // Thread safety messiness: From ticket 10295, calls to registerCleanup() may occur
+ // concurrently. Although such cases should be storing the same value, they raise errors
+ // from the thread sanity checker. Doing the store within a mutex avoids those.
+ // BUT that can trigger a recursive entry into std::call_once() in umutex.cpp when this code,
+ // running from the call_once function, tries to grab the ICU global mutex, which
+ // re-enters the mutex init path. So, work-around by special casing UCLN_COMMON_MUTEX, not
+ // using the ICU global mutex for it.
+ //
+ // No other point in ICU uses std::call_once().
+
U_ASSERT(UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT);
- if (UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT)
- {
+ if (type == UCLN_COMMON_MUTEX) {
+ gCommonCleanupFunctions[type] = func;
+ } else if (UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT) {
icu::Mutex m; // See ticket 10295 for discussion.
gCommonCleanupFunctions[type] = func;
}
diff --git a/deps/icu-small/source/common/ucln_cmn.h b/deps/icu-small/source/common/ucln_cmn.h
index 0ca911b47d..b837fb9462 100644
--- a/deps/icu-small/source/common/ucln_cmn.h
+++ b/deps/icu-small/source/common/ucln_cmn.h
@@ -22,8 +22,6 @@
/* These are the cleanup functions for various APIs. */
/* @return true if cleanup complete successfully.*/
-U_CFUNC UBool umtx_cleanup(void);
-
U_CFUNC UBool utrace_cleanup(void);
U_CFUNC UBool ucln_lib_cleanup(void);
@@ -41,6 +39,8 @@ typedef enum ECleanupCommonType {
UCLN_COMMON_LOCALE_KEY_TYPE,
UCLN_COMMON_LOCALE,
UCLN_COMMON_LOCALE_AVAILABLE,
+ UCLN_COMMON_LIKELY_SUBTAGS,
+ UCLN_COMMON_LOCALE_DISTANCE,
UCLN_COMMON_ULOC,
UCLN_COMMON_CURRENCY,
UCLN_COMMON_LOADED_NORMALIZER2,
@@ -62,6 +62,7 @@ typedef enum ECleanupCommonType {
*/
UCLN_COMMON_UNIFIED_CACHE,
UCLN_COMMON_URES,
+ UCLN_COMMON_MUTEX, // Mutexes should be the last to be cleaned up.
UCLN_COMMON_COUNT /* This must be last */
} ECleanupCommonType;
diff --git a/deps/icu-small/source/common/ucnv.cpp b/deps/icu-small/source/common/ucnv.cpp
index abf302eadd..e2e0c5b9f7 100644
--- a/deps/icu-small/source/common/ucnv.cpp
+++ b/deps/icu-small/source/common/ucnv.cpp
@@ -25,6 +25,8 @@
#if !UCONFIG_NO_CONVERSION
+#include <memory>
+
#include "unicode/ustring.h"
#include "unicode/ucnv.h"
#include "unicode/ucnv_err.h"
@@ -158,7 +160,6 @@ ucnv_safeClone(const UConverter* cnv, void *stackBuffer, int32_t *pBufferSize, U
UConverter *localConverter, *allocatedConverter;
int32_t stackBufferSize;
int32_t bufferSizeNeeded;
- char *stackBufferChars = (char *)stackBuffer;
UErrorCode cbErr;
UConverterToUnicodeArgs toUArgs = {
sizeof(UConverterToUnicodeArgs),
@@ -224,23 +225,22 @@ ucnv_safeClone(const UConverter* cnv, void *stackBuffer, int32_t *pBufferSize, U
}
}
-
- /* Pointers on 64-bit platforms need to be aligned
- * on a 64-bit boundary in memory.
+ /* Adjust (if necessary) the stackBuffer pointer to be aligned correctly for a UConverter.
+ * TODO(Jira ICU-20736) Redo this using std::align() once g++4.9 compatibility is no longer needed.
*/
- if (U_ALIGNMENT_OFFSET(stackBuffer) != 0) {
- int32_t offsetUp = (int32_t)U_ALIGNMENT_OFFSET_UP(stackBufferChars);
- if(stackBufferSize > offsetUp) {
- stackBufferSize -= offsetUp;
- stackBufferChars += offsetUp;
+ if (stackBuffer) {
+ uintptr_t p = reinterpret_cast<uintptr_t>(stackBuffer);
+ uintptr_t aligned_p = (p + alignof(UConverter) - 1) & ~(alignof(UConverter) - 1);
+ ptrdiff_t pointerAdjustment = aligned_p - p;
+ if (bufferSizeNeeded + pointerAdjustment <= stackBufferSize) {
+ stackBuffer = reinterpret_cast<void *>(aligned_p);
+ stackBufferSize -= pointerAdjustment;
} else {
/* prevent using the stack buffer but keep the size > 0 so that we do not just preflight */
stackBufferSize = 1;
}
}
- stackBuffer = (void *)stackBufferChars;
-
/* Now, see if we must allocate any memory */
if (stackBufferSize < bufferSizeNeeded || stackBuffer == NULL)
{
@@ -475,7 +475,7 @@ ucnv_setSubstString(UConverter *cnv,
const UChar *s,
int32_t length,
UErrorCode *err) {
- UAlignedMemory cloneBuffer[U_CNV_SAFECLONE_BUFFERSIZE / sizeof(UAlignedMemory) + 1];
+ alignas(UConverter) char cloneBuffer[U_CNV_SAFECLONE_BUFFERSIZE];
char chars[UCNV_ERROR_BUFFER_LENGTH];
UConverter *clone;
diff --git a/deps/icu-small/source/common/ucnv2022.cpp b/deps/icu-small/source/common/ucnv2022.cpp
index 4a35ff85e1..6cd9a3d12e 100644
--- a/deps/icu-small/source/common/ucnv2022.cpp
+++ b/deps/icu-small/source/common/ucnv2022.cpp
@@ -3571,20 +3571,11 @@ _ISO_2022_WriteSub(UConverterFromUnicodeArgs *args, int32_t offsetIndex, UErrorC
/*
* Structure for cloning an ISO 2022 converter into a single memory block.
- * ucnv_safeClone() of the converter will align the entire cloneStruct,
- * and then ucnv_safeClone() of the sub-converter may additionally align
- * currentConverter inside the cloneStruct, for which we need the deadSpace
- * after currentConverter.
- * This is because UAlignedMemory may be larger than the actually
- * necessary alignment size for the platform.
- * The other cloneStruct fields will not be moved around,
- * and are aligned properly with cloneStruct's alignment.
*/
struct cloneStruct
{
UConverter cnv;
UConverter currentConverter;
- UAlignedMemory deadSpace;
UConverterDataISO2022 mydata;
};
@@ -3602,6 +3593,10 @@ _ISO_2022_SafeClone(
UConverterDataISO2022 *cnvData;
int32_t i, size;
+ if (U_FAILURE(*status)){
+ return nullptr;
+ }
+
if (*pBufferSize == 0) { /* 'preflighting' request - set needed size into *pBufferSize */
*pBufferSize = (int32_t)sizeof(struct cloneStruct);
return NULL;
@@ -3619,7 +3614,7 @@ _ISO_2022_SafeClone(
/* share the subconverters */
if(cnvData->currentConverter != NULL) {
- size = (int32_t)(sizeof(UConverter) + sizeof(UAlignedMemory)); /* include size of padding */
+ size = (int32_t)sizeof(UConverter);
localClone->mydata.currentConverter =
ucnv_safeClone(cnvData->currentConverter,
&localClone->currentConverter,
diff --git a/deps/icu-small/source/common/ucnv_bld.cpp b/deps/icu-small/source/common/ucnv_bld.cpp
index e6ef833f4e..1c2363ea89 100644
--- a/deps/icu-small/source/common/ucnv_bld.cpp
+++ b/deps/icu-small/source/common/ucnv_bld.cpp
@@ -194,10 +194,7 @@ static struct {
/*initializes some global variables */
static UHashtable *SHARED_DATA_HASHTABLE = NULL;
-static icu::UMutex *cnvCacheMutex() { /* Mutex for synchronizing cnv cache access. */
- static icu::UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static icu::UMutex cnvCacheMutex;
/* Note: the global mutex is used for */
/* reference count updates. */
@@ -602,9 +599,9 @@ U_CFUNC void
ucnv_unloadSharedDataIfReady(UConverterSharedData *sharedData)
{
if(sharedData != NULL && sharedData->isReferenceCounted) {
- umtx_lock(cnvCacheMutex());
+ umtx_lock(&cnvCacheMutex);
ucnv_unload(sharedData);
- umtx_unlock(cnvCacheMutex());
+ umtx_unlock(&cnvCacheMutex);
}
}
@@ -612,9 +609,9 @@ U_CFUNC void
ucnv_incrementRefCount(UConverterSharedData *sharedData)
{
if(sharedData != NULL && sharedData->isReferenceCounted) {
- umtx_lock(cnvCacheMutex());
+ umtx_lock(&cnvCacheMutex);
sharedData->referenceCounter++;
- umtx_unlock(cnvCacheMutex());
+ umtx_unlock(&cnvCacheMutex);
}
}
@@ -815,9 +812,9 @@ ucnv_loadSharedData(const char *converterName,
pArgs->nestedLoads=1;
pArgs->pkg=NULL;
- umtx_lock(cnvCacheMutex());
+ umtx_lock(&cnvCacheMutex);
mySharedConverterData = ucnv_load(pArgs, err);
- umtx_unlock(cnvCacheMutex());
+ umtx_unlock(&cnvCacheMutex);
if (U_FAILURE (*err) || (mySharedConverterData == NULL))
{
return NULL;
@@ -1064,7 +1061,7 @@ ucnv_flushCache ()
* because the sequence of looking up in the cache + incrementing
* is protected by cnvCacheMutex.
*/
- umtx_lock(cnvCacheMutex());
+ umtx_lock(&cnvCacheMutex);
/*
* double loop: A delta/extension-only converter has a pointer to its base table's
* shared data; the first iteration of the outer loop may see the delta converter
@@ -1093,7 +1090,7 @@ ucnv_flushCache ()
}
}
} while(++i == 1 && remaining > 0);
- umtx_unlock(cnvCacheMutex());
+ umtx_unlock(&cnvCacheMutex);
UTRACE_DATA1(UTRACE_INFO, "ucnv_flushCache() exits with %d converters remaining", remaining);
@@ -1199,7 +1196,7 @@ internalSetName(const char *name, UErrorCode *status) {
}
algorithmicSharedData = getAlgorithmicTypeFromName(stackArgs.name);
- umtx_lock(cnvCacheMutex());
+ umtx_lock(&cnvCacheMutex);
gDefaultAlgorithmicSharedData = algorithmicSharedData;
gDefaultConverterContainsOption = containsOption;
@@ -1215,7 +1212,7 @@ internalSetName(const char *name, UErrorCode *status) {
ucnv_enableCleanup();
- umtx_unlock(cnvCacheMutex());
+ umtx_unlock(&cnvCacheMutex);
}
#endif
@@ -1240,7 +1237,7 @@ ucnv_getDefaultName() {
but ucnv_setDefaultName is not thread safe.
*/
{
- icu::Mutex lock(cnvCacheMutex());
+ icu::Mutex lock(&cnvCacheMutex);
name = gDefaultConverterName;
}
if(name==NULL) {
diff --git a/deps/icu-small/source/common/ucnv_lmb.cpp b/deps/icu-small/source/common/ucnv_lmb.cpp
index 6dd8e83428..5e7cfde353 100644
--- a/deps/icu-small/source/common/ucnv_lmb.cpp
+++ b/deps/icu-small/source/common/ucnv_lmb.cpp
@@ -1107,11 +1107,13 @@ GetUniFromLMBCSUni(char const ** ppLMBCSin) /* Called with LMBCS-style Unicode
all input as required by ICU converter semantics.
*/
-#define CHECK_SOURCE_LIMIT(index) \
- if (args->source+index > args->sourceLimit){\
- *err = U_TRUNCATED_CHAR_FOUND;\
- args->source = args->sourceLimit;\
- return 0xffff;}
+#define CHECK_SOURCE_LIMIT(index) UPRV_BLOCK_MACRO_BEGIN { \
+ if (args->source+index > args->sourceLimit) { \
+ *err = U_TRUNCATED_CHAR_FOUND; \
+ args->source = args->sourceLimit; \
+ return 0xffff; \
+ } \
+} UPRV_BLOCK_MACRO_END
/* Return the Unicode representation for the current LMBCS character */
diff --git a/deps/icu-small/source/common/ucnvbocu.cpp b/deps/icu-small/source/common/ucnvbocu.cpp
index 5b66c5059a..7c2aab5655 100644
--- a/deps/icu-small/source/common/ucnvbocu.cpp
+++ b/deps/icu-small/source/common/ucnvbocu.cpp
@@ -202,14 +202,14 @@ bocu1TrailToByte[BOCU1_TRAIL_CONTROLS_COUNT]={
* @param d Divisor.
* @param m Output variable for the rest (modulo result).
*/
-#define NEGDIVMOD(n, d, m) { \
+#define NEGDIVMOD(n, d, m) UPRV_BLOCK_MACRO_BEGIN { \
(m)=(n)%(d); \
(n)/=(d); \
if((m)<0) { \
--(n); \
(m)+=(d); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/* Faster versions of packDiff() for single-byte-encoded diff values. */
diff --git a/deps/icu-small/source/common/ucnvhz.cpp b/deps/icu-small/source/common/ucnvhz.cpp
index 3159537469..b26cf78289 100644
--- a/deps/icu-small/source/common/ucnvhz.cpp
+++ b/deps/icu-small/source/common/ucnvhz.cpp
@@ -38,7 +38,7 @@
#define ESC_LEN 2
-#define CONCAT_ESCAPE_MACRO( args, targetIndex,targetLength,strToAppend, err, len,sourceIndex){ \
+#define CONCAT_ESCAPE_MACRO(args, targetIndex,targetLength,strToAppend, err, len,sourceIndex) UPRV_BLOCK_MACRO_BEGIN { \
while(len-->0){ \
if(targetIndex < targetLength){ \
args->target[targetIndex] = (unsigned char) *strToAppend; \
@@ -53,7 +53,7 @@
} \
strToAppend++; \
} \
-}
+} UPRV_BLOCK_MACRO_END
typedef struct{
@@ -518,19 +518,11 @@ _HZ_WriteSub(UConverterFromUnicodeArgs *args, int32_t offsetIndex, UErrorCode *e
/*
* Structure for cloning an HZ converter into a single memory block.
- * ucnv_safeClone() of the HZ converter will align the entire cloneHZStruct,
- * and then ucnv_safeClone() of the sub-converter may additionally align
- * subCnv inside the cloneHZStruct, for which we need the deadSpace after
- * subCnv. This is because UAlignedMemory may be larger than the actually
- * necessary alignment size for the platform.
- * The other cloneHZStruct fields will not be moved around,
- * and are aligned properly with cloneHZStruct's alignment.
*/
struct cloneHZStruct
{
UConverter cnv;
UConverter subCnv;
- UAlignedMemory deadSpace;
UConverterDataHZ mydata;
};
@@ -545,12 +537,12 @@ _HZ_SafeClone(const UConverter *cnv,
int32_t size, bufferSizeNeeded = sizeof(struct cloneHZStruct);
if (U_FAILURE(*status)){
- return 0;
+ return nullptr;
}
if (*pBufferSize == 0){ /* 'preflighting' request - set needed size into *pBufferSize */
*pBufferSize = bufferSizeNeeded;
- return 0;
+ return nullptr;
}
localClone = (struct cloneHZStruct *)stackBuffer;
@@ -561,7 +553,7 @@ _HZ_SafeClone(const UConverter *cnv,
localClone->cnv.isExtraLocal = TRUE;
/* deep-clone the sub-converter */
- size = (int32_t)(sizeof(UConverter) + sizeof(UAlignedMemory)); /* include size of padding */
+ size = (int32_t)sizeof(UConverter);
((UConverterDataHZ*)localClone->cnv.extraInfo)->gbConverter =
ucnv_safeClone(((UConverterDataHZ*)cnv->extraInfo)->gbConverter, &localClone->subCnv, &size, status);
diff --git a/deps/icu-small/source/common/ucnvisci.cpp b/deps/icu-small/source/common/ucnvisci.cpp
index d0c07f2b27..c1ab06e137 100644
--- a/deps/icu-small/source/common/ucnvisci.cpp
+++ b/deps/icu-small/source/common/ucnvisci.cpp
@@ -831,7 +831,7 @@ static const uint16_t nuktaSpecialCases[][2]={
};
-#define WRITE_TO_TARGET_FROM_U(args,offsets,source,target,targetLimit,targetByteUnit,err){ \
+#define WRITE_TO_TARGET_FROM_U(args,offsets,source,target,targetLimit,targetByteUnit,err) UPRV_BLOCK_MACRO_BEGIN { \
int32_t offset = (int32_t)(source - args->source-1); \
/* write the targetUniChar to target */ \
if(target < targetLimit){ \
@@ -884,7 +884,7 @@ static const uint16_t nuktaSpecialCases[][2]={
(uint8_t) (targetByteUnit); \
*err = U_BUFFER_OVERFLOW_ERROR; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/* Rules:
* Explicit Halant :
@@ -1119,7 +1119,7 @@ static const uint16_t lookupTable[][2]={
{ GURMUKHI, PNJ_MASK }
};
-#define WRITE_TO_TARGET_TO_U(args,source,target,offsets,offset,targetUniChar,delta, err){\
+#define WRITE_TO_TARGET_TO_U(args,source,target,offsets,offset,targetUniChar,delta, err) UPRV_BLOCK_MACRO_BEGIN { \
/* add offset to current Indic Block */ \
if(targetUniChar>ASCII_END && \
targetUniChar != ZWJ && \
@@ -1140,9 +1140,9 @@ static const uint16_t lookupTable[][2]={
(UChar)targetUniChar; \
*err = U_BUFFER_OVERFLOW_ERROR; \
} \
-}
+} UPRV_BLOCK_MACRO_END
-#define GET_MAPPING(sourceChar,targetUniChar,data){ \
+#define GET_MAPPING(sourceChar,targetUniChar,data) UPRV_BLOCK_MACRO_BEGIN { \
targetUniChar = toUnicodeTable[(sourceChar)] ; \
/* is the code point valid in current script? */ \
if(sourceChar> ASCII_END && \
@@ -1153,7 +1153,7 @@ static const uint16_t lookupTable[][2]={
targetUniChar=missingCharMarker; \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/***********
* Rules for ISCII to Unicode converter
diff --git a/deps/icu-small/source/common/ucnvsel.cpp b/deps/icu-small/source/common/ucnvsel.cpp
index 6ccee1ae61..07b55022c3 100644
--- a/deps/icu-small/source/common/ucnvsel.cpp
+++ b/deps/icu-small/source/common/ucnvsel.cpp
@@ -691,36 +691,36 @@ static int16_t countOnes(uint32_t* mask, int32_t len) {
/* internal function! */
static UEnumeration *selectForMask(const UConverterSelector* sel,
- uint32_t *mask, UErrorCode *status) {
+ uint32_t *theMask, UErrorCode *status) {
+ LocalMemory<uint32_t> mask(theMask);
// this is the context we will use. Store a table of indices to which
// encodings are legit.
- struct Enumerator* result = (Enumerator*)uprv_malloc(sizeof(Enumerator));
- if (result == NULL) {
- uprv_free(mask);
+ LocalMemory<Enumerator> result(static_cast<Enumerator *>(uprv_malloc(sizeof(Enumerator))));
+ if (result.isNull()) {
*status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
+ return nullptr;
}
- result->index = NULL; // this will be allocated later!
+ result->index = nullptr; // this will be allocated later!
result->length = result->cur = 0;
result->sel = sel;
- UEnumeration *en = (UEnumeration *)uprv_malloc(sizeof(UEnumeration));
- if (en == NULL) {
+ LocalMemory<UEnumeration> en(static_cast<UEnumeration *>(uprv_malloc(sizeof(UEnumeration))));
+ if (en.isNull()) {
// TODO(markus): Combine Enumerator and UEnumeration into one struct.
- uprv_free(mask);
- uprv_free(result);
*status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
+ return nullptr;
}
- memcpy(en, &defaultEncodings, sizeof(UEnumeration));
- en->context = result;
+ memcpy(en.getAlias(), &defaultEncodings, sizeof(UEnumeration));
int32_t columns = (sel->encodingsCount+31)/32;
- int16_t numOnes = countOnes(mask, columns);
+ int16_t numOnes = countOnes(mask.getAlias(), columns);
// now, we know the exact space we need for index
if (numOnes > 0) {
- result->index = (int16_t*) uprv_malloc(numOnes * sizeof(int16_t));
-
+ result->index = static_cast<int16_t*>(uprv_malloc(numOnes * sizeof(int16_t)));
+ if (result->index == nullptr) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ return nullptr;
+ }
int32_t i, j;
int16_t k = 0;
for (j = 0 ; j < columns; j++) {
@@ -734,8 +734,8 @@ static UEnumeration *selectForMask(const UConverterSelector* sel,
}
} //otherwise, index will remain NULL (and will never be touched by
//the enumerator code anyway)
- uprv_free(mask);
- return en;
+ en->context = result.orphan();
+ return en.orphan();
}
/* check a string against the selector - UTF16 version */
diff --git a/deps/icu-small/source/common/ucptrie.cpp b/deps/icu-small/source/common/ucptrie.cpp
index b72e318387..0004160a23 100644
--- a/deps/icu-small/source/common/ucptrie.cpp
+++ b/deps/icu-small/source/common/ucptrie.cpp
@@ -280,7 +280,7 @@ UChar32 getRange(const void *t, UChar32 start,
int32_t prevI3Block = -1;
int32_t prevBlock = -1;
UChar32 c = start;
- uint32_t trieValue, value;
+ uint32_t trieValue, value = nullValue;
bool haveValue = false;
do {
int32_t i3Block;
diff --git a/deps/icu-small/source/common/ucurr.cpp b/deps/icu-small/source/common/ucurr.cpp
index dba3247fef..d42c2f10b1 100644
--- a/deps/icu-small/source/common/ucurr.cpp
+++ b/deps/icu-small/source/common/ucurr.cpp
@@ -365,10 +365,7 @@ U_CDECL_END
#if !UCONFIG_NO_SERVICE
struct CReg;
-static UMutex *gCRegLock() {
- static UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static UMutex gCRegLock;
static CReg* gCRegHead = 0;
struct CReg : public icu::UMemory {
@@ -394,14 +391,14 @@ struct CReg : public icu::UMemory {
if (status && U_SUCCESS(*status) && _iso && _id) {
CReg* n = new CReg(_iso, _id);
if (n) {
- umtx_lock(gCRegLock());
+ umtx_lock(&gCRegLock);
if (!gCRegHead) {
/* register for the first time */
ucln_common_registerCleanup(UCLN_COMMON_CURRENCY, currency_cleanup);
}
n->next = gCRegHead;
gCRegHead = n;
- umtx_unlock(gCRegLock());
+ umtx_unlock(&gCRegLock);
return n;
}
*status = U_MEMORY_ALLOCATION_ERROR;
@@ -411,7 +408,7 @@ struct CReg : public icu::UMemory {
static UBool unreg(UCurrRegistryKey key) {
UBool found = FALSE;
- umtx_lock(gCRegLock());
+ umtx_lock(&gCRegLock);
CReg** p = &gCRegHead;
while (*p) {
@@ -424,13 +421,13 @@ struct CReg : public icu::UMemory {
p = &((*p)->next);
}
- umtx_unlock(gCRegLock());
+ umtx_unlock(&gCRegLock);
return found;
}
static const UChar* get(const char* id) {
const UChar* result = NULL;
- umtx_lock(gCRegLock());
+ umtx_lock(&gCRegLock);
CReg* p = gCRegHead;
/* register cleanup of the mutex */
@@ -442,7 +439,7 @@ struct CReg : public icu::UMemory {
}
p = p->next;
}
- umtx_unlock(gCRegLock());
+ umtx_unlock(&gCRegLock);
return result;
}
@@ -716,7 +713,9 @@ ucurr_getName(const UChar* currency,
// We no longer support choice format data in names. Data should not contain
// choice patterns.
- *isChoiceFormat = FALSE;
+ if (isChoiceFormat != NULL) {
+ *isChoiceFormat = FALSE;
+ }
if (U_SUCCESS(ec2)) {
U_ASSERT(s != NULL);
return s;
@@ -1356,10 +1355,7 @@ static CurrencyNameCacheEntry* currCache[CURRENCY_NAME_CACHE_NUM] = {NULL};
// It is a simple round-robin replacement strategy.
static int8_t currentCacheEntryIndex = 0;
-static UMutex *gCurrencyCacheMutex() {
- static UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static UMutex gCurrencyCacheMutex;
// Cache deletion
static void
@@ -1408,7 +1404,7 @@ getCacheEntry(const char* locale, UErrorCode& ec) {
CurrencyNameStruct* currencySymbols = NULL;
CurrencyNameCacheEntry* cacheEntry = NULL;
- umtx_lock(gCurrencyCacheMutex());
+ umtx_lock(&gCurrencyCacheMutex);
// in order to handle racing correctly,
// not putting 'search' in a separate function.
int8_t found = -1;
@@ -1423,13 +1419,13 @@ getCacheEntry(const char* locale, UErrorCode& ec) {
cacheEntry = currCache[found];
++(cacheEntry->refCount);
}
- umtx_unlock(gCurrencyCacheMutex());
+ umtx_unlock(&gCurrencyCacheMutex);
if (found == -1) {
collectCurrencyNames(locale, &currencyNames, &total_currency_name_count, &currencySymbols, &total_currency_symbol_count, ec);
if (U_FAILURE(ec)) {
return NULL;
}
- umtx_lock(gCurrencyCacheMutex());
+ umtx_lock(&gCurrencyCacheMutex);
// check again.
for (int8_t i = 0; i < CURRENCY_NAME_CACHE_NUM; ++i) {
if (currCache[i]!= NULL &&
@@ -1468,19 +1464,19 @@ getCacheEntry(const char* locale, UErrorCode& ec) {
cacheEntry = currCache[found];
++(cacheEntry->refCount);
}
- umtx_unlock(gCurrencyCacheMutex());
+ umtx_unlock(&gCurrencyCacheMutex);
}
return cacheEntry;
}
static void releaseCacheEntry(CurrencyNameCacheEntry* cacheEntry) {
- umtx_lock(gCurrencyCacheMutex());
+ umtx_lock(&gCurrencyCacheMutex);
--(cacheEntry->refCount);
if (cacheEntry->refCount == 0) { // remove
deleteCacheEntry(cacheEntry);
}
- umtx_unlock(gCurrencyCacheMutex());
+ umtx_unlock(&gCurrencyCacheMutex);
}
U_CAPI void
@@ -1601,10 +1597,9 @@ uprv_getStaticCurrencyName(const UChar* iso, const char* loc,
{
U_NAMESPACE_USE
- UBool isChoiceFormat;
int32_t len;
const UChar* currname = ucurr_getName(iso, loc, UCURR_SYMBOL_NAME,
- &isChoiceFormat, &len, &ec);
+ nullptr /* isChoiceFormat */, &len, &ec);
if (U_SUCCESS(ec)) {
result.setTo(currname, len);
}
diff --git a/deps/icu-small/source/common/udata.cpp b/deps/icu-small/source/common/udata.cpp
index 99efbc97ee..f2faa82777 100644
--- a/deps/icu-small/source/common/udata.cpp
+++ b/deps/icu-small/source/common/udata.cpp
@@ -33,6 +33,7 @@ might have to #include some other header
#include "cstring.h"
#include "mutex.h"
#include "putilimp.h"
+#include "restrace.h"
#include "uassert.h"
#include "ucln_cmn.h"
#include "ucmndata.h"
@@ -110,11 +111,12 @@ static u_atomic_int32_t gHaveTriedToLoadCommonData = ATOMIC_INT32_T_INITIALIZER(
static UHashtable *gCommonDataCache = NULL; /* Global hash table of opened ICU data files. */
static icu::UInitOnce gCommonDataCacheInitOnce = U_INITONCE_INITIALIZER;
-#if U_PLATFORM_HAS_WINUWP_API == 0
+#if !defined(ICU_DATA_DIR_WINDOWS)
static UDataFileAccess gDataFileAccess = UDATA_DEFAULT_ACCESS; // Access not synchronized.
// Modifying is documented as thread-unsafe.
#else
-static UDataFileAccess gDataFileAccess = UDATA_NO_FILES; // Windows UWP looks in one spot explicitly
+// If we are using the Windows data directory, then look in one spot only.
+static UDataFileAccess gDataFileAccess = UDATA_NO_FILES;
#endif
static UBool U_CALLCONV
@@ -206,7 +208,7 @@ setCommonICUData(UDataMemory *pData, /* The new common data. Belongs to ca
return didUpdate;
}
-#if U_PLATFORM_HAS_WINUWP_API == 0
+#if !defined(ICU_DATA_DIR_WINDOWS)
static UBool
setCommonICUDataPointer(const void *pData, UBool /*warn*/, UErrorCode *pErrorCode) {
@@ -320,7 +322,7 @@ static UDataMemory *udata_findCachedData(const char *path, UErrorCode &err)
retVal = el->item;
}
#ifdef UDATA_DEBUG
- fprintf(stderr, "Cache: [%s] -> %p\n", baseName, retVal);
+ fprintf(stderr, "Cache: [%s] -> %p\n", baseName, (void*) retVal);
#endif
return retVal;
}
@@ -383,7 +385,7 @@ static UDataMemory *udata_cacheDataItem(const char *path, UDataMemory *item, UEr
#ifdef UDATA_DEBUG
fprintf(stderr, "Cache: [%s] <<< %p : %s. vFunc=%p\n", newElement->name,
- newElement->item, u_errorName(subErr), newElement->item->vFuncs);
+ (void*) newElement->item, u_errorName(subErr), (void*) newElement->item->vFuncs);
#endif
if (subErr == U_USING_DEFAULT_WARNING || U_FAILURE(subErr)) {
@@ -477,7 +479,7 @@ UDataPathIterator::UDataPathIterator(const char *inPath, const char *pkg,
nextPath = itemPath.data();
}
#ifdef UDATA_DEBUG
- fprintf(stderr, "SUFFIX=%s [%p]\n", inSuffix, inSuffix);
+ fprintf(stderr, "SUFFIX=%s [%p]\n", inSuffix, (void*) inSuffix);
#endif
/** Suffix **/
@@ -492,12 +494,11 @@ UDataPathIterator::UDataPathIterator(const char *inPath, const char *pkg,
/* pathBuffer will hold the output path strings returned by this iterator */
#ifdef UDATA_DEBUG
- fprintf(stderr, "%p: init %s -> [path=%s], [base=%s], [suff=%s], [itempath=%s], [nextpath=%s], [checklast4=%s]\n",
- iter,
+ fprintf(stderr, "0: init %s -> [path=%s], [base=%s], [suff=%s], [itempath=%s], [nextpath=%s], [checklast4=%s]\n",
item,
path,
basename,
- suffix,
+ suffix.data(),
itemPath.data(),
nextPath,
checkLastFour?"TRUE":"false");
@@ -553,7 +554,7 @@ const char *UDataPathIterator::next(UErrorCode *pErrorCode)
fprintf(stderr, "rest of path (IDD) = %s\n", currentPath);
fprintf(stderr, " ");
{
- uint32_t qqq;
+ int32_t qqq;
for(qqq=0;qqq<pathLen;qqq++)
{
fprintf(stderr, " ");
@@ -574,7 +575,7 @@ const char *UDataPathIterator::next(UErrorCode *pErrorCode)
uprv_strlen(pathBasename)==(basenameLen+4)) { /* base+suffix = full len */
#ifdef UDATA_DEBUG
- fprintf(stderr, "Have %s file on the path: %s\n", suffix, pathBuffer.data());
+ fprintf(stderr, "Have %s file on the path: %s\n", suffix.data(), pathBuffer.data());
#endif
/* do nothing */
}
@@ -640,7 +641,8 @@ U_NAMESPACE_END
* our common data. *
* *
*----------------------------------------------------------------------*/
-#if U_PLATFORM_HAS_WINUWP_API == 0 // Windows UWP Platform does not support dll icu data at this time
+#if !defined(ICU_DATA_DIR_WINDOWS)
+// When using the Windows system data, we expect only a single data file.
extern "C" const DataHeader U_DATA_API U_ICUDATA_ENTRY_POINT;
#endif
@@ -690,7 +692,8 @@ openCommonData(const char *path, /* Path from OpenChoice? */
if(gCommonICUDataArray[commonDataIndex] != NULL) {
return gCommonICUDataArray[commonDataIndex];
}
-#if U_PLATFORM_HAS_WINUWP_API == 0 // Windows UWP Platform does not support dll icu data at this time
+#if !defined(ICU_DATA_DIR_WINDOWS)
+// When using the Windows system data, we expect only a single data file.
int32_t i;
for(i = 0; i < commonDataIndex; ++i) {
if(gCommonICUDataArray[i]->pHeader == &U_ICUDATA_ENTRY_POINT) {
@@ -714,7 +717,8 @@ openCommonData(const char *path, /* Path from OpenChoice? */
setCommonICUDataPointer(uprv_getICUData_conversion(), FALSE, pErrorCode);
}
*/
-#if U_PLATFORM_HAS_WINUWP_API == 0 // Windows UWP Platform does not support dll icu data at this time
+#if !defined(ICU_DATA_DIR_WINDOWS)
+// When using the Windows system data, we expect only a single data file.
setCommonICUDataPointer(&U_ICUDATA_ENTRY_POINT, FALSE, pErrorCode);
{
Mutex lock;
@@ -831,7 +835,7 @@ static UBool extendICUData(UErrorCode *pErr)
* Use a specific mutex to avoid nested locks of the global mutex.
*/
#if MAP_IMPLEMENTATION==MAP_STDIO
- static UMutex extendICUDataMutex = U_MUTEX_INITIALIZER;
+ static UMutex extendICUDataMutex;
umtx_lock(&extendICUDataMutex);
#endif
if(!umtx_loadAcquire(gHaveTriedToLoadCommonData)) {
@@ -1070,13 +1074,13 @@ static UDataMemory *doLoadFromCommonData(UBool isICUData, const char * /*pkgName
/* look up the data piece in the common data */
pHeader=pCommonData->vFuncs->Lookup(pCommonData, tocEntryName, &length, subErrorCode);
#ifdef UDATA_DEBUG
- fprintf(stderr, "%s: pHeader=%p - %s\n", tocEntryName, pHeader, u_errorName(*subErrorCode));
+ fprintf(stderr, "%s: pHeader=%p - %s\n", tocEntryName, (void*) pHeader, u_errorName(*subErrorCode));
#endif
if(pHeader!=NULL) {
pEntryData = checkDataItem(pHeader, isAcceptable, context, type, name, subErrorCode, pErrorCode);
#ifdef UDATA_DEBUG
- fprintf(stderr, "pEntryData=%p\n", pEntryData);
+ fprintf(stderr, "pEntryData=%p\n", (void*) pEntryData);
#endif
if (U_FAILURE(*pErrorCode)) {
return NULL;
@@ -1168,6 +1172,9 @@ doOpenChoice(const char *path, const char *type, const char *name,
UBool isICUData = FALSE;
+ FileTracer::traceOpen(path, type, name);
+
+
/* Is this path ICU data? */
if(path == NULL ||
!strcmp(path, U_ICUDATA_ALIAS) || /* "ICUDATA" */
@@ -1276,12 +1283,12 @@ doOpenChoice(const char *path, const char *type, const char *name,
fprintf(stderr, " tocEntryPath = %s\n", tocEntryName.data());
#endif
-#if U_PLATFORM_HAS_WINUWP_API == 0 // Windows UWP Platform does not support dll icu data at this time
+#if !defined(ICU_DATA_DIR_WINDOWS)
if(path == NULL) {
path = COMMON_DATA_NAME; /* "icudt26e" */
}
#else
- // Windows UWP expects only a single data file.
+ // When using the Windows system data, we expects only a single data file.
path = COMMON_DATA_NAME; /* "icudt26e" */
#endif
diff --git a/deps/icu-small/source/common/uhash.cpp b/deps/icu-small/source/common/uhash.cpp
index 79241a2829..86311ceb0b 100644
--- a/deps/icu-small/source/common/uhash.cpp
+++ b/deps/icu-small/source/common/uhash.cpp
@@ -119,13 +119,14 @@ static const float RESIZE_POLICY_RATIO_TABLE[6] = {
/* This macro expects a UHashTok.pointer as its keypointer and
valuepointer parameters */
-#define HASH_DELETE_KEY_VALUE(hash, keypointer, valuepointer) \
- if (hash->keyDeleter != NULL && keypointer != NULL) { \
- (*hash->keyDeleter)(keypointer); \
- } \
- if (hash->valueDeleter != NULL && valuepointer != NULL) { \
- (*hash->valueDeleter)(valuepointer); \
- }
+#define HASH_DELETE_KEY_VALUE(hash, keypointer, valuepointer) UPRV_BLOCK_MACRO_BEGIN { \
+ if (hash->keyDeleter != NULL && keypointer != NULL) { \
+ (*hash->keyDeleter)(keypointer); \
+ } \
+ if (hash->valueDeleter != NULL && valuepointer != NULL) { \
+ (*hash->valueDeleter)(valuepointer); \
+ } \
+} UPRV_BLOCK_MACRO_END
/*
* Constants for hinting whether a key or value is an integer
diff --git a/deps/icu-small/source/common/uidna.cpp b/deps/icu-small/source/common/uidna.cpp
index 6d56fcb8f5..09347efd6d 100644
--- a/deps/icu-small/source/common/uidna.cpp
+++ b/deps/icu-small/source/common/uidna.cpp
@@ -57,18 +57,16 @@ toASCIILower(UChar ch){
inline static UBool
startsWithPrefix(const UChar* src , int32_t srcLength){
- UBool startsWithPrefix = TRUE;
-
if(srcLength < ACE_PREFIX_LENGTH){
return FALSE;
}
for(int8_t i=0; i< ACE_PREFIX_LENGTH; i++){
if(toASCIILower(src[i]) != ACE_PREFIX[i]){
- startsWithPrefix = FALSE;
+ return FALSE;
}
}
- return startsWithPrefix;
+ return TRUE;
}
@@ -441,6 +439,7 @@ _internal_toUnicode(const UChar* src, int32_t srcLength,
for(int32_t j=0; j<srcLength; j++){
if(src[j]> 0x7f){
srcIsASCII = FALSE;
+ break;
}/*else if(isLDHChar(src[j])==FALSE){
// here we do not assemble surrogates
// since we know that LDH code points
diff --git a/deps/icu-small/source/common/uinvchar.cpp b/deps/icu-small/source/common/uinvchar.cpp
index 2e0f42d927..ac9716066f 100644
--- a/deps/icu-small/source/common/uinvchar.cpp
+++ b/deps/icu-small/source/common/uinvchar.cpp
@@ -207,7 +207,8 @@ u_UCharsToChars(const UChar *us, char *cs, int32_t length) {
while(length>0) {
u=*us++;
if(!UCHAR_IS_INVARIANT(u)) {
- UPRV_UNREACHABLE; /* Variant characters were used. These are not portable in ICU. */
+ U_ASSERT(FALSE); /* Variant characters were used. These are not portable in ICU. */
+ u=0;
}
*cs++=(char)UCHAR_TO_CHAR(u);
--length;
@@ -445,6 +446,13 @@ uprv_copyEbcdic(const UDataSwapper *ds,
return length;
}
+U_CFUNC UBool
+uprv_isEbcdicAtSign(char c) {
+ static const uint8_t ebcdicAtSigns[] = {
+ 0x7C, 0x44, 0x66, 0x80, 0xAC, 0xAE, 0xAF, 0xB5, 0xEC, 0xEF, 0x00 };
+ return c != 0 && uprv_strchr((const char *)ebcdicAtSigns, c) != nullptr;
+}
+
/* compare invariant strings; variant characters compare less than others and unlike each other */
U_CFUNC int32_t
uprv_compareInvAscii(const UDataSwapper *ds,
@@ -562,6 +570,11 @@ uprv_compareInvEbcdicAsAscii(const char *s1, const char *s2) {
}
U_CAPI char U_EXPORT2
+uprv_ebcdicToAscii(char c) {
+ return (char)asciiFromEbcdic[(uint8_t)c];
+}
+
+U_CAPI char U_EXPORT2
uprv_ebcdicToLowercaseAscii(char c) {
return (char)lowercaseAsciiFromEbcdic[(uint8_t)c];
}
diff --git a/deps/icu-small/source/common/uinvchar.h b/deps/icu-small/source/common/uinvchar.h
index 56dddfa8fd..a43cfcd982 100644
--- a/deps/icu-small/source/common/uinvchar.h
+++ b/deps/icu-small/source/common/uinvchar.h
@@ -68,6 +68,75 @@ uprv_isInvariantUString(const UChar *s, int32_t length);
# error Unknown charset family!
#endif
+#ifdef __cplusplus
+
+U_NAMESPACE_BEGIN
+
+/**
+ * Like U_UPPER_ORDINAL(x) but with validation.
+ * Returns 0..25 for A..Z else a value outside 0..25.
+ */
+inline int32_t uprv_upperOrdinal(int32_t c) {
+#if U_CHARSET_FAMILY==U_ASCII_FAMILY
+ return c - 'A';
+#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
+ // EBCDIC: A-Z (26 letters) is split into three ranges A-I (9 letters), J-R (9), S-Z (8).
+ // https://en.wikipedia.org/wiki/EBCDIC_037#Codepage_layout
+ if (c <= 'I') { return c - 'A'; } // A-I --> 0-8
+ if (c < 'J') { return -1; }
+ if (c <= 'R') { return c - 'J' + 9; } // J-R --> 9..17
+ if (c < 'S') { return -1; }
+ return c - 'S' + 18; // S-Z --> 18..25
+#else
+# error Unknown charset family!
+#endif
+}
+
+// Like U_UPPER_ORDINAL(x) but for lowercase and with validation.
+// Returns 0..25 for a..z else a value outside 0..25.
+inline int32_t uprv_lowerOrdinal(int32_t c) {
+#if U_CHARSET_FAMILY==U_ASCII_FAMILY
+ return c - 'a';
+#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
+ // EBCDIC: a-z (26 letters) is split into three ranges a-i (9 letters), j-r (9), s-z (8).
+ // https://en.wikipedia.org/wiki/EBCDIC_037#Codepage_layout
+ if (c <= 'i') { return c - 'a'; } // a-i --> 0-8
+ if (c < 'j') { return -1; }
+ if (c <= 'r') { return c - 'j' + 9; } // j-r --> 9..17
+ if (c < 's') { return -1; }
+ return c - 's' + 18; // s-z --> 18..25
+#else
+# error Unknown charset family!
+#endif
+}
+
+U_NAMESPACE_END
+
+#endif
+
+/**
+ * Returns true if c == '@' is possible.
+ * The @ sign is variant, and the @ sign used on one
+ * EBCDIC machine won't be compiled the same way on other EBCDIC based machines.
+ * @internal
+ */
+U_CFUNC UBool
+uprv_isEbcdicAtSign(char c);
+
+/**
+ * \def uprv_isAtSign
+ * Returns true if c == '@' is possible.
+ * For ASCII, checks for exactly '@'. For EBCDIC, calls uprv_isEbcdicAtSign().
+ * @internal
+ */
+#if U_CHARSET_FAMILY==U_ASCII_FAMILY
+# define uprv_isAtSign(c) ((c)=='@')
+#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
+# define uprv_isAtSign(c) uprv_isEbcdicAtSign(c)
+#else
+# error Unknown charset family!
+#endif
+
/**
* Compare two EBCDIC invariant-character strings in ASCII order.
* @internal
@@ -89,6 +158,26 @@ uprv_compareInvEbcdicAsAscii(const char *s1, const char *s2);
#endif
/**
+ * Converts an EBCDIC invariant character to ASCII.
+ * @internal
+ */
+U_INTERNAL char U_EXPORT2
+uprv_ebcdicToAscii(char c);
+
+/**
+ * \def uprv_invCharToAscii
+ * Converts an invariant character to ASCII.
+ * @internal
+ */
+#if U_CHARSET_FAMILY==U_ASCII_FAMILY
+# define uprv_invCharToAscii(c) (c)
+#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
+# define uprv_invCharToAscii(c) uprv_ebcdicToAscii(c)
+#else
+# error Unknown charset family!
+#endif
+
+/**
* Converts an EBCDIC invariant character to lowercase ASCII.
* @internal
*/
diff --git a/deps/icu-small/source/common/uloc.cpp b/deps/icu-small/source/common/uloc.cpp
index 73b43204b8..6a9bfcfbff 100644
--- a/deps/icu-small/source/common/uloc.cpp
+++ b/deps/icu-small/source/common/uloc.cpp
@@ -148,7 +148,8 @@ static const char * const LANGUAGES[] = {
"mad", "maf", "mag", "mai", "mak", "man", "mas", "mde",
"mdf", "mdh", "mdr", "men", "mer", "mfe", "mg", "mga",
"mgh", "mgo", "mh", "mi", "mic", "min", "mis", "mk",
- "ml", "mn", "mnc", "mni", "moh", "mos", "mr", "mrj",
+ "ml", "mn", "mnc", "mni", "mo",
+ "moh", "mos", "mr", "mrj",
"ms", "mt", "mua", "mul", "mus", "mwl", "mwr", "mwv",
"my", "mye", "myv", "mzn",
"na", "nan", "nap", "naq", "nb", "nd", "nds", "ne",
@@ -264,7 +265,8 @@ static const char * const LANGUAGES_3[] = {
"mad", "maf", "mag", "mai", "mak", "man", "mas", "mde",
"mdf", "mdh", "mdr", "men", "mer", "mfe", "mlg", "mga",
"mgh", "mgo", "mah", "mri", "mic", "min", "mis", "mkd",
- "mal", "mon", "mnc", "mni", "moh", "mos", "mar", "mrj",
+ "mal", "mon", "mnc", "mni", "mol",
+ "moh", "mos", "mar", "mrj",
"msa", "mlt", "mua", "mul", "mus", "mwl", "mwr", "mwv",
"mya", "mye", "myv", "mzn",
"nau", "nan", "nap", "naq", "nob", "nde", "nds", "nep",
@@ -480,14 +482,15 @@ static const CanonicalizationMap CANONICALIZE_MAP[] = {
/* Test if the locale id has BCP47 u extension and does not have '@' */
#define _hasBCP47Extension(id) (id && uprv_strstr(id, "@") == NULL && getShortestSubtagLength(localeID) == 1)
/* Converts the BCP47 id to Unicode id. Does nothing to id if conversion fails */
-#define _ConvertBCP47(finalID, id, buffer, length,err) \
- if (uloc_forLanguageTag(id, buffer, length, NULL, err) <= 0 || \
- U_FAILURE(*err) || *err == U_STRING_NOT_TERMINATED_WARNING) { \
- finalID=id; \
- if (*err == U_STRING_NOT_TERMINATED_WARNING) { *err = U_BUFFER_OVERFLOW_ERROR; } \
- } else { \
- finalID=buffer; \
- }
+#define _ConvertBCP47(finalID, id, buffer, length,err) UPRV_BLOCK_MACRO_BEGIN { \
+ if (uloc_forLanguageTag(id, buffer, length, NULL, err) <= 0 || \
+ U_FAILURE(*err) || *err == U_STRING_NOT_TERMINATED_WARNING) { \
+ finalID=id; \
+ if (*err == U_STRING_NOT_TERMINATED_WARNING) { *err = U_BUFFER_OVERFLOW_ERROR; } \
+ } else { \
+ finalID=buffer; \
+ } \
+} UPRV_BLOCK_MACRO_END
/* Gets the size of the shortest subtag in the given localeID. */
static int32_t getShortestSubtagLength(const char *localeID) {
int32_t localeIDLength = static_cast<int32_t>(uprv_strlen(localeID));
@@ -1454,31 +1457,29 @@ static const UEnumeration gKeywordsEnum = {
U_CAPI UEnumeration* U_EXPORT2
uloc_openKeywordList(const char *keywordList, int32_t keywordListSize, UErrorCode* status)
{
- UKeywordsContext *myContext = NULL;
- UEnumeration *result = NULL;
+ LocalMemory<UKeywordsContext> myContext;
+ LocalMemory<UEnumeration> result;
- if(U_FAILURE(*status)) {
- return NULL;
+ if (U_FAILURE(*status)) {
+ return nullptr;
}
- result = (UEnumeration *)uprv_malloc(sizeof(UEnumeration));
- /* Null pointer test */
- if (result == NULL) {
+ myContext.adoptInstead(static_cast<UKeywordsContext *>(uprv_malloc(sizeof(UKeywordsContext))));
+ result.adoptInstead(static_cast<UEnumeration *>(uprv_malloc(sizeof(UEnumeration))));
+ if (myContext.isNull() || result.isNull()) {
*status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
+ return nullptr;
}
- uprv_memcpy(result, &gKeywordsEnum, sizeof(UEnumeration));
- myContext = static_cast<UKeywordsContext *>(uprv_malloc(sizeof(UKeywordsContext)));
- if (myContext == NULL) {
+ uprv_memcpy(result.getAlias(), &gKeywordsEnum, sizeof(UEnumeration));
+ myContext->keywords = static_cast<char *>(uprv_malloc(keywordListSize+1));
+ if (myContext->keywords == nullptr) {
*status = U_MEMORY_ALLOCATION_ERROR;
- uprv_free(result);
- return NULL;
+ return nullptr;
}
- myContext->keywords = (char *)uprv_malloc(keywordListSize+1);
uprv_memcpy(myContext->keywords, keywordList, keywordListSize);
myContext->keywords[keywordListSize] = 0;
myContext->current = myContext->keywords;
- result->context = myContext;
- return result;
+ result->context = myContext.orphan();
+ return result.orphan();
}
U_CAPI UEnumeration* U_EXPORT2
diff --git a/deps/icu-small/source/common/uloc_tag.cpp b/deps/icu-small/source/common/uloc_tag.cpp
index c732170cb6..8f673541a7 100644
--- a/deps/icu-small/source/common/uloc_tag.cpp
+++ b/deps/icu-small/source/common/uloc_tag.cpp
@@ -1558,10 +1558,8 @@ _appendLDMLExtensionAsKeywords(const char* ldmlext, ExtensionListEntry** appendT
return;
}
- if (!_addAttributeToList(&attrFirst, attr)) {
- *status = U_ILLEGAL_ARGUMENT_ERROR;
- return;
- }
+ // duplicate attribute is ignored, causes no error.
+ _addAttributeToList(&attrFirst, attr);
/* next tag */
pTag += len;
diff --git a/deps/icu-small/source/common/umutex.cpp b/deps/icu-small/source/common/umutex.cpp
index 20b03d6cd3..ccbee9960a 100644
--- a/deps/icu-small/source/common/umutex.cpp
+++ b/deps/icu-small/source/common/umutex.cpp
@@ -24,6 +24,7 @@
#include "unicode/utypes.h"
#include "uassert.h"
+#include "ucln_cmn.h"
#include "cmemory.h"
U_NAMESPACE_BEGIN
@@ -35,60 +36,94 @@ U_NAMESPACE_BEGIN
#error U_USER_MUTEX_CPP not supported
#endif
+
/*************************************************************************************************
*
* ICU Mutex wrappers.
*
*************************************************************************************************/
-// The ICU global mutex. Used when ICU implementation code passes NULL for the mutex pointer.
-static UMutex *globalMutex() {
- static UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+namespace {
+std::mutex *initMutex;
+std::condition_variable *initCondition;
-U_CAPI void U_EXPORT2
-umtx_lock(UMutex *mutex) {
- if (mutex == nullptr) {
- mutex = globalMutex();
- }
- mutex->fMutex.lock();
-}
+// The ICU global mutex.
+// Used when ICU implementation code passes nullptr for the mutex pointer.
+UMutex globalMutex;
+std::once_flag initFlag;
+std::once_flag *pInitFlag = &initFlag;
-U_CAPI void U_EXPORT2
-umtx_unlock(UMutex* mutex)
-{
- if (mutex == nullptr) {
- mutex = globalMutex();
- }
- mutex->fMutex.unlock();
-}
+} // Anonymous namespace
-UConditionVar::UConditionVar() : fCV() {
+U_CDECL_BEGIN
+static UBool U_CALLCONV umtx_cleanup() {
+ initMutex->~mutex();
+ initCondition->~condition_variable();
+ UMutex::cleanup();
+
+ // Reset the once_flag, by destructing it and creating a fresh one in its place.
+ // Do not use this trick anywhere else in ICU; use umtx_initOnce, not std::call_once().
+ pInitFlag->~once_flag();
+ pInitFlag = new(&initFlag) std::once_flag();
+ return true;
}
-UConditionVar::~UConditionVar() {
+static void U_CALLCONV umtx_init() {
+ initMutex = STATIC_NEW(std::mutex);
+ initCondition = STATIC_NEW(std::condition_variable);
+ ucln_common_registerCleanup(UCLN_COMMON_MUTEX, umtx_cleanup);
+}
+U_CDECL_END
+
+
+std::mutex *UMutex::getMutex() {
+ std::mutex *retPtr = fMutex.load(std::memory_order_acquire);
+ if (retPtr == nullptr) {
+ std::call_once(*pInitFlag, umtx_init);
+ std::lock_guard<std::mutex> guard(*initMutex);
+ retPtr = fMutex.load(std::memory_order_acquire);
+ if (retPtr == nullptr) {
+ fMutex = new(fStorage) std::mutex();
+ retPtr = fMutex;
+ fListLink = gListHead;
+ gListHead = this;
+ }
+ }
+ U_ASSERT(retPtr != nullptr);
+ return retPtr;
}
-U_CAPI void U_EXPORT2
-umtx_condWait(UConditionVar *cond, UMutex *mutex) {
- if (mutex == nullptr) {
- mutex = globalMutex();
+UMutex *UMutex::gListHead = nullptr;
+
+void UMutex::cleanup() {
+ UMutex *next = nullptr;
+ for (UMutex *m = gListHead; m != nullptr; m = next) {
+ (*m->fMutex).~mutex();
+ m->fMutex = nullptr;
+ next = m->fListLink;
+ m->fListLink = nullptr;
}
- cond->fCV.wait(mutex->fMutex);
+ gListHead = nullptr;
}
-U_CAPI void U_EXPORT2
-umtx_condBroadcast(UConditionVar *cond) {
- cond->fCV.notify_all();
+U_CAPI void U_EXPORT2
+umtx_lock(UMutex *mutex) {
+ if (mutex == nullptr) {
+ mutex = &globalMutex;
+ }
+ mutex->lock();
}
-U_CAPI void U_EXPORT2
-umtx_condSignal(UConditionVar *cond) {
- cond->fCV.notify_one();
+U_CAPI void U_EXPORT2
+umtx_unlock(UMutex* mutex)
+{
+ if (mutex == nullptr) {
+ mutex = &globalMutex;
+ }
+ mutex->unlock();
}
@@ -98,17 +133,6 @@ umtx_condSignal(UConditionVar *cond) {
*
*************************************************************************************************/
-static std::mutex &initMutex() {
- static std::mutex m;
- return m;
-}
-
-static std::condition_variable &initCondition() {
- static std::condition_variable cv;
- return cv;
-}
-
-
// This function is called when a test of a UInitOnce::fState reveals that
// initialization has not completed, that we either need to call the init
// function on this thread, or wait for some other thread to complete.
@@ -119,8 +143,8 @@ static std::condition_variable &initCondition() {
//
U_COMMON_API UBool U_EXPORT2
umtx_initImplPreInit(UInitOnce &uio) {
- std::unique_lock<std::mutex> lock(initMutex());
-
+ std::call_once(*pInitFlag, umtx_init);
+ std::unique_lock<std::mutex> lock(*initMutex);
if (umtx_loadAcquire(uio.fState) == 0) {
umtx_storeRelease(uio.fState, 1);
return true; // Caller will next call the init function.
@@ -128,7 +152,7 @@ umtx_initImplPreInit(UInitOnce &uio) {
while (umtx_loadAcquire(uio.fState) == 1) {
// Another thread is currently running the initialization.
// Wait until it completes.
- initCondition().wait(lock);
+ initCondition->wait(lock);
}
U_ASSERT(uio.fState == 2);
return false;
@@ -145,10 +169,10 @@ umtx_initImplPreInit(UInitOnce &uio) {
U_COMMON_API void U_EXPORT2
umtx_initImplPostInit(UInitOnce &uio) {
{
- std::unique_lock<std::mutex> lock(initMutex());
+ std::unique_lock<std::mutex> lock(*initMutex);
umtx_storeRelease(uio.fState, 2);
}
- initCondition().notify_all();
+ initCondition->notify_all();
}
U_NAMESPACE_END
diff --git a/deps/icu-small/source/common/umutex.h b/deps/icu-small/source/common/umutex.h
index 1674d00bb2..7588bcc5d9 100755
--- a/deps/icu-small/source/common/umutex.h
+++ b/deps/icu-small/source/common/umutex.h
@@ -23,6 +23,7 @@
#include <atomic>
#include <condition_variable>
#include <mutex>
+#include <type_traits>
#include "unicode/utypes.h"
#include "unicode/uclean.h"
@@ -36,10 +37,11 @@
#error U_USER_ATOMICS and U_USER_MUTEX_H are not supported
#endif
-
// Export an explicit template instantiation of std::atomic<int32_t>.
// When building DLLs for Windows this is required as it is used as a data member of the exported SharedObject class.
// See digitlst.h, pluralaffix.h, datefmt.h, and others for similar examples.
+//
+// Similar story for std::atomic<std::mutex *>, and the exported UMutex class.
#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN && !defined(U_IN_DOXYGEN)
#if defined(__clang__) || defined(_MSC_VER)
#if defined(__clang__)
@@ -48,12 +50,14 @@
#pragma clang diagnostic ignored "-Winstantiation-after-specialization"
#endif
template struct U_COMMON_API std::atomic<int32_t>;
+template struct U_COMMON_API std::atomic<std::mutex *>;
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
#elif defined(__GNUC__)
// For GCC this class is already exported/visible, so no need for U_COMMON_API.
template struct std::atomic<int32_t>;
+template struct std::atomic<std::mutex *>;
#endif
#endif
@@ -180,49 +184,78 @@ template<class T> void umtx_initOnce(UInitOnce &uio, void (U_CALLCONV *fp)(T, UE
}
}
+// UMutex should be constexpr-constructible, so that no initialization code
+// is run during startup.
+// This works on all C++ libraries except MS VS before VS2019.
+#if (defined(_CPPLIB_VER) && !defined(_MSVC_STL_VERSION)) || \
+ (defined(_MSVC_STL_VERSION) && _MSVC_STL_VERSION < 142)
+ // (VS std lib older than VS2017) || (VS std lib version < VS2019)
+# define UMUTEX_CONSTEXPR
+#else
+# define UMUTEX_CONSTEXPR constexpr
+#endif
-/*************************************************************************************************
+/**
+ * UMutex - ICU Mutex class.
*
- * ICU Mutex wrappers. Originally wrapped operating system mutexes, giving the rest of ICU a
- * platform independent set of mutex operations. Now vestigial, wrapping std::mutex only.
- * For internal ICU use only.
+ * This is the preferred Mutex class for use within ICU implementation code.
+ * It is a thin wrapper over C++ std::mutex, with these additions:
+ * - Static instances are safe, not triggering static construction or destruction,
+ * and the associated order of construction or destruction issues.
+ * - Plumbed into u_cleanup() for destructing the underlying std::mutex,
+ * which frees any OS level resources they may be holding.
*
- *************************************************************************************************/
+ * Limitations:
+ * - Static or global instances only. Cannot be heap allocated. Cannot appear as a
+ * member of another class.
+ * - No condition variables or other advanced features. If needed, you will need to use
+ * std::mutex and std::condition_variable directly. For an example, see unifiedcache.cpp
+ *
+ * Typical Usage:
+ * static UMutex myMutex;
+ *
+ * {
+ * Mutex lock(myMutex);
+ * ... // Do stuff that is protected by myMutex;
+ * } // myMutex is released when lock goes out of scope.
+ */
-struct UMutex : public icu::UMemory {
- UMutex() = default;
+class U_COMMON_API UMutex {
+public:
+ UMUTEX_CONSTEXPR UMutex() {}
~UMutex() = default;
+
UMutex(const UMutex &other) = delete;
UMutex &operator =(const UMutex &other) = delete;
+ void *operator new(size_t) = delete;
- std::mutex fMutex = {}; // Note: struct - pubic members - because most access is from
- // // plain C style functions (umtx_lock(), etc.)
-};
+ // requirements for C++ BasicLockable, allows UMutex to work with std::lock_guard
+ void lock() {
+ std::mutex *m = fMutex.load(std::memory_order_acquire);
+ if (m == nullptr) { m = getMutex(); }
+ m->lock();
+ }
+ void unlock() { fMutex.load(std::memory_order_relaxed)->unlock(); }
+ static void cleanup();
-struct UConditionVar : public icu::UMemory {
- U_COMMON_API UConditionVar();
- U_COMMON_API ~UConditionVar();
- UConditionVar(const UConditionVar &other) = delete;
- UConditionVar &operator =(const UConditionVar &other) = delete;
+private:
+ alignas(std::mutex) char fStorage[sizeof(std::mutex)] {};
+ std::atomic<std::mutex *> fMutex { nullptr };
- std::condition_variable_any fCV;
-};
+ /** All initialized UMutexes are kept in a linked list, so that they can be found,
+ * and the underlying std::mutex destructed, by u_cleanup().
+ */
+ UMutex *fListLink { nullptr };
+ static UMutex *gListHead;
-#define U_MUTEX_INITIALIZER {}
-#define U_CONDITION_INITIALIZER {}
+ /** Out-of-line function to lazily initialize a UMutex on first use.
+ * Initial fast check is inline, in lock(). The returned value may never
+ * be nullptr.
+ */
+ std::mutex *getMutex();
+};
-// Implementation notes for UConditionVar:
-//
-// Use an out-of-line constructor to reduce problems with the ICU dependency checker.
-// On Linux, the default constructor of std::condition_variable_any
-// produces an in-line reference to global operator new(), which the
-// dependency checker flags for any file that declares a UConditionVar. With
-// an out-of-line constructor, the dependency is constrained to umutex.o
-//
-// Do not export (U_COMMON_API) the entire class, but only the constructor
-// and destructor, to avoid Windows build problems with attempting to export the
-// std::condition_variable_any.
/* Lock a mutex.
* @param mutex The given mutex to be locked. Pass NULL to specify
@@ -237,30 +270,6 @@ U_INTERNAL void U_EXPORT2 umtx_lock(UMutex* mutex);
*/
U_INTERNAL void U_EXPORT2 umtx_unlock (UMutex* mutex);
-/*
- * Wait on a condition variable.
- * The calling thread will unlock the mutex and wait on the condition variable.
- * The mutex must be locked by the calling thread when invoking this function.
- *
- * @param cond the condition variable to wait on.
- * @param mutex the associated mutex.
- */
-
-U_INTERNAL void U_EXPORT2 umtx_condWait(UConditionVar *cond, UMutex *mutex);
-
-
-/*
- * Broadcast wakeup of all threads waiting on a Condition.
- *
- * @param cond the condition variable.
- */
-U_INTERNAL void U_EXPORT2 umtx_condBroadcast(UConditionVar *cond);
-
-/*
- * Signal a condition variable, waking up one waiting thread.
- */
-U_INTERNAL void U_EXPORT2 umtx_condSignal(UConditionVar *cond);
-
U_NAMESPACE_END
diff --git a/deps/icu-small/source/common/unames.cpp b/deps/icu-small/source/common/unames.cpp
index 038743004e..a28b6ee603 100644
--- a/deps/icu-small/source/common/unames.cpp
+++ b/deps/icu-small/source/common/unames.cpp
@@ -212,13 +212,13 @@ isDataLoaded(UErrorCode *pErrorCode) {
return U_SUCCESS(*pErrorCode);
}
-#define WRITE_CHAR(buffer, bufferLength, bufferPos, c) { \
+#define WRITE_CHAR(buffer, bufferLength, bufferPos, c) UPRV_BLOCK_MACRO_BEGIN { \
if((bufferLength)>0) { \
*(buffer)++=c; \
--(bufferLength); \
} \
++(bufferPos); \
-}
+} UPRV_BLOCK_MACRO_END
#define U_ISO_COMMENT U_CHAR_NAME_CHOICE_COUNT
diff --git a/deps/icu-small/source/common/unicode/appendable.h b/deps/icu-small/source/common/unicode/appendable.h
index 8512c2f303..4beacaf658 100644
--- a/deps/icu-small/source/common/unicode/appendable.h
+++ b/deps/icu-small/source/common/unicode/appendable.h
@@ -23,6 +23,9 @@
*/
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/uobject.h"
U_NAMESPACE_BEGIN
@@ -231,4 +234,6 @@ private:
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __APPENDABLE_H__
diff --git a/deps/icu-small/source/common/unicode/brkiter.h b/deps/icu-small/source/common/unicode/brkiter.h
index ac1bf1df29..b944497345 100644
--- a/deps/icu-small/source/common/unicode/brkiter.h
+++ b/deps/icu-small/source/common/unicode/brkiter.h
@@ -29,6 +29,10 @@
* \brief C++ API: Break Iterator.
*/
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#if UCONFIG_NO_BREAK_ITERATION
U_NAMESPACE_BEGIN
@@ -135,7 +139,7 @@ public:
* method which subclasses implement.
* @stable ICU 2.0
*/
- virtual BreakIterator* clone(void) const = 0;
+ virtual BreakIterator* clone() const = 0;
/**
* Return a polymorphic class ID for this object. Different subclasses
@@ -493,6 +497,7 @@ public:
static UnicodeString& U_EXPORT2 getDisplayName(const Locale& objectLocale,
UnicodeString& name);
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Deprecated functionality. Use clone() instead.
*
@@ -515,6 +520,7 @@ public:
virtual BreakIterator * createBufferClone(void *stackBuffer,
int32_t &BufferSize,
UErrorCode &status) = 0;
+#endif // U_FORCE_HIDE_DEPRECATED_API
#ifndef U_HIDE_DEPRECATED_API
@@ -658,5 +664,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // BRKITER_H
//eof
diff --git a/deps/icu-small/source/common/unicode/bytestream.h b/deps/icu-small/source/common/unicode/bytestream.h
index 61d1e8aca6..2c71c248e3 100644
--- a/deps/icu-small/source/common/unicode/bytestream.h
+++ b/deps/icu-small/source/common/unicode/bytestream.h
@@ -38,6 +38,9 @@
*/
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/uobject.h"
#include "unicode/std_string.h"
@@ -267,4 +270,6 @@ class StringByteSink : public ByteSink {
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __BYTESTREAM_H__
diff --git a/deps/icu-small/source/common/unicode/bytestrie.h b/deps/icu-small/source/common/unicode/bytestrie.h
index c57b8ccfeb..51405f64a1 100644
--- a/deps/icu-small/source/common/unicode/bytestrie.h
+++ b/deps/icu-small/source/common/unicode/bytestrie.h
@@ -23,6 +23,9 @@
*/
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/stringpiece.h"
#include "unicode/uobject.h"
#include "unicode/ustringtrie.h"
@@ -94,6 +97,41 @@ public:
return *this;
}
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Returns the state of this trie as a 64-bit integer.
+ * The state value is never 0.
+ *
+ * @return opaque state value
+ * @see resetToState64
+ * @draft ICU 65
+ */
+ uint64_t getState64() const {
+ return (static_cast<uint64_t>(remainingMatchLength_ + 2) << kState64RemainingShift) |
+ (uint64_t)(pos_ - bytes_);
+ }
+
+ /**
+ * Resets this trie to the saved state.
+ * Unlike resetToState(State), the 64-bit state value
+ * must be from getState64() from the same trie object or
+ * from one initialized the exact same way.
+ * Because of no validation, this method is faster.
+ *
+ * @param state The opaque trie state value from getState64().
+ * @return *this
+ * @see getState64
+ * @see resetToState
+ * @see reset
+ * @draft ICU 65
+ */
+ BytesTrie &resetToState64(uint64_t state) {
+ remainingMatchLength_ = static_cast<int32_t>(state >> kState64RemainingShift) - 2;
+ pos_ = bytes_ + (state & kState64PosMask);
+ return *this;
+ }
+#endif /* U_HIDE_DRAFT_API */
+
/**
* BytesTrie state object, for saving a trie's current state
* and resetting the trie back to this state later.
@@ -502,6 +540,13 @@ private:
static const int32_t kMaxTwoByteDelta=((kMinThreeByteDeltaLead-kMinTwoByteDeltaLead)<<8)-1; // 0x2fff
static const int32_t kMaxThreeByteDelta=((kFourByteDeltaLead-kMinThreeByteDeltaLead)<<16)-1; // 0xdffff
+ // For getState64():
+ // The remainingMatchLength_ is -1..14=(kMaxLinearMatchLength=0x10)-2
+ // so we need at least 5 bits for that.
+ // We add 2 to store it as a positive value 1..16=kMaxLinearMatchLength.
+ static constexpr int32_t kState64RemainingShift = 59;
+ static constexpr uint64_t kState64PosMask = (UINT64_C(1) << kState64RemainingShift) - 1;
+
uint8_t *ownedArray_;
// Fixed value referencing the BytesTrie bytes.
@@ -517,4 +562,6 @@ private:
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __BYTESTRIE_H__
diff --git a/deps/icu-small/source/common/unicode/bytestriebuilder.h b/deps/icu-small/source/common/unicode/bytestriebuilder.h
index b164e3bbd6..e58f18755e 100644
--- a/deps/icu-small/source/common/unicode/bytestriebuilder.h
+++ b/deps/icu-small/source/common/unicode/bytestriebuilder.h
@@ -23,6 +23,9 @@
#define __BYTESTRIEBUILDER_H__
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/bytestrie.h"
#include "unicode/stringpiece.h"
#include "unicode/stringtriebuilder.h"
@@ -179,4 +182,6 @@ private:
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __BYTESTRIEBUILDER_H__
diff --git a/deps/icu-small/source/common/unicode/caniter.h b/deps/icu-small/source/common/unicode/caniter.h
index b47e35da07..87c946c2b4 100644
--- a/deps/icu-small/source/common/unicode/caniter.h
+++ b/deps/icu-small/source/common/unicode/caniter.h
@@ -12,6 +12,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_NORMALIZATION
#include "unicode/uobject.h"
@@ -207,4 +209,6 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_NORMALIZATION */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/casemap.h b/deps/icu-small/source/common/unicode/casemap.h
index 477eb484d1..53af84fa74 100644
--- a/deps/icu-small/source/common/unicode/casemap.h
+++ b/deps/icu-small/source/common/unicode/casemap.h
@@ -8,6 +8,9 @@
#define __CASEMAP_H__
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/stringpiece.h"
#include "unicode/uobject.h"
@@ -489,4 +492,6 @@ private:
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __CASEMAP_H__
diff --git a/deps/icu-small/source/common/unicode/char16ptr.h b/deps/icu-small/source/common/unicode/char16ptr.h
index a7c5f1a0c5..c8a9ae6c35 100644
--- a/deps/icu-small/source/common/unicode/char16ptr.h
+++ b/deps/icu-small/source/common/unicode/char16ptr.h
@@ -7,9 +7,12 @@
#ifndef __CHAR16PTR_H__
#define __CHAR16PTR_H__
-#include <cstddef>
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
+#include <cstddef>
+
/**
* \file
* \brief C++ API: char16_t pointer wrappers with
@@ -305,4 +308,6 @@ inline OldUChar *toOldUCharPtr(char16_t *p) {
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __CHAR16PTR_H__
diff --git a/deps/icu-small/source/common/unicode/chariter.h b/deps/icu-small/source/common/unicode/chariter.h
index 292794f6d6..7e4f446bb0 100644
--- a/deps/icu-small/source/common/unicode/chariter.h
+++ b/deps/icu-small/source/common/unicode/chariter.h
@@ -13,6 +13,9 @@
#define CHARITER_H
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/uobject.h"
#include "unicode/unistr.h"
/**
@@ -377,7 +380,7 @@ public:
* @return a pointer to a new CharacterIterator
* @stable ICU 2.0
*/
- virtual CharacterIterator* clone(void) const = 0;
+ virtual CharacterIterator* clone() const = 0;
/**
* Sets the iterator to refer to the first code unit in its
@@ -725,4 +728,7 @@ CharacterIterator::getLength(void) const {
}
U_NAMESPACE_END
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/dbbi.h b/deps/icu-small/source/common/unicode/dbbi.h
index 62509c5227..9031c0b96b 100644
--- a/deps/icu-small/source/common/unicode/dbbi.h
+++ b/deps/icu-small/source/common/unicode/dbbi.h
@@ -13,6 +13,10 @@
#ifndef DBBI_H
#define DBBI_H
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/rbbi.h"
#if !UCONFIG_NO_BREAK_ITERATION
@@ -39,4 +43,6 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/docmain.h b/deps/icu-small/source/common/unicode/docmain.h
index 8990679987..2b38692997 100644
--- a/deps/icu-small/source/common/unicode/docmain.h
+++ b/deps/icu-small/source/common/unicode/docmain.h
@@ -99,7 +99,7 @@
* </tr>
* <tr>
* <td>Codepage Conversion</td>
- * <td>ucnv.h, ucnvsel.hb</td>
+ * <td>ucnv.h, ucnvsel.h</td>
* <td>C API</td>
* </tr>
* <tr>
@@ -115,7 +115,7 @@
* <tr>
* <td>Locales </td>
* <td>uloc.h</a></td>
- * <td>icu::Locale, icu::LocaleBuilder</td>
+ * <td>icu::Locale, icu::LocaleBuilder, icu::LocaleMatcher</td>
* </tr>
* <tr>
* <td>Resource Bundles</td>
diff --git a/deps/icu-small/source/common/unicode/dtintrv.h b/deps/icu-small/source/common/unicode/dtintrv.h
index 625456f0c8..325faa3ccb 100644
--- a/deps/icu-small/source/common/unicode/dtintrv.h
+++ b/deps/icu-small/source/common/unicode/dtintrv.h
@@ -15,6 +15,9 @@
#define __DTINTRV_H__
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/uobject.h"
/**
@@ -22,7 +25,6 @@
* \brief C++ API: Date Interval data type
*/
-
U_NAMESPACE_BEGIN
@@ -157,4 +159,6 @@ DateInterval::operator!=(const DateInterval& other) const {
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/edits.h b/deps/icu-small/source/common/unicode/edits.h
index 79e98b0cc2..c3ceaccb3b 100644
--- a/deps/icu-small/source/common/unicode/edits.h
+++ b/deps/icu-small/source/common/unicode/edits.h
@@ -8,6 +8,9 @@
#define __EDITS_H__
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/uobject.h"
/**
@@ -159,7 +162,7 @@ public:
* @return TRUE if U_FAILURE(outErrorCode)
* @stable ICU 59
*/
- UBool copyErrorTo(UErrorCode &outErrorCode);
+ UBool copyErrorTo(UErrorCode &outErrorCode) const;
/**
* How much longer is the new text compared with the old text?
@@ -523,4 +526,6 @@ private:
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __EDITS_H__
diff --git a/deps/icu-small/source/common/unicode/errorcode.h b/deps/icu-small/source/common/unicode/errorcode.h
index 1e5df8f03e..75cdbb6a98 100644
--- a/deps/icu-small/source/common/unicode/errorcode.h
+++ b/deps/icu-small/source/common/unicode/errorcode.h
@@ -26,6 +26,9 @@
*/
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/uobject.h"
U_NAMESPACE_BEGIN
@@ -136,4 +139,6 @@ protected:
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __ERRORCODE_H__
diff --git a/deps/icu-small/source/common/unicode/filteredbrk.h b/deps/icu-small/source/common/unicode/filteredbrk.h
index 2444114e9a..4293676325 100644
--- a/deps/icu-small/source/common/unicode/filteredbrk.h
+++ b/deps/icu-small/source/common/unicode/filteredbrk.h
@@ -11,6 +11,9 @@
#define FILTEREDBRK_H
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/brkiter.h"
#if !UCONFIG_NO_BREAK_ITERATION && !UCONFIG_NO_FILTERED_BREAK_ITERATION
@@ -101,6 +104,7 @@ class U_COMMON_API FilteredBreakIteratorBuilder : public UObject {
*/
virtual UBool unsuppressBreakAfter(const UnicodeString& string, UErrorCode& status) = 0;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* This function has been deprecated in favor of wrapIteratorWithFilter()
* The behavior is identical.
@@ -111,6 +115,7 @@ class U_COMMON_API FilteredBreakIteratorBuilder : public UObject {
* @see wrapBreakIteratorWithFilter()
*/
virtual BreakIterator *build(BreakIterator* adoptBreakIterator, UErrorCode& status) = 0;
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Wrap (adopt) an existing break iterator in a new filtered instance.
@@ -142,4 +147,6 @@ U_NAMESPACE_END
#endif // #if !UCONFIG_NO_BREAK_ITERATION && !UCONFIG_NO_FILTERED_BREAK_ITERATION
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // #ifndef FILTEREDBRK_H
diff --git a/deps/icu-small/source/common/unicode/idna.h b/deps/icu-small/source/common/unicode/idna.h
index f08658e502..6dfcfe48db 100644
--- a/deps/icu-small/source/common/unicode/idna.h
+++ b/deps/icu-small/source/common/unicode/idna.h
@@ -24,6 +24,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_IDNA
#include "unicode/bytestream.h"
@@ -322,4 +324,7 @@ private:
U_NAMESPACE_END
#endif // UCONFIG_NO_IDNA
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __IDNA_H__
diff --git a/deps/icu-small/source/common/unicode/localebuilder.h b/deps/icu-small/source/common/unicode/localebuilder.h
index 960e5980c0..19e10f1c07 100644
--- a/deps/icu-small/source/common/unicode/localebuilder.h
+++ b/deps/icu-small/source/common/unicode/localebuilder.h
@@ -3,11 +3,14 @@
#ifndef __LOCALEBUILDER_H__
#define __LOCALEBUILDER_H__
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/locid.h"
+#include "unicode/localematcher.h"
#include "unicode/stringpiece.h"
#include "unicode/uobject.h"
-#include "unicode/utypes.h"
-
#ifndef U_HIDE_DRAFT_API
/**
@@ -276,7 +279,24 @@ public:
*/
Locale build(UErrorCode& status);
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Sets the UErrorCode if an error occurred while recording sets.
+ * Preserves older error codes in the outErrorCode.
+ * @param outErrorCode Set to an error code that occurred while setting subtags.
+ * Unchanged if there is no such error or if outErrorCode
+ * already contained an error.
+ * @return TRUE if U_FAILURE(outErrorCode)
+ * @draft ICU 65
+ */
+ UBool copyErrorTo(UErrorCode &outErrorCode) const;
+#endif /* U_HIDE_DRAFT_API */
+
private:
+ friend class LocaleMatcher::Result;
+
+ void copyExtensionsFrom(const Locale& src, UErrorCode& errorCode);
+
UErrorCode status_;
char language_[9];
char script_[5];
@@ -289,4 +309,7 @@ private:
U_NAMESPACE_END
#endif // U_HIDE_DRAFT_API
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __LOCALEBUILDER_H__
diff --git a/deps/icu-small/source/common/unicode/localematcher.h b/deps/icu-small/source/common/unicode/localematcher.h
new file mode 100644
index 0000000000..701123f750
--- /dev/null
+++ b/deps/icu-small/source/common/unicode/localematcher.h
@@ -0,0 +1,605 @@
+// © 2019 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+
+// localematcher.h
+// created: 2019may08 Markus W. Scherer
+
+#ifndef __LOCALEMATCHER_H__
+#define __LOCALEMATCHER_H__
+
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
+#include "unicode/locid.h"
+#include "unicode/stringpiece.h"
+#include "unicode/uobject.h"
+
+/**
+ * \file
+ * \brief C++ API: Locale matcher: User's desired locales vs. application's supported locales.
+ */
+
+#ifndef U_HIDE_DRAFT_API
+
+/**
+ * Builder option for whether the language subtag or the script subtag is most important.
+ *
+ * @see Builder#setFavorSubtag(FavorSubtag)
+ * @draft ICU 65
+ */
+enum ULocMatchFavorSubtag {
+ /**
+ * Language differences are most important, then script differences, then region differences.
+ * (This is the default behavior.)
+ *
+ * @draft ICU 65
+ */
+ ULOCMATCH_FAVOR_LANGUAGE,
+ /**
+ * Makes script differences matter relatively more than language differences.
+ *
+ * @draft ICU 65
+ */
+ ULOCMATCH_FAVOR_SCRIPT
+};
+#ifndef U_IN_DOXYGEN
+typedef enum ULocMatchFavorSubtag ULocMatchFavorSubtag;
+#endif
+
+/**
+ * Builder option for whether all desired locales are treated equally or
+ * earlier ones are preferred.
+ *
+ * @see Builder#setDemotionPerDesiredLocale(Demotion)
+ * @draft ICU 65
+ */
+enum ULocMatchDemotion {
+ /**
+ * All desired locales are treated equally.
+ *
+ * @draft ICU 65
+ */
+ ULOCMATCH_DEMOTION_NONE,
+ /**
+ * Earlier desired locales are preferred.
+ *
+ * <p>From each desired locale to the next,
+ * the distance to any supported locale is increased by an additional amount
+ * which is at least as large as most region mismatches.
+ * A later desired locale has to have a better match with some supported locale
+ * due to more than merely having the same region subtag.
+ *
+ * <p>For example: <code>Supported={en, sv} desired=[en-GB, sv]</code>
+ * yields <code>Result(en-GB, en)</code> because
+ * with the demotion of sv its perfect match is no better than
+ * the region distance between the earlier desired locale en-GB and en=en-US.
+ *
+ * <p>Notes:
+ * <ul>
+ * <li>In some cases, language and/or script differences can be as small as
+ * the typical region difference. (Example: sr-Latn vs. sr-Cyrl)
+ * <li>It is possible for certain region differences to be larger than usual,
+ * and larger than the demotion.
+ * (As of CLDR 35 there is no such case, but
+ * this is possible in future versions of the data.)
+ * </ul>
+ *
+ * @draft ICU 65
+ */
+ ULOCMATCH_DEMOTION_REGION
+};
+#ifndef U_IN_DOXYGEN
+typedef enum ULocMatchDemotion ULocMatchDemotion;
+#endif
+
+struct UHashtable;
+
+U_NAMESPACE_BEGIN
+
+struct LSR;
+
+class LocaleDistance;
+class LocaleLsrIterator;
+class UVector;
+class XLikelySubtags;
+
+/**
+ * Immutable class that picks the best match between a user's desired locales and
+ * an application's supported locales.
+ * Movable but not copyable.
+ *
+ * <p>Example:
+ * <pre>
+ * UErrorCode errorCode = U_ZERO_ERROR;
+ * LocaleMatcher matcher = LocaleMatcher::Builder().setSupportedLocales("fr, en-GB, en").build(errorCode);
+ * Locale *bestSupported = matcher.getBestLocale(Locale.US, errorCode); // "en"
+ * </pre>
+ *
+ * <p>A matcher takes into account when languages are close to one another,
+ * such as Danish and Norwegian,
+ * and when regional variants are close, like en-GB and en-AU as opposed to en-US.
+ *
+ * <p>If there are multiple supported locales with the same (language, script, region)
+ * likely subtags, then the current implementation returns the first of those locales.
+ * It ignores variant subtags (except for pseudolocale variants) and extensions.
+ * This may change in future versions.
+ *
+ * <p>For example, the current implementation does not distinguish between
+ * de, de-DE, de-Latn, de-1901, de-u-co-phonebk.
+ *
+ * <p>If you prefer one equivalent locale over another, then provide only the preferred one,
+ * or place it earlier in the list of supported locales.
+ *
+ * <p>Otherwise, the order of supported locales may have no effect on the best-match results.
+ * The current implementation compares each desired locale with supported locales
+ * in the following order:
+ * 1. Default locale, if supported;
+ * 2. CLDR "paradigm locales" like en-GB and es-419;
+ * 3. other supported locales.
+ * This may change in future versions.
+ *
+ * <p>Often a product will just need one matcher instance, built with the languages
+ * that it supports. However, it may want multiple instances with different
+ * default languages based on additional information, such as the domain.
+ *
+ * <p>This class is not intended for public subclassing.
+ *
+ * @draft ICU 65
+ */
+class U_COMMON_API LocaleMatcher : public UMemory {
+public:
+ /**
+ * Data for the best-matching pair of a desired and a supported locale.
+ * Movable but not copyable.
+ *
+ * @draft ICU 65
+ */
+ class U_COMMON_API Result : public UMemory {
+ public:
+ /**
+ * Move constructor; might modify the source.
+ * This object will have the same contents that the source object had.
+ *
+ * @param src Result to move contents from.
+ * @draft ICU 65
+ */
+ Result(Result &&src) U_NOEXCEPT;
+
+ /**
+ * Destructor.
+ *
+ * @draft ICU 65
+ */
+ ~Result();
+
+ /**
+ * Move assignment; might modify the source.
+ * This object will have the same contents that the source object had.
+ *
+ * @param src Result to move contents from.
+ * @draft ICU 65
+ */
+ Result &operator=(Result &&src) U_NOEXCEPT;
+
+ /**
+ * Returns the best-matching desired locale.
+ * nullptr if the list of desired locales is empty or if none matched well enough.
+ *
+ * @return the best-matching desired locale, or nullptr.
+ * @draft ICU 65
+ */
+ inline const Locale *getDesiredLocale() const { return desiredLocale; }
+
+ /**
+ * Returns the best-matching supported locale.
+ * If none matched well enough, this is the default locale.
+ * The default locale is nullptr if the list of supported locales is empty and
+ * no explicit default locale is set.
+ *
+ * @return the best-matching supported locale, or nullptr.
+ * @draft ICU 65
+ */
+ inline const Locale *getSupportedLocale() const { return supportedLocale; }
+
+ /**
+ * Returns the index of the best-matching desired locale in the input Iterable order.
+ * -1 if the list of desired locales is empty or if none matched well enough.
+ *
+ * @return the index of the best-matching desired locale, or -1.
+ * @draft ICU 65
+ */
+ inline int32_t getDesiredIndex() const { return desiredIndex; }
+
+ /**
+ * Returns the index of the best-matching supported locale in the
+ * constructor’s or builder’s input order (“set” Collection plus “added” locales).
+ * If the matcher was built from a locale list string, then the iteration order is that
+ * of a LocalePriorityList built from the same string.
+ * -1 if the list of supported locales is empty or if none matched well enough.
+ *
+ * @return the index of the best-matching supported locale, or -1.
+ * @draft ICU 65
+ */
+ inline int32_t getSupportedIndex() const { return supportedIndex; }
+
+ /**
+ * Takes the best-matching supported locale and adds relevant fields of the
+ * best-matching desired locale, such as the -t- and -u- extensions.
+ * May replace some fields of the supported locale.
+ * The result is the locale that should be used for date and number formatting, collation, etc.
+ * Returns the root locale if getSupportedLocale() returns nullptr.
+ *
+ * <p>Example: desired=ar-SA-u-nu-latn, supported=ar-EG, resolved locale=ar-SA-u-nu-latn
+ *
+ * @return a locale combining the best-matching desired and supported locales.
+ * @draft ICU 65
+ */
+ Locale makeResolvedLocale(UErrorCode &errorCode) const;
+
+ private:
+ Result(const Locale *desired, const Locale *supported,
+ int32_t desIndex, int32_t suppIndex, UBool owned) :
+ desiredLocale(desired), supportedLocale(supported),
+ desiredIndex(desIndex), supportedIndex(suppIndex),
+ desiredIsOwned(owned) {}
+
+ Result(const Result &other) = delete;
+ Result &operator=(const Result &other) = delete;
+
+ const Locale *desiredLocale;
+ const Locale *supportedLocale;
+ int32_t desiredIndex;
+ int32_t supportedIndex;
+ UBool desiredIsOwned;
+
+ friend class LocaleMatcher;
+ };
+
+ /**
+ * LocaleMatcher builder.
+ * Movable but not copyable.
+ *
+ * @see LocaleMatcher#builder()
+ * @draft ICU 65
+ */
+ class U_COMMON_API Builder : public UMemory {
+ public:
+ /**
+ * Constructs a builder used in chaining parameters for building a LocaleMatcher.
+ *
+ * @return a new Builder object
+ * @draft ICU 65
+ */
+ Builder() {}
+
+ /**
+ * Move constructor; might modify the source.
+ * This builder will have the same contents that the source builder had.
+ *
+ * @param src Builder to move contents from.
+ * @draft ICU 65
+ */
+ Builder(Builder &&src) U_NOEXCEPT;
+
+ /**
+ * Destructor.
+ *
+ * @draft ICU 65
+ */
+ ~Builder();
+
+ /**
+ * Move assignment; might modify the source.
+ * This builder will have the same contents that the source builder had.
+ *
+ * @param src Builder to move contents from.
+ * @draft ICU 65
+ */
+ Builder &operator=(Builder &&src) U_NOEXCEPT;
+
+ /**
+ * Parses an Accept-Language string
+ * (<a href="https://tools.ietf.org/html/rfc2616#section-14.4">RFC 2616 Section 14.4</a>),
+ * such as "af, en, fr;q=0.9", and sets the supported locales accordingly.
+ * Allows whitespace in more places but does not allow "*".
+ * Clears any previously set/added supported locales first.
+ *
+ * @param locales the Accept-Language string of locales to set
+ * @return this Builder object
+ * @draft ICU 65
+ */
+ Builder &setSupportedLocalesFromListString(StringPiece locales);
+
+ /**
+ * Copies the supported locales, preserving iteration order.
+ * Clears any previously set/added supported locales first.
+ * Duplicates are allowed, and are not removed.
+ *
+ * @param locales the list of locale
+ * @return this Builder object
+ * @draft ICU 65
+ */
+ Builder &setSupportedLocales(Locale::Iterator &locales);
+
+ /**
+ * Copies the supported locales from the begin/end range, preserving iteration order.
+ * Clears any previously set/added supported locales first.
+ * Duplicates are allowed, and are not removed.
+ *
+ * Each of the iterator parameter values must be an
+ * input iterator whose value is convertible to const Locale &.
+ *
+ * @param begin Start of range.
+ * @param end Exclusive end of range.
+ * @return this Builder object
+ * @draft ICU 65
+ */
+ template<typename Iter>
+ Builder &setSupportedLocales(Iter begin, Iter end) {
+ if (U_FAILURE(errorCode_)) { return *this; }
+ clearSupportedLocales();
+ while (begin != end) {
+ addSupportedLocale(*begin++);
+ }
+ return *this;
+ }
+
+ /**
+ * Copies the supported locales from the begin/end range, preserving iteration order.
+ * Calls the converter to convert each *begin to a Locale or const Locale &.
+ * Clears any previously set/added supported locales first.
+ * Duplicates are allowed, and are not removed.
+ *
+ * Each of the iterator parameter values must be an
+ * input iterator whose value is convertible to const Locale &.
+ *
+ * @param begin Start of range.
+ * @param end Exclusive end of range.
+ * @param converter Converter from *begin to const Locale & or compatible.
+ * @return this Builder object
+ * @draft ICU 65
+ */
+ template<typename Iter, typename Conv>
+ Builder &setSupportedLocalesViaConverter(Iter begin, Iter end, Conv converter) {
+ if (U_FAILURE(errorCode_)) { return *this; }
+ clearSupportedLocales();
+ while (begin != end) {
+ addSupportedLocale(converter(*begin++));
+ }
+ return *this;
+ }
+
+ /**
+ * Adds another supported locale.
+ * Duplicates are allowed, and are not removed.
+ *
+ * @param locale another locale
+ * @return this Builder object
+ * @draft ICU 65
+ */
+ Builder &addSupportedLocale(const Locale &locale);
+
+ /**
+ * Sets the default locale; if nullptr, or if it is not set explicitly,
+ * then the first supported locale is used as the default locale.
+ *
+ * @param defaultLocale the default locale (will be copied)
+ * @return this Builder object
+ * @draft ICU 65
+ */
+ Builder &setDefaultLocale(const Locale *defaultLocale);
+
+ /**
+ * If ULOCMATCH_FAVOR_SCRIPT, then the language differences are smaller than script
+ * differences.
+ * This is used in situations (such as maps) where
+ * it is better to fall back to the same script than a similar language.
+ *
+ * @param subtag the subtag to favor
+ * @return this Builder object
+ * @draft ICU 65
+ */
+ Builder &setFavorSubtag(ULocMatchFavorSubtag subtag);
+
+ /**
+ * Option for whether all desired locales are treated equally or
+ * earlier ones are preferred (this is the default).
+ *
+ * @param demotion the demotion per desired locale to set.
+ * @return this Builder object
+ * @draft ICU 65
+ */
+ Builder &setDemotionPerDesiredLocale(ULocMatchDemotion demotion);
+
+ /**
+ * Sets the UErrorCode if an error occurred while setting parameters.
+ * Preserves older error codes in the outErrorCode.
+ *
+ * @param outErrorCode Set to an error code if it does not contain one already
+ * and an error occurred while setting parameters.
+ * Otherwise unchanged.
+ * @return TRUE if U_FAILURE(outErrorCode)
+ * @draft ICU 65
+ */
+ UBool copyErrorTo(UErrorCode &outErrorCode) const;
+
+ /**
+ * Builds and returns a new locale matcher.
+ * This builder can continue to be used.
+ *
+ * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+ * or else the function returns immediately. Check for U_FAILURE()
+ * on output or use with function chaining. (See User Guide for details.)
+ * @return new LocaleMatcher.
+ * @draft ICU 65
+ */
+ LocaleMatcher build(UErrorCode &errorCode) const;
+
+ private:
+ friend class LocaleMatcher;
+
+ Builder(const Builder &other) = delete;
+ Builder &operator=(const Builder &other) = delete;
+
+ void clearSupportedLocales();
+ bool ensureSupportedLocaleVector();
+
+ UErrorCode errorCode_ = U_ZERO_ERROR;
+ UVector *supportedLocales_ = nullptr;
+ int32_t thresholdDistance_ = -1;
+ ULocMatchDemotion demotion_ = ULOCMATCH_DEMOTION_REGION;
+ Locale *defaultLocale_ = nullptr;
+ ULocMatchFavorSubtag favor_ = ULOCMATCH_FAVOR_LANGUAGE;
+ };
+
+ // FYI No public LocaleMatcher constructors in C++; use the Builder.
+
+ /**
+ * Move copy constructor; might modify the source.
+ * This matcher will have the same settings that the source matcher had.
+ * @param src source matcher
+ * @draft ICU 65
+ */
+ LocaleMatcher(LocaleMatcher &&src) U_NOEXCEPT;
+
+ /**
+ * Destructor.
+ * @draft ICU 65
+ */
+ ~LocaleMatcher();
+
+ /**
+ * Move assignment operator; might modify the source.
+ * This matcher will have the same settings that the source matcher had.
+ * The behavior is undefined if *this and src are the same object.
+ * @param src source matcher
+ * @return *this
+ * @draft ICU 65
+ */
+ LocaleMatcher &operator=(LocaleMatcher &&src) U_NOEXCEPT;
+
+ /**
+ * Returns the supported locale which best matches the desired locale.
+ *
+ * @param desiredLocale Typically a user's language.
+ * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+ * or else the function returns immediately. Check for U_FAILURE()
+ * on output or use with function chaining. (See User Guide for details.)
+ * @return the best-matching supported locale.
+ * @draft ICU 65
+ */
+ const Locale *getBestMatch(const Locale &desiredLocale, UErrorCode &errorCode) const;
+
+ /**
+ * Returns the supported locale which best matches one of the desired locales.
+ *
+ * @param desiredLocales Typically a user's languages, in order of preference (descending).
+ * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+ * or else the function returns immediately. Check for U_FAILURE()
+ * on output or use with function chaining. (See User Guide for details.)
+ * @return the best-matching supported locale.
+ * @draft ICU 65
+ */
+ const Locale *getBestMatch(Locale::Iterator &desiredLocales, UErrorCode &errorCode) const;
+
+ /**
+ * Parses an Accept-Language string
+ * (<a href="https://tools.ietf.org/html/rfc2616#section-14.4">RFC 2616 Section 14.4</a>),
+ * such as "af, en, fr;q=0.9",
+ * and returns the supported locale which best matches one of the desired locales.
+ * Allows whitespace in more places but does not allow "*".
+ *
+ * @param desiredLocaleList Typically a user's languages, as an Accept-Language string.
+ * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+ * or else the function returns immediately. Check for U_FAILURE()
+ * on output or use with function chaining. (See User Guide for details.)
+ * @return the best-matching supported locale.
+ * @draft ICU 65
+ */
+ const Locale *getBestMatchForListString(StringPiece desiredLocaleList, UErrorCode &errorCode) const;
+
+ /**
+ * Returns the best match between the desired locale and the supported locales.
+ * If the result's desired locale is not nullptr, then it is the address of the input locale.
+ * It has not been cloned.
+ *
+ * @param desiredLocale Typically a user's language.
+ * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+ * or else the function returns immediately. Check for U_FAILURE()
+ * on output or use with function chaining. (See User Guide for details.)
+ * @return the best-matching pair of the desired and a supported locale.
+ * @draft ICU 65
+ */
+ Result getBestMatchResult(const Locale &desiredLocale, UErrorCode &errorCode) const;
+
+ /**
+ * Returns the best match between the desired and supported locales.
+ * If the result's desired locale is not nullptr, then it is a clone of
+ * the best-matching desired locale. The Result object owns the clone.
+ *
+ * @param desiredLocales Typically a user's languages, in order of preference (descending).
+ * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+ * or else the function returns immediately. Check for U_FAILURE()
+ * on output or use with function chaining. (See User Guide for details.)
+ * @return the best-matching pair of a desired and a supported locale.
+ * @draft ICU 65
+ */
+ Result getBestMatchResult(Locale::Iterator &desiredLocales, UErrorCode &errorCode) const;
+
+#ifndef U_HIDE_INTERNAL_API
+ /**
+ * Returns a fraction between 0 and 1, where 1 means that the languages are a
+ * perfect match, and 0 means that they are completely different.
+ *
+ * <p>This is mostly an implementation detail, and the precise values may change over time.
+ * The implementation may use either the maximized forms or the others ones, or both.
+ * The implementation may or may not rely on the forms to be consistent with each other.
+ *
+ * <p>Callers should construct and use a matcher rather than match pairs of locales directly.
+ *
+ * @param desired Desired locale.
+ * @param supported Supported locale.
+ * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
+ * or else the function returns immediately. Check for U_FAILURE()
+ * on output or use with function chaining. (See User Guide for details.)
+ * @return value between 0 and 1, inclusive.
+ * @internal (has a known user)
+ */
+ double internalMatch(const Locale &desired, const Locale &supported, UErrorCode &errorCode) const;
+#endif // U_HIDE_INTERNAL_API
+
+private:
+ LocaleMatcher(const Builder &builder, UErrorCode &errorCode);
+ LocaleMatcher(const LocaleMatcher &other) = delete;
+ LocaleMatcher &operator=(const LocaleMatcher &other) = delete;
+
+ int32_t getBestSuppIndex(LSR desiredLSR, LocaleLsrIterator *remainingIter, UErrorCode &errorCode) const;
+
+ const XLikelySubtags &likelySubtags;
+ const LocaleDistance &localeDistance;
+ int32_t thresholdDistance;
+ int32_t demotionPerDesiredLocale;
+ ULocMatchFavorSubtag favorSubtag;
+
+ // These are in input order.
+ const Locale ** supportedLocales;
+ LSR *lsrs;
+ int32_t supportedLocalesLength;
+ // These are in preference order: 1. Default locale 2. paradigm locales 3. others.
+ UHashtable *supportedLsrToIndex; // Map<LSR, Integer> stores index+1 because 0 is "not found"
+ // Array versions of the supportedLsrToIndex keys and values.
+ // The distance lookup loops over the supportedLSRs and returns the index of the best match.
+ const LSR **supportedLSRs;
+ int32_t *supportedIndexes;
+ int32_t supportedLSRsLength;
+ Locale *ownedDefaultLocale;
+ const Locale *defaultLocale;
+ int32_t defaultLocaleIndex;
+};
+
+U_NAMESPACE_END
+
+#endif // U_HIDE_DRAFT_API
+#endif // U_SHOW_CPLUSPLUS_API
+#endif // __LOCALEMATCHER_H__
diff --git a/deps/icu-small/source/common/unicode/locdspnm.h b/deps/icu-small/source/common/unicode/locdspnm.h
index f6e778356f..4f06f85704 100644
--- a/deps/icu-small/source/common/unicode/locdspnm.h
+++ b/deps/icu-small/source/common/unicode/locdspnm.h
@@ -12,6 +12,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Provides display names of Locale and its components.
@@ -204,4 +206,6 @@ U_NAMESPACE_END
#endif
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/locid.h b/deps/icu-small/source/common/unicode/locid.h
index 7350e381ff..6fb0897fc0 100644
--- a/deps/icu-small/source/common/unicode/locid.h
+++ b/deps/icu-small/source/common/unicode/locid.h
@@ -31,11 +31,14 @@
#ifndef LOCID_H
#define LOCID_H
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/bytestream.h"
#include "unicode/localpointer.h"
#include "unicode/strenum.h"
#include "unicode/stringpiece.h"
-#include "unicode/utypes.h"
#include "unicode/uobject.h"
#include "unicode/putil.h"
#include "unicode/uloc.h"
@@ -284,16 +287,14 @@ public:
*/
Locale(const Locale& other);
-#ifndef U_HIDE_DRAFT_API
/**
* Move constructor; might leave source in bogus state.
* This locale will have the same contents that the source locale had.
*
* @param other The Locale object being moved in.
- * @draft ICU 63
+ * @stable ICU 63
*/
Locale(Locale&& other) U_NOEXCEPT;
-#endif // U_HIDE_DRAFT_API
/**
* Destructor
@@ -310,7 +311,6 @@ public:
*/
Locale& operator=(const Locale& other);
-#ifndef U_HIDE_DRAFT_API
/**
* Move assignment operator; might leave source in bogus state.
* This locale will have the same contents that the source locale had.
@@ -318,10 +318,9 @@ public:
*
* @param other The Locale object being moved in.
* @return *this
- * @draft ICU 63
+ * @stable ICU 63
*/
Locale& operator=(Locale&& other) U_NOEXCEPT;
-#endif // U_HIDE_DRAFT_API
/**
* Checks if two locale keys are the same.
@@ -389,7 +388,6 @@ public:
UErrorCode& success);
#endif /* U_HIDE_SYSTEM_API */
-#ifndef U_HIDE_DRAFT_API
/**
* Returns a Locale for the specified BCP47 language tag string.
* If the specified language tag contains any ill-formed subtags,
@@ -405,7 +403,7 @@ public:
* @param tag the input BCP47 language tag.
* @param status error information if creating the Locale failed.
* @return the Locale for the specified BCP47 language tag.
- * @draft ICU 63
+ * @stable ICU 63
*/
static Locale U_EXPORT2 forLanguageTag(StringPiece tag, UErrorCode& status);
@@ -420,7 +418,7 @@ public:
* @param sink the output sink receiving the BCP47 language
* tag for this Locale.
* @param status error information if creating the language tag failed.
- * @draft ICU 63
+ * @stable ICU 63
*/
void toLanguageTag(ByteSink& sink, UErrorCode& status) const;
@@ -432,11 +430,10 @@ public:
*
* @param status error information if creating the language tag failed.
* @return the BCP47 language tag for this Locale.
- * @draft ICU 63
+ * @stable ICU 63
*/
template<typename StringClass>
inline StringClass toLanguageTag(UErrorCode& status) const;
-#endif // U_HIDE_DRAFT_API
/**
* Creates a locale which has had minimal canonicalization
@@ -508,7 +505,6 @@ public:
*/
const char * getBaseName() const;
-#ifndef U_HIDE_DRAFT_API
/**
* Add the likely subtags for this Locale, per the algorithm described
* in the following CLDR technical report:
@@ -536,7 +532,7 @@ public:
* @param status error information if maximizing this Locale failed.
* If this Locale is not well-formed, the error code is
* U_ILLEGAL_ARGUMENT_ERROR.
- * @draft ICU 63
+ * @stable ICU 63
*/
void addLikelySubtags(UErrorCode& status);
@@ -567,10 +563,9 @@ public:
* @param status error information if maximizing this Locale failed.
* If this Locale is not well-formed, the error code is
* U_ILLEGAL_ARGUMENT_ERROR.
- * @draft ICU 63
+ * @stable ICU 63
*/
void minimizeSubtags(UErrorCode& status);
-#endif // U_HIDE_DRAFT_API
/**
* Gets the list of keywords for the specified locale.
@@ -583,8 +578,6 @@ public:
*/
StringEnumeration * createKeywords(UErrorCode &status) const;
-#ifndef U_HIDE_DRAFT_API
-
/**
* Gets the list of Unicode keywords for the specified locale.
*
@@ -592,7 +585,7 @@ public:
* @return pointer to StringEnumeration class, or NULL if there are no keywords.
* Client must dispose of it by calling delete.
* @see getUnicodeKeywords
- * @draft ICU 63
+ * @stable ICU 63
*/
StringEnumeration * createUnicodeKeywords(UErrorCode &status) const;
@@ -605,7 +598,7 @@ public:
*
* @param iterator an STL style output iterator to write the keywords to.
* @param status error information if creating set of keywords failed.
- * @draft ICU 63
+ * @stable ICU 63
*/
template<typename StringClass, typename OutputIterator>
inline void getKeywords(OutputIterator iterator, UErrorCode& status) const;
@@ -619,13 +612,11 @@ public:
*
* @param iterator an STL style output iterator to write the keywords to.
* @param status error information if creating set of keywords failed.
- * @draft ICU 63
+ * @stable ICU 63
*/
template<typename StringClass, typename OutputIterator>
inline void getUnicodeKeywords(OutputIterator iterator, UErrorCode& status) const;
-#endif // U_HIDE_DRAFT_API
-
/**
* Gets the value for a keyword.
*
@@ -644,7 +635,6 @@ public:
*/
int32_t getKeywordValue(const char* keywordName, char *buffer, int32_t bufferCapacity, UErrorCode &status) const;
-#ifndef U_HIDE_DRAFT_API
/**
* Gets the value for a keyword.
*
@@ -656,7 +646,7 @@ public:
* @param keywordName name of the keyword for which we want the value.
* @param sink the sink to receive the keyword value.
* @param status error information if getting the value failed.
- * @draft ICU 63
+ * @stable ICU 63
*/
void getKeywordValue(StringPiece keywordName, ByteSink& sink, UErrorCode& status) const;
@@ -671,7 +661,7 @@ public:
* @param keywordName name of the keyword for which we want the value.
* @param status error information if getting the value failed.
* @return the keyword value.
- * @draft ICU 63
+ * @stable ICU 63
*/
template<typename StringClass>
inline StringClass getKeywordValue(StringPiece keywordName, UErrorCode& status) const;
@@ -687,7 +677,7 @@ public:
* @param keywordName name of the keyword for which we want the value.
* @param sink the sink to receive the keyword value.
* @param status error information if getting the value failed.
- * @draft ICU 63
+ * @stable ICU 63
*/
void getUnicodeKeywordValue(StringPiece keywordName, ByteSink& sink, UErrorCode& status) const;
@@ -702,11 +692,10 @@ public:
* @param keywordName name of the keyword for which we want the value.
* @param status error information if getting the value failed.
* @return the keyword value.
- * @draft ICU 63
+ * @stable ICU 63
*/
template<typename StringClass>
inline StringClass getUnicodeKeywordValue(StringPiece keywordName, UErrorCode& status) const;
-#endif // U_HIDE_DRAFT_API
/**
* Sets or removes the value for a keyword.
@@ -729,7 +718,6 @@ public:
*/
void setKeywordValue(const char* keywordName, const char* keywordValue, UErrorCode &status);
-#ifndef U_HIDE_DRAFT_API
/**
* Sets or removes the value for a keyword.
*
@@ -746,7 +734,7 @@ public:
* NULL, will result in the keyword being removed. No error is given if
* that keyword does not exist.
* @param status Returns any error information while performing this operation.
- * @draft ICU 63
+ * @stable ICU 63
*/
void setKeywordValue(StringPiece keywordName, StringPiece keywordValue, UErrorCode& status);
@@ -766,10 +754,9 @@ public:
* NULL, will result in the keyword being removed. No error is given if
* that keyword does not exist.
* @param status Returns any error information while performing this operation.
- * @draft ICU 63
+ * @stable ICU 63
*/
void setUnicodeKeywordValue(StringPiece keywordName, StringPiece keywordValue, UErrorCode& status);
-#endif // U_HIDE_DRAFT_API
/**
* returns the locale's three-letter language code, as specified
@@ -1008,6 +995,104 @@ public:
*/
virtual UClassID getDynamicClassID() const;
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * A Locale iterator interface similar to a Java Iterator<Locale>.
+ * @draft ICU 65
+ */
+ class U_COMMON_API Iterator /* not : public UObject because this is an interface/mixin class */ {
+ public:
+ /** @draft ICU 65 */
+ virtual ~Iterator();
+
+ /**
+ * @return TRUE if next() can be called again.
+ * @draft ICU 65
+ */
+ virtual UBool hasNext() const = 0;
+
+ /**
+ * @return the next locale.
+ * @draft ICU 65
+ */
+ virtual const Locale &next() = 0;
+ };
+
+ /**
+ * A generic Locale iterator implementation over Locale input iterators.
+ * @draft ICU 65
+ */
+ template<typename Iter>
+ class RangeIterator : public Iterator, public UMemory {
+ public:
+ /**
+ * Constructs an iterator from a begin/end range.
+ * Each of the iterator parameter values must be an
+ * input iterator whose value is convertible to const Locale &.
+ *
+ * @param begin Start of range.
+ * @param end Exclusive end of range.
+ * @draft ICU 65
+ */
+ RangeIterator(Iter begin, Iter end) : it_(begin), end_(end) {}
+
+ /**
+ * @return TRUE if next() can be called again.
+ * @draft ICU 65
+ */
+ UBool hasNext() const override { return it_ != end_; }
+
+ /**
+ * @return the next locale.
+ * @draft ICU 65
+ */
+ const Locale &next() override { return *it_++; }
+
+ private:
+ Iter it_;
+ const Iter end_;
+ };
+
+ /**
+ * A generic Locale iterator implementation over Locale input iterators.
+ * Calls the converter to convert each *begin to a const Locale &.
+ * @draft ICU 65
+ */
+ template<typename Iter, typename Conv>
+ class ConvertingIterator : public Iterator, public UMemory {
+ public:
+ /**
+ * Constructs an iterator from a begin/end range.
+ * Each of the iterator parameter values must be an
+ * input iterator whose value the converter converts to const Locale &.
+ *
+ * @param begin Start of range.
+ * @param end Exclusive end of range.
+ * @param converter Converter from *begin to const Locale & or compatible.
+ * @draft ICU 65
+ */
+ ConvertingIterator(Iter begin, Iter end, Conv converter) :
+ it_(begin), end_(end), converter_(converter) {}
+
+ /**
+ * @return TRUE if next() can be called again.
+ * @draft ICU 65
+ */
+ UBool hasNext() const override { return it_ != end_; }
+
+ /**
+ * @return the next locale.
+ * @draft ICU 65
+ */
+ const Locale &next() override { return converter_(*it_++); }
+
+ private:
+ Iter it_;
+ const Iter end_;
+ Conv converter_;
+ };
+#endif // U_HIDE_DRAFT_API
+
protected: /* only protected for testing purposes. DO NOT USE. */
#ifndef U_HIDE_INTERNAL_API
/**
@@ -1074,7 +1159,6 @@ Locale::operator!=(const Locale& other) const
return !operator==(other);
}
-#ifndef U_HIDE_DRAFT_API
template<typename StringClass> inline StringClass
Locale::toLanguageTag(UErrorCode& status) const
{
@@ -1083,7 +1167,6 @@ Locale::toLanguageTag(UErrorCode& status) const
toLanguageTag(sink, status);
return result;
}
-#endif // U_HIDE_DRAFT_API
inline const char *
Locale::getCountry() const
@@ -1115,13 +1198,11 @@ Locale::getName() const
return fullName;
}
-#ifndef U_HIDE_DRAFT_API
-
template<typename StringClass, typename OutputIterator> inline void
Locale::getKeywords(OutputIterator iterator, UErrorCode& status) const
{
LocalPointer<StringEnumeration> keys(createKeywords(status));
- if (U_FAILURE(status)) {
+ if (U_FAILURE(status) || keys.isNull()) {
return;
}
for (;;) {
@@ -1138,7 +1219,7 @@ template<typename StringClass, typename OutputIterator> inline void
Locale::getUnicodeKeywords(OutputIterator iterator, UErrorCode& status) const
{
LocalPointer<StringEnumeration> keys(createUnicodeKeywords(status));
- if (U_FAILURE(status)) {
+ if (U_FAILURE(status) || keys.isNull()) {
return;
}
for (;;) {
@@ -1169,8 +1250,6 @@ Locale::getUnicodeKeywordValue(StringPiece keywordName, UErrorCode& status) cons
return result;
}
-#endif // U_HIDE_DRAFT_API
-
inline UBool
Locale::isBogus(void) const {
return fIsBogus;
@@ -1178,4 +1257,6 @@ Locale::isBogus(void) const {
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/messagepattern.h b/deps/icu-small/source/common/unicode/messagepattern.h
index 9f2a86551c..04f00a8757 100644
--- a/deps/icu-small/source/common/unicode/messagepattern.h
+++ b/deps/icu-small/source/common/unicode/messagepattern.h
@@ -24,6 +24,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
#include "unicode/parseerr.h"
@@ -942,4 +944,6 @@ U_NAMESPACE_END
#endif // !UCONFIG_NO_FORMATTING
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __MESSAGEPATTERN_H__
diff --git a/deps/icu-small/source/common/unicode/normalizer2.h b/deps/icu-small/source/common/unicode/normalizer2.h
index 4caa0e3103..4aeb3bb3d8 100644
--- a/deps/icu-small/source/common/unicode/normalizer2.h
+++ b/deps/icu-small/source/common/unicode/normalizer2.h
@@ -26,6 +26,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_NORMALIZATION
#include "unicode/stringpiece.h"
@@ -771,4 +773,7 @@ private:
U_NAMESPACE_END
#endif // !UCONFIG_NO_NORMALIZATION
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __NORMALIZER2_H__
diff --git a/deps/icu-small/source/common/unicode/normlzr.h b/deps/icu-small/source/common/unicode/normlzr.h
index 82335ae6d7..00dd820474 100644
--- a/deps/icu-small/source/common/unicode/normlzr.h
+++ b/deps/icu-small/source/common/unicode/normlzr.h
@@ -13,6 +13,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Unicode Normalization
@@ -183,6 +185,7 @@ public:
Normalizer(const CharacterIterator& iter, UNormalizationMode mode);
#endif /* U_HIDE_DEPRECATED_API */
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Copy constructor.
* @param copy The object to be copied.
@@ -195,7 +198,7 @@ public:
* @deprecated ICU 56 Use Normalizer2 instead.
*/
virtual ~Normalizer();
-
+#endif // U_FORCE_HIDE_DEPRECATED_API
//-------------------------------------------------------------------------
// Static utility methods
@@ -599,7 +602,7 @@ public:
* @return a pointer to a new Normalizer
* @deprecated ICU 56 Use Normalizer2 instead.
*/
- Normalizer* clone(void) const;
+ Normalizer* clone() const;
/**
* Generates a hash code for this iterator.
@@ -723,12 +726,14 @@ public:
static UClassID U_EXPORT2 getStaticClassID();
#endif /* U_HIDE_DEPRECATED_API */
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
* @return a UClassID for the actual class.
* @deprecated ICU 56 Use Normalizer2 instead.
*/
virtual UClassID getDynamicClassID() const;
+#endif // U_FORCE_HIDE_DEPRECATED_API
private:
//-------------------------------------------------------------------------
@@ -807,3 +812,5 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_NORMALIZATION */
#endif // NORMLZR_H
+
+#endif /* U_SHOW_CPLUSPLUS_API */
diff --git a/deps/icu-small/source/common/unicode/parsepos.h b/deps/icu-small/source/common/unicode/parsepos.h
index c02c816956..ae5754b8d7 100644
--- a/deps/icu-small/source/common/unicode/parsepos.h
+++ b/deps/icu-small/source/common/unicode/parsepos.h
@@ -19,6 +19,9 @@
#define PARSEPOS_H
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/uobject.h"
@@ -229,4 +232,6 @@ ParsePosition::setErrorIndex(int32_t ei)
}
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/platform.h b/deps/icu-small/source/common/unicode/platform.h
index ee0d8b7a00..74689d790c 100644
--- a/deps/icu-small/source/common/unicode/platform.h
+++ b/deps/icu-small/source/common/unicode/platform.h
@@ -135,6 +135,14 @@
/** Fuchsia is a POSIX-ish platform. @internal */
#define U_PF_FUCHSIA 4100
/* Maximum value for Linux-based platform is 4499 */
+/**
+ * Emscripten is a C++ transpiler for the Web that can target asm.js or
+ * WebAssembly. It provides some POSIX-compatible wrappers and stubs and
+ * some Linux-like functionality, but is not fully compatible with
+ * either.
+ * @internal
+ */
+#define U_PF_EMSCRIPTEN 5010
/** z/OS is the successor to OS/390 which was the successor to MVS. @internal */
#define U_PF_OS390 9000
/** "IBM i" is the current name of what used to be i5/OS and earlier OS/400. @internal */
@@ -192,6 +200,8 @@
# define U_PLATFORM U_PF_OS390
#elif defined(__OS400__) || defined(__TOS_OS400__)
# define U_PLATFORM U_PF_OS400
+#elif defined(__EMSCRIPTEN__)
+# define U_PLATFORM U_PF_EMSCRIPTEN
#else
# define U_PLATFORM U_PF_UNKNOWN
#endif
@@ -414,26 +424,40 @@
#endif
/* Compatibility with compilers other than clang: http://clang.llvm.org/docs/LanguageExtensions.html */
-#ifndef __has_attribute
-# define __has_attribute(x) 0
+#ifdef __has_attribute
+# define UPRV_HAS_ATTRIBUTE(x) __has_attribute(x)
+#else
+# define UPRV_HAS_ATTRIBUTE(x) 0
#endif
-#ifndef __has_cpp_attribute
-# define __has_cpp_attribute(x) 0
+#ifdef __has_cpp_attribute
+# define UPRV_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
+#else
+# define UPRV_HAS_CPP_ATTRIBUTE(x) 0
#endif
-#ifndef __has_declspec_attribute
-# define __has_declspec_attribute(x) 0
+#ifdef __has_declspec_attribute
+# define UPRV_HAS_DECLSPEC_ATTRIBUTE(x) __has_declspec_attribute(x)
+#else
+# define UPRV_HAS_DECLSPEC_ATTRIBUTE(x) 0
#endif
-#ifndef __has_builtin
-# define __has_builtin(x) 0
+#ifdef __has_builtin
+# define UPRV_HAS_BUILTIN(x) __has_builtin(x)
+#else
+# define UPRV_HAS_BUILTIN(x) 0
#endif
-#ifndef __has_feature
-# define __has_feature(x) 0
+#ifdef __has_feature
+# define UPRV_HAS_FEATURE(x) __has_feature(x)
+#else
+# define UPRV_HAS_FEATURE(x) 0
#endif
-#ifndef __has_extension
-# define __has_extension(x) 0
+#ifdef __has_extension
+# define UPRV_HAS_EXTENSION(x) __has_extension(x)
+#else
+# define UPRV_HAS_EXTENSION(x) 0
#endif
-#ifndef __has_warning
-# define __has_warning(x) 0
+#ifdef __has_warning
+# define UPRV_HAS_WARNING(x) __has_warning(x)
+#else
+# define UPRV_HAS_WARNING(x) 0
#endif
/**
@@ -452,7 +476,9 @@
* Attribute to specify the size of the allocated buffer for malloc-like functions
* @internal
*/
-#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || __has_attribute(alloc_size)
+#if (defined(__GNUC__) && \
+ (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || \
+ UPRV_HAS_ATTRIBUTE(alloc_size)
# define U_ALLOC_SIZE_ATTR(X) __attribute__ ((alloc_size(X)))
# define U_ALLOC_SIZE_ATTR2(X,Y) __attribute__ ((alloc_size(X,Y)))
#else
@@ -516,8 +542,9 @@ namespace std {
#elif defined(__clang__)
// Test for compiler vs. feature separately.
// Other compilers might choke on the feature test.
-# if __has_cpp_attribute(clang::fallthrough) || \
- (__has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough"))
+# if UPRV_HAS_CPP_ATTRIBUTE(clang::fallthrough) || \
+ (UPRV_HAS_FEATURE(cxx_attributes) && \
+ UPRV_HAS_WARNING("-Wimplicit-fallthrough"))
# define U_FALLTHROUGH [[clang::fallthrough]]
# endif
#elif defined(__GNUC__) && (__GNUC__ >= 7)
@@ -620,7 +647,8 @@ namespace std {
*/
#ifdef U_CHARSET_IS_UTF8
/* Use the predefined value. */
-#elif U_PLATFORM_IS_LINUX_BASED || U_PLATFORM_IS_DARWIN_BASED
+#elif U_PLATFORM_IS_LINUX_BASED || U_PLATFORM_IS_DARWIN_BASED || \
+ U_PLATFORM == U_PF_EMSCRIPTEN
# define U_CHARSET_IS_UTF8 1
#else
# define U_CHARSET_IS_UTF8 0
@@ -707,7 +735,7 @@ namespace std {
* narrow-character strings are in EBCDIC.
*/
# define U_SIZEOF_WCHAR_T 2
-#else
+# else
/*
* LOCALETYPE(*CLD) or LOCALETYPE(*LOCALE) is specified.
* Wide-character strings are in 16-bit EBCDIC,
@@ -786,7 +814,8 @@ namespace std {
/* Use the predefined value. */
#elif defined(U_STATIC_IMPLEMENTATION)
# define U_EXPORT
-#elif defined(_MSC_VER) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))
+#elif defined(_MSC_VER) || (UPRV_HAS_DECLSPEC_ATTRIBUTE(dllexport) && \
+ UPRV_HAS_DECLSPEC_ATTRIBUTE(dllimport))
# define U_EXPORT __declspec(dllexport)
#elif defined(__GNUC__)
# define U_EXPORT __attribute__((visibility("default")))
@@ -810,7 +839,8 @@ namespace std {
#ifdef U_IMPORT
/* Use the predefined value. */
-#elif defined(_MSC_VER) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))
+#elif defined(_MSC_VER) || (UPRV_HAS_DECLSPEC_ATTRIBUTE(dllexport) && \
+ UPRV_HAS_DECLSPEC_ATTRIBUTE(dllimport))
/* Windows needs to export/import data. */
# define U_IMPORT __declspec(dllimport)
#else
@@ -852,4 +882,4 @@ namespace std {
#endif
/* @} */
-#endif
+#endif // _PLATFORM_H
diff --git a/deps/icu-small/source/common/unicode/rbbi.h b/deps/icu-small/source/common/unicode/rbbi.h
index 365ae2d3d2..7825f603a5 100644
--- a/deps/icu-small/source/common/unicode/rbbi.h
+++ b/deps/icu-small/source/common/unicode/rbbi.h
@@ -18,6 +18,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Rule Based Break Iterator
@@ -272,7 +274,7 @@ public:
* @return a newly-constructed RuleBasedBreakIterator
* @stable ICU 2.0
*/
- virtual BreakIterator* clone() const;
+ virtual RuleBasedBreakIterator* clone() const;
/**
* Compute a hash code for this BreakIterator
@@ -536,6 +538,7 @@ public:
*/
static UClassID U_EXPORT2 getStaticClassID(void);
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Deprecated functionality. Use clone() instead.
*
@@ -562,10 +565,10 @@ public:
* or if the stackBuffer was too small to hold the clone.
* @deprecated ICU 52. Use clone() instead.
*/
- virtual BreakIterator * createBufferClone(void *stackBuffer,
- int32_t &BufferSize,
- UErrorCode &status);
-
+ virtual RuleBasedBreakIterator *createBufferClone(void *stackBuffer,
+ int32_t &BufferSize,
+ UErrorCode &status);
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Return the binary form of compiled break rules,
@@ -696,4 +699,6 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/rep.h b/deps/icu-small/source/common/unicode/rep.h
index b1023a37a2..f66c2ac060 100644
--- a/deps/icu-small/source/common/unicode/rep.h
+++ b/deps/icu-small/source/common/unicode/rep.h
@@ -16,6 +16,10 @@
#ifndef REP_H
#define REP_H
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/uobject.h"
/**
@@ -189,9 +193,6 @@ public:
* Clones can be used concurrently in multiple threads.
* If a subclass does not implement clone(), or if an error occurs,
* then NULL is returned.
- * The clone functions in all subclasses return a pointer to a Replaceable
- * because some compilers do not support covariant (same-as-this)
- * return types; cast to the appropriate subclass if necessary.
* The caller must delete the clone.
*
* @return a clone of this object
@@ -260,4 +261,6 @@ Replaceable::char32At(int32_t offset) const {
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/resbund.h b/deps/icu-small/source/common/unicode/resbund.h
index ab0b60bbb2..708a3423d2 100644
--- a/deps/icu-small/source/common/unicode/resbund.h
+++ b/deps/icu-small/source/common/unicode/resbund.h
@@ -49,6 +49,9 @@
#define RESBUND_H
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/uobject.h"
#include "unicode/ures.h"
#include "unicode/unistr.h"
@@ -489,4 +492,7 @@ private:
};
U_NAMESPACE_END
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/schriter.h b/deps/icu-small/source/common/unicode/schriter.h
index 1a12769e8d..4925ecfe44 100644
--- a/deps/icu-small/source/common/unicode/schriter.h
+++ b/deps/icu-small/source/common/unicode/schriter.h
@@ -21,6 +21,9 @@
#define SCHRITER_H
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/chariter.h"
#include "unicode/uchriter.h"
@@ -130,7 +133,7 @@ public:
* @return the newly cloned object.
* @stable ICU 2.0
*/
- virtual CharacterIterator* clone(void) const;
+ virtual StringCharacterIterator* clone() const;
/**
* Sets the iterator to iterate over the provided string.
@@ -186,4 +189,7 @@ protected:
};
U_NAMESPACE_END
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/simpleformatter.h b/deps/icu-small/source/common/unicode/simpleformatter.h
index 3f7d93dc09..9414bca308 100644
--- a/deps/icu-small/source/common/unicode/simpleformatter.h
+++ b/deps/icu-small/source/common/unicode/simpleformatter.h
@@ -17,6 +17,9 @@
*/
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/unistr.h"
U_NAMESPACE_BEGIN
@@ -333,4 +336,6 @@ private:
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __SIMPLEFORMATTER_H__
diff --git a/deps/icu-small/source/common/unicode/std_string.h b/deps/icu-small/source/common/unicode/std_string.h
index 729c563995..bf87230167 100644
--- a/deps/icu-small/source/common/unicode/std_string.h
+++ b/deps/icu-small/source/common/unicode/std_string.h
@@ -27,6 +27,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
// Workaround for a libstdc++ bug before libstdc++4.6 (2011).
// https://bugs.llvm.org/show_bug.cgi?id=13364
#if defined(__GLIBCXX__)
@@ -34,4 +36,6 @@ namespace std { class type_info; }
#endif
#include <string>
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __STD_STRING_H__
diff --git a/deps/icu-small/source/common/unicode/strenum.h b/deps/icu-small/source/common/unicode/strenum.h
index fa525d4f52..e813cd84b3 100644
--- a/deps/icu-small/source/common/unicode/strenum.h
+++ b/deps/icu-small/source/common/unicode/strenum.h
@@ -12,6 +12,10 @@
#ifndef STRENUM_H
#define STRENUM_H
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/uobject.h"
#include "unicode/unistr.h"
@@ -67,9 +71,6 @@ public:
* Clones can be used concurrently in multiple threads.
* If a subclass does not implement clone(), or if an error occurs,
* then NULL is returned.
- * The clone functions in all subclasses return a base class pointer
- * because some compilers do not support covariant (same-as-this)
- * return types; cast to the appropriate subclass if necessary.
* The caller must delete the clone.
*
* @return a clone of this object
@@ -274,5 +275,7 @@ protected:
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
/* STRENUM_H */
#endif
diff --git a/deps/icu-small/source/common/unicode/stringpiece.h b/deps/icu-small/source/common/unicode/stringpiece.h
index 640fbac5a8..15cebb0f20 100644
--- a/deps/icu-small/source/common/unicode/stringpiece.h
+++ b/deps/icu-small/source/common/unicode/stringpiece.h
@@ -28,6 +28,12 @@
*/
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
+#include <cstddef>
+#include <type_traits>
+
#include "unicode/uobject.h"
#include "unicode/std_string.h"
@@ -74,6 +80,33 @@ class U_COMMON_API StringPiece : public UMemory {
*/
StringPiece(const std::string& str)
: ptr_(str.data()), length_(static_cast<int32_t>(str.size())) { }
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Constructs from some other implementation of a string piece class, from any
+ * C++ record type that has these two methods:
+ *
+ * \code{.cpp}
+ *
+ * struct OtherStringPieceClass {
+ * const char* data();
+ * size_t size();
+ * };
+ *
+ * \endcode
+ *
+ * The other string piece class will typically be std::string_view from C++17
+ * or absl::string_view from Abseil.
+ *
+ * @param str the other string piece
+ * @draft ICU 65
+ */
+ template <typename T,
+ typename = typename std::enable_if<
+ std::is_same<decltype(T().data()), const char*>::value &&
+ std::is_same<decltype(T().size()), size_t>::value>::type>
+ StringPiece(T str)
+ : ptr_(str.data()), length_(static_cast<int32_t>(str.size())) {}
+#endif // U_HIDE_DRAFT_API
/**
* Constructs from a const char * pointer and a specified length.
* @param offset a const char * pointer (need not be terminated)
@@ -221,4 +254,6 @@ inline UBool operator!=(const StringPiece& x, const StringPiece& y) {
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __STRINGPIECE_H__
diff --git a/deps/icu-small/source/common/unicode/stringtriebuilder.h b/deps/icu-small/source/common/unicode/stringtriebuilder.h
index c27fbd6796..2860cbf551 100644
--- a/deps/icu-small/source/common/unicode/stringtriebuilder.h
+++ b/deps/icu-small/source/common/unicode/stringtriebuilder.h
@@ -18,6 +18,9 @@
#define __STRINGTRIEBUILDER_H__
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/uobject.h"
/**
@@ -418,4 +421,6 @@ protected:
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __STRINGTRIEBUILDER_H__
diff --git a/deps/icu-small/source/common/unicode/symtable.h b/deps/icu-small/source/common/unicode/symtable.h
index c2dc95a61b..f5a77b01ec 100644
--- a/deps/icu-small/source/common/unicode/symtable.h
+++ b/deps/icu-small/source/common/unicode/symtable.h
@@ -13,6 +13,9 @@
#define SYMTABLE_H
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/uobject.h"
/**
@@ -111,4 +114,6 @@ public:
};
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/uchar.h b/deps/icu-small/source/common/unicode/uchar.h
index d70c964e38..1b7ee099be 100644
--- a/deps/icu-small/source/common/unicode/uchar.h
+++ b/deps/icu-small/source/common/unicode/uchar.h
@@ -2578,8 +2578,6 @@ typedef enum UVerticalOrientation {
U_STABLE UBool U_EXPORT2
u_hasBinaryProperty(UChar32 c, UProperty which);
-#ifndef U_HIDE_DRAFT_API
-
/**
* Returns a frozen USet for a binary property.
* The library retains ownership over the returned object.
@@ -2593,13 +2591,11 @@ u_hasBinaryProperty(UChar32 c, UProperty which);
* @see UProperty
* @see u_hasBinaryProperty
* @see Unicode::fromUSet
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI const USet * U_EXPORT2
u_getBinaryPropertySet(UProperty property, UErrorCode *pErrorCode);
-#endif // U_HIDE_DRAFT_API
-
/**
* Check if a code point has the Alphabetic Unicode property.
* Same as u_hasBinaryProperty(c, UCHAR_ALPHABETIC).
@@ -2757,8 +2753,6 @@ u_getIntPropertyMinValue(UProperty which);
U_STABLE int32_t U_EXPORT2
u_getIntPropertyMaxValue(UProperty which);
-#ifndef U_HIDE_DRAFT_API
-
/**
* Returns an immutable UCPMap for an enumerated/catalog/int-valued property.
* The library retains ownership over the returned object.
@@ -2772,13 +2766,11 @@ u_getIntPropertyMaxValue(UProperty which);
* @return the property as a map
* @see UProperty
* @see u_getIntPropertyValue
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI const UCPMap * U_EXPORT2
u_getIntPropertyMap(UProperty property, UErrorCode *pErrorCode);
-#endif // U_HIDE_DRAFT_API
-
/**
* Get the numeric value for a Unicode code point as defined in the
* Unicode Character Database.
@@ -3197,15 +3189,14 @@ U_STABLE UBool U_EXPORT2
u_isprint(UChar32 c);
/**
- * Determines whether the specified code point is a base character.
+ * Non-standard: Determines whether the specified code point is a base character.
* True for general categories "L" (letters), "N" (numbers),
* "Mc" (spacing combining marks), and "Me" (enclosing marks).
*
- * Note that this is different from the Unicode definition in
- * chapter 3.5, conformance clause D13,
- * which defines base characters to be all characters (not Cn)
- * that do not graphically combine with preceding characters (M)
- * and that are neither control (Cc) or format (Cf) characters.
+ * Note that this is different from the Unicode Standard definition in
+ * chapter 3.6, conformance clause D51 “Base character”,
+ * which defines base characters as the code points with general categories
+ * Letter (L), Number (N), Punctuation (P), Symbol (S), or Space Separator (Zs).
*
* @param c the code point to be tested
* @return TRUE if the code point is a base character according to this function
diff --git a/deps/icu-small/source/common/unicode/ucharstrie.h b/deps/icu-small/source/common/unicode/ucharstrie.h
index dfc93f6d0b..d5729d944e 100644
--- a/deps/icu-small/source/common/unicode/ucharstrie.h
+++ b/deps/icu-small/source/common/unicode/ucharstrie.h
@@ -24,6 +24,9 @@
*/
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/unistr.h"
#include "unicode/uobject.h"
#include "unicode/ustringtrie.h"
@@ -94,6 +97,41 @@ public:
return *this;
}
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Returns the state of this trie as a 64-bit integer.
+ * The state value is never 0.
+ *
+ * @return opaque state value
+ * @see resetToState64
+ * @draft ICU 65
+ */
+ uint64_t getState64() const {
+ return (static_cast<uint64_t>(remainingMatchLength_ + 2) << kState64RemainingShift) |
+ (uint64_t)(pos_ - uchars_);
+ }
+
+ /**
+ * Resets this trie to the saved state.
+ * Unlike resetToState(State), the 64-bit state value
+ * must be from getState64() from the same trie object or
+ * from one initialized the exact same way.
+ * Because of no validation, this method is faster.
+ *
+ * @param state The opaque trie state value from getState64().
+ * @return *this
+ * @see getState64
+ * @see resetToState
+ * @see reset
+ * @draft ICU 65
+ */
+ UCharsTrie &resetToState64(uint64_t state) {
+ remainingMatchLength_ = static_cast<int32_t>(state >> kState64RemainingShift) - 2;
+ pos_ = uchars_ + (state & kState64PosMask);
+ return *this;
+ }
+#endif /* U_HIDE_DRAFT_API */
+
/**
* UCharsTrie state object, for saving a trie's current state
* and resetting the trie back to this state later.
@@ -560,6 +598,13 @@ private:
static const int32_t kMaxTwoUnitDelta=((kThreeUnitDeltaLead-kMinTwoUnitDeltaLead)<<16)-1; // 0x03feffff
+ // For getState64():
+ // The remainingMatchLength_ is -1..14=(kMaxLinearMatchLength=0x10)-2
+ // so we need at least 5 bits for that.
+ // We add 2 to store it as a positive value 1..16=kMaxLinearMatchLength.
+ static constexpr int32_t kState64RemainingShift = 59;
+ static constexpr uint64_t kState64PosMask = (UINT64_C(1) << kState64RemainingShift) - 1;
+
char16_t *ownedArray_;
// Fixed value referencing the UCharsTrie words.
@@ -575,4 +620,6 @@ private:
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __UCHARSTRIE_H__
diff --git a/deps/icu-small/source/common/unicode/ucharstriebuilder.h b/deps/icu-small/source/common/unicode/ucharstriebuilder.h
index 2aa4757e52..540dcc047f 100644
--- a/deps/icu-small/source/common/unicode/ucharstriebuilder.h
+++ b/deps/icu-small/source/common/unicode/ucharstriebuilder.h
@@ -18,6 +18,9 @@
#define __UCHARSTRIEBUILDER_H__
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/stringtriebuilder.h"
#include "unicode/ucharstrie.h"
#include "unicode/unistr.h"
@@ -184,4 +187,6 @@ private:
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __UCHARSTRIEBUILDER_H__
diff --git a/deps/icu-small/source/common/unicode/uchriter.h b/deps/icu-small/source/common/unicode/uchriter.h
index 38f67c5b45..bee842cc25 100644
--- a/deps/icu-small/source/common/unicode/uchriter.h
+++ b/deps/icu-small/source/common/unicode/uchriter.h
@@ -11,6 +11,9 @@
#define UCHRITER_H
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/chariter.h"
/**
@@ -132,7 +135,7 @@ public:
* @return the CharacterIterator newly created
* @stable ICU 2.0
*/
- virtual CharacterIterator* clone(void) const;
+ virtual UCharCharacterIterator* clone() const;
/**
* Sets the iterator to refer to the first code unit in its
@@ -384,4 +387,7 @@ protected:
};
U_NAMESPACE_END
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/uconfig.h b/deps/icu-small/source/common/unicode/uconfig.h
index 9c82d82812..c0157efe6d 100644
--- a/deps/icu-small/source/common/unicode/uconfig.h
+++ b/deps/icu-small/source/common/unicode/uconfig.h
@@ -453,4 +453,4 @@
# define UCONFIG_NO_FILTERED_BREAK_ITERATION 0
#endif
-#endif
+#endif // __UCONFIG_H__
diff --git a/deps/icu-small/source/common/unicode/ucpmap.h b/deps/icu-small/source/common/unicode/ucpmap.h
index f2c42b6b7f..31e1365cac 100644
--- a/deps/icu-small/source/common/unicode/ucpmap.h
+++ b/deps/icu-small/source/common/unicode/ucpmap.h
@@ -9,8 +9,6 @@
#include "unicode/utypes.h"
-#ifndef U_HIDE_DRAFT_API
-
U_CDECL_BEGIN
/**
@@ -28,7 +26,7 @@ U_CDECL_BEGIN
*
* @see UCPTrie
* @see UMutableCPTrie
- * @draft ICU 63
+ * @stable ICU 63
*/
typedef struct UCPMap UCPMap;
@@ -39,13 +37,13 @@ typedef struct UCPMap UCPMap;
* @see ucpmap_getRange
* @see ucptrie_getRange
* @see umutablecptrie_getRange
- * @draft ICU 63
+ * @stable ICU 63
*/
enum UCPMapRangeOption {
/**
* ucpmap_getRange() enumerates all same-value ranges as stored in the map.
* Most users should use this option.
- * @draft ICU 63
+ * @stable ICU 63
*/
UCPMAP_RANGE_NORMAL,
/**
@@ -61,7 +59,7 @@ enum UCPMapRangeOption {
* special values optimized for UTF-16 string processing
* or for special error behavior for unpaired surrogates,
* but those values are not to be associated with the lead surrogate code *points*.
- * @draft ICU 63
+ * @stable ICU 63
*/
UCPMAP_RANGE_FIXED_LEAD_SURROGATES,
/**
@@ -77,7 +75,7 @@ enum UCPMapRangeOption {
* special values optimized for UTF-16 string processing
* or for special error behavior for unpaired surrogates,
* but those values are not to be associated with the lead surrogate code *points*.
- * @draft ICU 63
+ * @stable ICU 63
*/
UCPMAP_RANGE_FIXED_ALL_SURROGATES
};
@@ -93,7 +91,7 @@ typedef enum UCPMapRangeOption UCPMapRangeOption;
* @param c the code point
* @return the map value,
* or an implementation-defined error value if the code point is not in the range 0..U+10FFFF
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI uint32_t U_EXPORT2
ucpmap_get(const UCPMap *map, UChar32 c);
@@ -110,7 +108,7 @@ ucpmap_get(const UCPMap *map, UChar32 c);
* @param context an opaque pointer, as passed into the getRange function
* @param value a value from the map
* @return the modified value
- * @draft ICU 63
+ * @stable ICU 63
*/
typedef uint32_t U_CALLCONV
UCPMapValueFilter(const void *context, uint32_t value);
@@ -149,7 +147,7 @@ UCPMapValueFilter(const void *context, uint32_t value);
* may have been modified by filter(context, map value)
* if that function pointer is not NULL
* @return the range end code point, or -1 if start is not a valid code point
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI UChar32 U_EXPORT2
ucpmap_getRange(const UCPMap *map, UChar32 start,
@@ -158,5 +156,4 @@ ucpmap_getRange(const UCPMap *map, UChar32 start,
U_CDECL_END
-#endif // U_HIDE_DRAFT_API
#endif
diff --git a/deps/icu-small/source/common/unicode/ucptrie.h b/deps/icu-small/source/common/unicode/ucptrie.h
index 2718c984e4..be06a22792 100644
--- a/deps/icu-small/source/common/unicode/ucptrie.h
+++ b/deps/icu-small/source/common/unicode/ucptrie.h
@@ -9,8 +9,6 @@
#include "unicode/utypes.h"
-#ifndef U_HIDE_DRAFT_API
-
#include "unicode/localpointer.h"
#include "unicode/ucpmap.h"
#include "unicode/utf8.h"
@@ -55,7 +53,7 @@ typedef union UCPTrieData {
* The macros will return bogus values, or may crash, if used on the wrong type or value width.
*
* @see UMutableCPTrie
- * @draft ICU 63
+ * @stable ICU 63
*/
struct UCPTrie {
#ifndef U_IN_DOXYGEN
@@ -115,23 +113,23 @@ typedef struct UCPTrie UCPTrie;
* @see umutablecptrie_buildImmutable
* @see ucptrie_openFromBinary
* @see ucptrie_getType
- * @draft ICU 63
+ * @stable ICU 63
*/
enum UCPTrieType {
/**
* For ucptrie_openFromBinary() to accept any type.
* ucptrie_getType() will return the actual type.
- * @draft ICU 63
+ * @stable ICU 63
*/
UCPTRIE_TYPE_ANY = -1,
/**
* Fast/simple/larger BMP data structure. Use functions and "fast" macros.
- * @draft ICU 63
+ * @stable ICU 63
*/
UCPTRIE_TYPE_FAST,
/**
* Small/slower BMP data structure. Use functions and "small" macros.
- * @draft ICU 63
+ * @stable ICU 63
*/
UCPTRIE_TYPE_SMALL
};
@@ -145,30 +143,30 @@ typedef enum UCPTrieType UCPTrieType;
* @see umutablecptrie_buildImmutable
* @see ucptrie_openFromBinary
* @see ucptrie_getValueWidth
- * @draft ICU 63
+ * @stable ICU 63
*/
enum UCPTrieValueWidth {
/**
* For ucptrie_openFromBinary() to accept any data value width.
* ucptrie_getValueWidth() will return the actual data value width.
- * @draft ICU 63
+ * @stable ICU 63
*/
UCPTRIE_VALUE_BITS_ANY = -1,
/**
* The trie stores 16 bits per data value.
* It returns them as unsigned values 0..0xffff=65535.
- * @draft ICU 63
+ * @stable ICU 63
*/
UCPTRIE_VALUE_BITS_16,
/**
* The trie stores 32 bits per data value.
- * @draft ICU 63
+ * @stable ICU 63
*/
UCPTRIE_VALUE_BITS_32,
/**
* The trie stores 8 bits per data value.
* It returns them as unsigned values 0..0xff=255.
- * @draft ICU 63
+ * @stable ICU 63
*/
UCPTRIE_VALUE_BITS_8
};
@@ -200,7 +198,7 @@ typedef enum UCPTrieValueWidth UCPTrieValueWidth;
* @see umutablecptrie_open
* @see umutablecptrie_buildImmutable
* @see ucptrie_toBinary
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI UCPTrie * U_EXPORT2
ucptrie_openFromBinary(UCPTrieType type, UCPTrieValueWidth valueWidth,
@@ -211,30 +209,11 @@ ucptrie_openFromBinary(UCPTrieType type, UCPTrieValueWidth valueWidth,
* Closes a trie and releases associated memory.
*
* @param trie the trie
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI void U_EXPORT2
ucptrie_close(UCPTrie *trie);
-#if U_SHOW_CPLUSPLUS_API
-
-U_NAMESPACE_BEGIN
-
-/**
- * \class LocalUCPTriePointer
- * "Smart pointer" class, closes a UCPTrie via ucptrie_close().
- * For most methods see the LocalPointerBase base class.
- *
- * @see LocalPointerBase
- * @see LocalPointer
- * @draft ICU 63
- */
-U_DEFINE_LOCAL_OPEN_POINTER(LocalUCPTriePointer, UCPTrie, ucptrie_close);
-
-U_NAMESPACE_END
-
-#endif
-
/**
* Returns the trie type.
*
@@ -242,7 +221,7 @@ U_NAMESPACE_END
* @return the trie type
* @see ucptrie_openFromBinary
* @see UCPTRIE_TYPE_ANY
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI UCPTrieType U_EXPORT2
ucptrie_getType(const UCPTrie *trie);
@@ -254,7 +233,7 @@ ucptrie_getType(const UCPTrie *trie);
* @return the number of bits in a trie data value
* @see ucptrie_openFromBinary
* @see UCPTRIE_VALUE_BITS_ANY
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI UCPTrieValueWidth U_EXPORT2
ucptrie_getValueWidth(const UCPTrie *trie);
@@ -271,7 +250,7 @@ ucptrie_getValueWidth(const UCPTrie *trie);
* @param c the code point
* @return the trie value,
* or the trie error value if the code point is not in the range 0..U+10FFFF
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI uint32_t U_EXPORT2
ucptrie_get(const UCPTrie *trie, UChar32 c);
@@ -310,7 +289,7 @@ ucptrie_get(const UCPTrie *trie, UChar32 c);
* may have been modified by filter(context, trie value)
* if that function pointer is not NULL
* @return the range end code point, or -1 if start is not a valid code point
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI UChar32 U_EXPORT2
ucptrie_getRange(const UCPTrie *trie, UChar32 start,
@@ -330,7 +309,7 @@ ucptrie_getRange(const UCPTrie *trie, UChar32 start,
* @return the number of bytes written or (if buffer overflow) needed for the trie
*
* @see ucptrie_openFromBinary()
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI int32_t U_EXPORT2
ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *pErrorCode);
@@ -341,7 +320,7 @@ ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *
* Do not use this macro in any other way.
*
* @see UCPTRIE_VALUE_BITS_16
- * @draft ICU 63
+ * @stable ICU 63
*/
#define UCPTRIE_16(trie, i) ((trie)->data.ptr16[i])
@@ -351,7 +330,7 @@ ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *
* Do not use this macro in any other way.
*
* @see UCPTRIE_VALUE_BITS_32
- * @draft ICU 63
+ * @stable ICU 63
*/
#define UCPTRIE_32(trie, i) ((trie)->data.ptr32[i])
@@ -361,7 +340,7 @@ ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *
* Do not use this macro in any other way.
*
* @see UCPTRIE_VALUE_BITS_8
- * @draft ICU 63
+ * @stable ICU 63
*/
#define UCPTRIE_8(trie, i) ((trie)->data.ptr8[i])
@@ -373,7 +352,7 @@ ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *
* @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width
* @param c (UChar32, in) the input code point
* @return The code point's trie value.
- * @draft ICU 63
+ * @stable ICU 63
*/
#define UCPTRIE_FAST_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_CP_INDEX(trie, 0xffff, c))
@@ -385,7 +364,7 @@ ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *
* @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width
* @param c (UChar32, in) the input code point
* @return The code point's trie value.
- * @draft ICU 63
+ * @stable ICU 63
*/
#define UCPTRIE_SMALL_GET(trie, dataAccess, c) \
dataAccess(trie, _UCPTRIE_CP_INDEX(trie, UCPTRIE_SMALL_MAX, c))
@@ -401,9 +380,9 @@ ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *
* @param limit (const UChar *, in) the limit pointer for the text, or NULL if NUL-terminated
* @param c (UChar32, out) variable for the code point
* @param result (out) variable for the trie lookup result
- * @draft ICU 63
+ * @stable ICU 63
*/
-#define UCPTRIE_FAST_U16_NEXT(trie, dataAccess, src, limit, c, result) { \
+#define UCPTRIE_FAST_U16_NEXT(trie, dataAccess, src, limit, c, result) UPRV_BLOCK_MACRO_BEGIN { \
(c) = *(src)++; \
int32_t __index; \
if (!U16_IS_SURROGATE(c)) { \
@@ -419,7 +398,7 @@ ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *
} \
} \
(result) = dataAccess(trie, __index); \
-}
+} UPRV_BLOCK_MACRO_END
/**
* UTF-16: Reads the previous code point (UChar32 c, out), pre-decrements src,
@@ -432,9 +411,9 @@ ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *
* @param src (const UChar *, in/out) the source text pointer
* @param c (UChar32, out) variable for the code point
* @param result (out) variable for the trie lookup result
- * @draft ICU 63
+ * @stable ICU 63
*/
-#define UCPTRIE_FAST_U16_PREV(trie, dataAccess, start, src, c, result) { \
+#define UCPTRIE_FAST_U16_PREV(trie, dataAccess, start, src, c, result) UPRV_BLOCK_MACRO_BEGIN { \
(c) = *--(src); \
int32_t __index; \
if (!U16_IS_SURROGATE(c)) { \
@@ -450,7 +429,7 @@ ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *
} \
} \
(result) = dataAccess(trie, __index); \
-}
+} UPRV_BLOCK_MACRO_END
/**
* UTF-8: Post-increments src and gets a value from the trie.
@@ -466,9 +445,9 @@ ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *
* @param src (const char *, in/out) the source text pointer
* @param limit (const char *, in) the limit pointer for the text (must not be NULL)
* @param result (out) variable for the trie lookup result
- * @draft ICU 63
+ * @stable ICU 63
*/
-#define UCPTRIE_FAST_U8_NEXT(trie, dataAccess, src, limit, result) { \
+#define UCPTRIE_FAST_U8_NEXT(trie, dataAccess, src, limit, result) UPRV_BLOCK_MACRO_BEGIN { \
int32_t __lead = (uint8_t)*(src)++; \
if (!U8_IS_SINGLE(__lead)) { \
uint8_t __t1, __t2, __t3; \
@@ -496,7 +475,7 @@ ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *
} \
} \
(result) = dataAccess(trie, __lead); \
-}
+} UPRV_BLOCK_MACRO_END
/**
* UTF-8: Pre-decrements src and gets a value from the trie.
@@ -512,9 +491,9 @@ ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *
* @param start (const char *, in) the start pointer for the text
* @param src (const char *, in/out) the source text pointer
* @param result (out) variable for the trie lookup result
- * @draft ICU 63
+ * @stable ICU 63
*/
-#define UCPTRIE_FAST_U8_PREV(trie, dataAccess, start, src, result) { \
+#define UCPTRIE_FAST_U8_PREV(trie, dataAccess, start, src, result) UPRV_BLOCK_MACRO_BEGIN { \
int32_t __index = (uint8_t)*--(src); \
if (!U8_IS_SINGLE(__index)) { \
__index = ucptrie_internalU8PrevIndex((trie), __index, (const uint8_t *)(start), \
@@ -523,7 +502,7 @@ ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *
__index >>= 3; \
} \
(result) = dataAccess(trie, __index); \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Returns a trie value for an ASCII code point, without range checking.
@@ -532,7 +511,7 @@ ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *
* @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width
* @param c (UChar32, in) the input code point; must be U+0000..U+007F
* @return The ASCII code point's trie value.
- * @draft ICU 63
+ * @stable ICU 63
*/
#define UCPTRIE_ASCII_GET(trie, dataAccess, c) dataAccess(trie, c)
@@ -545,7 +524,7 @@ ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *
* @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width
* @param c (UChar32, in) the input code point, must be U+0000..U+FFFF
* @return The BMP code point's trie value.
- * @draft ICU 63
+ * @stable ICU 63
*/
#define UCPTRIE_FAST_BMP_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_FAST_INDEX(trie, c))
@@ -557,7 +536,7 @@ ucptrie_toBinary(const UCPTrie *trie, void *data, int32_t capacity, UErrorCode *
* @param dataAccess UCPTRIE_16, UCPTRIE_32, or UCPTRIE_8 according to the trie’s value width
* @param c (UChar32, in) the input code point, must be U+10000..U+10FFFF
* @return The supplementary code point's trie value.
- * @draft ICU 63
+ * @stable ICU 63
*/
#define UCPTRIE_FAST_SUPP_GET(trie, dataAccess, c) dataAccess(trie, _UCPTRIE_SMALL_INDEX(trie, c))
@@ -642,5 +621,24 @@ ucptrie_internalU8PrevIndex(const UCPTrie *trie, UChar32 c,
U_CDECL_END
#endif // U_IN_DOXYGEN
-#endif // U_HIDE_DRAFT_API
+
+#if U_SHOW_CPLUSPLUS_API
+
+U_NAMESPACE_BEGIN
+
+/**
+ * \class LocalUCPTriePointer
+ * "Smart pointer" class, closes a UCPTrie via ucptrie_close().
+ * For most methods see the LocalPointerBase base class.
+ *
+ * @see LocalPointerBase
+ * @see LocalPointer
+ * @stable ICU 63
+ */
+U_DEFINE_LOCAL_OPEN_POINTER(LocalUCPTriePointer, UCPTrie, ucptrie_close);
+
+U_NAMESPACE_END
+
+#endif // U_SHOW_CPLUSPLUS_API
+
#endif
diff --git a/deps/icu-small/source/common/unicode/ucurr.h b/deps/icu-small/source/common/unicode/ucurr.h
index a1c6de80b7..7149e7adf1 100644
--- a/deps/icu-small/source/common/unicode/ucurr.h
+++ b/deps/icu-small/source/common/unicode/ucurr.h
@@ -159,14 +159,14 @@ ucurr_unregister(UCurrRegistryKey key, UErrorCode* status);
* @param currency null-terminated 3-letter ISO 4217 code
* @param locale locale in which to display currency
* @param nameStyle selector for which kind of name to return
- * @param isChoiceFormat fill-in set to TRUE if the returned value
- * is a ChoiceFormat pattern; otherwise it is a static string
+ * @param isChoiceFormat always set to FALSE, or can be NULL;
+ * display names are static strings;
+ * since ICU 4.4, ChoiceFormat patterns are no longer supported
* @param len fill-in parameter to receive length of result
* @param ec error code
* @return pointer to display string of 'len' UChars. If the resource
* data contains no entry for 'currency', then 'currency' itself is
- * returned. If *isChoiceFormat is TRUE, then the result is a
- * ChoiceFormat pattern. Otherwise it is a static string.
+ * returned.
* @stable ICU 2.6
*/
U_STABLE const UChar* U_EXPORT2
@@ -183,8 +183,9 @@ ucurr_getName(const UChar* currency,
* currency object in the en_US locale is "US dollar" or "US dollars".
* @param currency null-terminated 3-letter ISO 4217 code
* @param locale locale in which to display currency
- * @param isChoiceFormat fill-in set to TRUE if the returned value
- * is a ChoiceFormat pattern; otherwise it is a static string
+ * @param isChoiceFormat always set to FALSE, or can be NULL;
+ * display names are static strings;
+ * since ICU 4.4, ChoiceFormat patterns are no longer supported
* @param pluralCount plural count
* @param len fill-in parameter to receive length of result
* @param ec error code
@@ -320,7 +321,7 @@ typedef enum UCurrCurrencyType {
* Provides a UEnumeration object for listing ISO-4217 codes.
* @param currType You can use one of several UCurrCurrencyType values for this
* variable. You can also | (or) them together to get a specific list of
- * currencies. Most people will want to use the (UCURR_CURRENCY|UCURR_NON_DEPRECATED) value to
+ * currencies. Most people will want to use the (UCURR_COMMON|UCURR_NON_DEPRECATED) value to
* get a list of current currencies.
* @param pErrorCode Error code
* @stable ICU 3.2
diff --git a/deps/icu-small/source/common/unicode/udata.h b/deps/icu-small/source/common/unicode/udata.h
index 6419c359f6..8236877b44 100644
--- a/deps/icu-small/source/common/unicode/udata.h
+++ b/deps/icu-small/source/common/unicode/udata.h
@@ -264,25 +264,6 @@ udata_openChoice(const char *path, const char *type, const char *name,
U_STABLE void U_EXPORT2
udata_close(UDataMemory *pData);
-#if U_SHOW_CPLUSPLUS_API
-
-U_NAMESPACE_BEGIN
-
-/**
- * \class LocalUDataMemoryPointer
- * "Smart pointer" class, closes a UDataMemory via udata_close().
- * For most methods see the LocalPointerBase base class.
- *
- * @see LocalPointerBase
- * @see LocalPointer
- * @stable ICU 4.4
- */
-U_DEFINE_LOCAL_OPEN_POINTER(LocalUDataMemoryPointer, UDataMemory, udata_close);
-
-U_NAMESPACE_END
-
-#endif
-
/**
* Get the pointer to the actual data inside the data memory.
* The data is read-only.
@@ -434,4 +415,23 @@ udata_setFileAccess(UDataFileAccess access, UErrorCode *status);
U_CDECL_END
+#if U_SHOW_CPLUSPLUS_API
+
+U_NAMESPACE_BEGIN
+
+/**
+ * \class LocalUDataMemoryPointer
+ * "Smart pointer" class, closes a UDataMemory via udata_close().
+ * For most methods see the LocalPointerBase base class.
+ *
+ * @see LocalPointerBase
+ * @see LocalPointer
+ * @stable ICU 4.4
+ */
+U_DEFINE_LOCAL_OPEN_POINTER(LocalUDataMemoryPointer, UDataMemory, udata_close);
+
+U_NAMESPACE_END
+
+#endif // U_SHOW_CPLUSPLUS_API
+
#endif
diff --git a/deps/icu-small/source/common/unicode/uloc.h b/deps/icu-small/source/common/unicode/uloc.h
index 5531070841..882f79bedc 100644
--- a/deps/icu-small/source/common/unicode/uloc.h
+++ b/deps/icu-small/source/common/unicode/uloc.h
@@ -742,12 +742,18 @@ uloc_getDisplayName(const char* localeID,
/**
- * Gets the specified locale from a list of all available locales.
- * The return value is a pointer to an item of
- * a locale name array. Both this array and the pointers
- * it contains are owned by ICU and should not be deleted or written through
- * by the caller. The locale name is terminated by a null pointer.
- * @param n the specific locale name index of the available locale list
+ * Gets the specified locale from a list of available locales.
+ *
+ * This method corresponds to uloc_openAvailableByType called with the
+ * ULOC_AVAILABLE_DEFAULT type argument.
+ *
+ * The return value is a pointer to an item of a locale name array. Both this
+ * array and the pointers it contains are owned by ICU and should not be
+ * deleted or written through by the caller. The locale name is terminated by
+ * a null pointer.
+ *
+ * @param n the specific locale name index of the available locale list;
+ * should not exceed the number returned by uloc_countAvailable.
* @return a specified locale name of all available locales
* @stable ICU 2.0
*/
@@ -762,6 +768,72 @@ uloc_getAvailable(int32_t n);
*/
U_STABLE int32_t U_EXPORT2 uloc_countAvailable(void);
+#ifndef U_HIDE_DRAFT_API
+
+/**
+ * Types for uloc_getAvailableByType and uloc_countAvailableByType.
+ *
+ * @draft ICU 65
+ */
+typedef enum ULocAvailableType {
+ /**
+ * Locales that return data when passed to ICU APIs,
+ * but not including legacy or alias locales.
+ *
+ * @draft ICU 65
+ */
+ ULOC_AVAILABLE_DEFAULT,
+
+ /**
+ * Legacy or alias locales that return data when passed to ICU APIs.
+ * Examples of supported legacy or alias locales:
+ *
+ * - iw (alias to he)
+ * - mo (alias to ro)
+ * - zh_CN (alias to zh_Hans_CN)
+ * - sr_BA (alias to sr_Cyrl_BA)
+ * - ars (alias to ar_SA)
+ *
+ * The locales in this set are disjoint from the ones in
+ * ULOC_AVAILABLE_DEFAULT. To get both sets at the same time, use
+ * ULOC_AVAILABLE_WITH_LEGACY_ALIASES.
+ *
+ * @draft ICU 65
+ */
+ ULOC_AVAILABLE_ONLY_LEGACY_ALIASES,
+
+ /**
+ * The union of the locales in ULOC_AVAILABLE_DEFAULT and
+ * ULOC_AVAILABLE_ONLY_LEGACY_ALIAS.
+ *
+ * @draft ICU 65
+ */
+ ULOC_AVAILABLE_WITH_LEGACY_ALIASES,
+
+#ifndef U_HIDE_INTERNAL_API
+ /**
+ * @internal
+ */
+ ULOC_AVAILABLE_COUNT
+#endif
+} ULocAvailableType;
+
+/**
+ * Gets a list of available locales according to the type argument, allowing
+ * the user to access different sets of supported locales in ICU.
+ *
+ * The returned UEnumeration must be closed by the caller.
+ *
+ * @param type Type choice from ULocAvailableType.
+ * @param status Set if an error occurred.
+ * @return a UEnumeration owned by the caller, or nullptr on failure.
+ * @draft ICU 65
+ */
+U_DRAFT UEnumeration* U_EXPORT2
+uloc_openAvailableByType(ULocAvailableType type, UErrorCode* status);
+
+#endif // U_HIDE_DRAFT_API
+
/**
*
* Gets a list of all available 2-letter language codes defined in ISO 639,
diff --git a/deps/icu-small/source/common/unicode/umachine.h b/deps/icu-small/source/common/unicode/umachine.h
index 6d932cfcfb..5cb95e58f3 100644
--- a/deps/icu-small/source/common/unicode/umachine.h
+++ b/deps/icu-small/source/common/unicode/umachine.h
@@ -140,6 +140,42 @@
#define U_FINAL final
#endif
+// Before ICU 65, function-like, multi-statement ICU macros were just defined as
+// series of statements wrapped in { } blocks and the caller could choose to
+// either treat them as if they were actual functions and end the invocation
+// with a trailing ; creating an empty statement after the block or else omit
+// this trailing ; using the knowledge that the macro would expand to { }.
+//
+// But doing so doesn't work well with macros that look like functions and
+// compiler warnings about empty statements (ICU-20601) and ICU 65 therefore
+// switches to the standard solution of wrapping such macros in do { } while.
+//
+// This will however break existing code that depends on being able to invoke
+// these macros without a trailing ; so to be able to remain compatible with
+// such code the wrapper is itself defined as macros so that it's possible to
+// build ICU 65 and later with the old macro behaviour, like this:
+//
+// export CPPFLAGS='-DUPRV_BLOCK_MACRO_BEGIN="" -DUPRV_BLOCK_MACRO_END=""'
+// runConfigureICU ...
+//
+
+/**
+ * \def UPRV_BLOCK_MACRO_BEGIN
+ * Defined as the "do" keyword by default.
+ * @internal
+ */
+#ifndef UPRV_BLOCK_MACRO_BEGIN
+#define UPRV_BLOCK_MACRO_BEGIN do
+#endif
+
+/**
+ * \def UPRV_BLOCK_MACRO_END
+ * Defined as "while (FALSE)" by default.
+ * @internal
+ */
+#ifndef UPRV_BLOCK_MACRO_END
+#define UPRV_BLOCK_MACRO_END while (FALSE)
+#endif
/*==========================================================================*/
/* limits for int32_t etc., like in POSIX inttypes.h */
diff --git a/deps/icu-small/source/common/unicode/umutablecptrie.h b/deps/icu-small/source/common/unicode/umutablecptrie.h
index e75191a449..13e71ef25e 100644
--- a/deps/icu-small/source/common/unicode/umutablecptrie.h
+++ b/deps/icu-small/source/common/unicode/umutablecptrie.h
@@ -9,8 +9,6 @@
#include "unicode/utypes.h"
-#ifndef U_HIDE_DRAFT_API
-
#include "unicode/localpointer.h"
#include "unicode/ucpmap.h"
#include "unicode/ucptrie.h"
@@ -44,7 +42,7 @@ U_CDECL_BEGIN
*
* @see UCPTrie
* @see umutablecptrie_buildImmutable
- * @draft ICU 63
+ * @stable ICU 63
*/
typedef struct UMutableCPTrie UMutableCPTrie;
@@ -59,7 +57,7 @@ typedef struct UMutableCPTrie UMutableCPTrie;
* @param errorValue the value for out-of-range code points and ill-formed UTF-8/16
* @param pErrorCode an in/out ICU UErrorCode
* @return the trie
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI UMutableCPTrie * U_EXPORT2
umutablecptrie_open(uint32_t initialValue, uint32_t errorValue, UErrorCode *pErrorCode);
@@ -71,7 +69,7 @@ umutablecptrie_open(uint32_t initialValue, uint32_t errorValue, UErrorCode *pErr
* @param other the trie to clone
* @param pErrorCode an in/out ICU UErrorCode
* @return the trie clone
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI UMutableCPTrie * U_EXPORT2
umutablecptrie_clone(const UMutableCPTrie *other, UErrorCode *pErrorCode);
@@ -80,7 +78,7 @@ umutablecptrie_clone(const UMutableCPTrie *other, UErrorCode *pErrorCode);
* Closes a mutable trie and releases associated memory.
*
* @param trie the trie
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI void U_EXPORT2
umutablecptrie_close(UMutableCPTrie *trie);
@@ -96,7 +94,7 @@ U_NAMESPACE_BEGIN
*
* @see LocalPointerBase
* @see LocalPointer
- * @draft ICU 63
+ * @stable ICU 63
*/
U_DEFINE_LOCAL_OPEN_POINTER(LocalUMutableCPTriePointer, UMutableCPTrie, umutablecptrie_close);
@@ -111,7 +109,7 @@ U_NAMESPACE_END
* @param map the source map
* @param pErrorCode an in/out ICU UErrorCode
* @return the mutable trie
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI UMutableCPTrie * U_EXPORT2
umutablecptrie_fromUCPMap(const UCPMap *map, UErrorCode *pErrorCode);
@@ -123,7 +121,7 @@ umutablecptrie_fromUCPMap(const UCPMap *map, UErrorCode *pErrorCode);
* @param trie the immutable trie
* @param pErrorCode an in/out ICU UErrorCode
* @return the mutable trie
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI UMutableCPTrie * U_EXPORT2
umutablecptrie_fromUCPTrie(const UCPTrie *trie, UErrorCode *pErrorCode);
@@ -134,7 +132,7 @@ umutablecptrie_fromUCPTrie(const UCPTrie *trie, UErrorCode *pErrorCode);
* @param trie the trie
* @param c the code point
* @return the value
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI uint32_t U_EXPORT2
umutablecptrie_get(const UMutableCPTrie *trie, UChar32 c);
@@ -166,7 +164,7 @@ umutablecptrie_get(const UMutableCPTrie *trie, UChar32 c);
* may have been modified by filter(context, trie value)
* if that function pointer is not NULL
* @return the range end code point, or -1 if start is not a valid code point
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI UChar32 U_EXPORT2
umutablecptrie_getRange(const UMutableCPTrie *trie, UChar32 start,
@@ -180,7 +178,7 @@ umutablecptrie_getRange(const UMutableCPTrie *trie, UChar32 start,
* @param c the code point
* @param value the value
* @param pErrorCode an in/out ICU UErrorCode
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI void U_EXPORT2
umutablecptrie_set(UMutableCPTrie *trie, UChar32 c, uint32_t value, UErrorCode *pErrorCode);
@@ -194,7 +192,7 @@ umutablecptrie_set(UMutableCPTrie *trie, UChar32 c, uint32_t value, UErrorCode *
* @param end the last code point to get the value (inclusive)
* @param value the value
* @param pErrorCode an in/out ICU UErrorCode
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI void U_EXPORT2
umutablecptrie_setRange(UMutableCPTrie *trie,
@@ -229,7 +227,7 @@ umutablecptrie_setRange(UMutableCPTrie *trie,
* @param pErrorCode an in/out ICU UErrorCode
*
* @see umutablecptrie_fromUCPTrie
- * @draft ICU 63
+ * @stable ICU 63
*/
U_CAPI UCPTrie * U_EXPORT2
umutablecptrie_buildImmutable(UMutableCPTrie *trie, UCPTrieType type, UCPTrieValueWidth valueWidth,
@@ -237,5 +235,4 @@ umutablecptrie_buildImmutable(UMutableCPTrie *trie, UCPTrieType type, UCPTrieVal
U_CDECL_END
-#endif // U_HIDE_DRAFT_API
#endif
diff --git a/deps/icu-small/source/common/unicode/unifilt.h b/deps/icu-small/source/common/unicode/unifilt.h
index 99cce785b6..1a77089233 100644
--- a/deps/icu-small/source/common/unicode/unifilt.h
+++ b/deps/icu-small/source/common/unicode/unifilt.h
@@ -12,6 +12,10 @@
#ifndef UNIFILT_H
#define UNIFILT_H
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/unifunct.h"
#include "unicode/unimatch.h"
@@ -68,6 +72,14 @@ public:
virtual ~UnicodeFilter();
/**
+ * Clones this object polymorphically.
+ * The caller owns the result and should delete it when done.
+ * @return clone, or nullptr if an error occurred
+ * @stable ICU 2.4
+ */
+ virtual UnicodeFilter* clone() const = 0;
+
+ /**
* Returns <tt>true</tt> for characters that are in the selected
* subset. In other words, if a character is <b>to be
* filtered</b>, then <tt>contains()</tt> returns
@@ -119,4 +131,6 @@ protected:
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/unifunct.h b/deps/icu-small/source/common/unicode/unifunct.h
index 66a02ce7cd..2b1b766ea7 100644
--- a/deps/icu-small/source/common/unicode/unifunct.h
+++ b/deps/icu-small/source/common/unicode/unifunct.h
@@ -13,6 +13,9 @@
#define UNIFUNCT_H
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/uobject.h"
/**
@@ -124,4 +127,6 @@ protected:
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/unimatch.h b/deps/icu-small/source/common/unicode/unimatch.h
index 8bf3995018..2d3c5210c3 100644
--- a/deps/icu-small/source/common/unicode/unimatch.h
+++ b/deps/icu-small/source/common/unicode/unimatch.h
@@ -17,6 +17,7 @@
* \brief C++ API: Unicode Matcher
*/
+#if U_SHOW_CPLUSPLUS_API
U_NAMESPACE_BEGIN
@@ -162,4 +163,6 @@ public:
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/uniset.h b/deps/icu-small/source/common/unicode/uniset.h
index e5e7726d60..18cc937644 100644
--- a/deps/icu-small/source/common/unicode/uniset.h
+++ b/deps/icu-small/source/common/unicode/uniset.h
@@ -13,6 +13,10 @@
#ifndef UNICODESET_H
#define UNICODESET_H
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/ucpmap.h"
#include "unicode/unifilt.h"
#include "unicode/unistr.h"
@@ -501,7 +505,7 @@ public:
* @see cloneAsThawed
* @stable ICU 2.0
*/
- virtual UnicodeFunctor* clone() const;
+ virtual UnicodeSet* clone() const;
/**
* Returns the hash code value for this set.
@@ -579,7 +583,7 @@ public:
* @see cloneAsThawed
* @stable ICU 3.8
*/
- UnicodeFunctor *freeze();
+ UnicodeSet *freeze();
/**
* Clone the set and make the clone mutable.
@@ -589,7 +593,7 @@ public:
* @see isFrozen
* @stable ICU 3.8
*/
- UnicodeFunctor *cloneAsThawed() const;
+ UnicodeSet *cloneAsThawed() const;
//----------------------------------------------------------------
// Public API
@@ -1651,11 +1655,10 @@ private:
const UnicodeSet* inclusions,
UErrorCode &status);
-#ifndef U_HIDE_DRAFT_API // Skipped: ucpmap.h is draft only.
+ // UCPMap is now stable ICU 63
void applyIntPropertyValue(const UCPMap *map,
UCPMapValueFilter *filter, const void *context,
UErrorCode &errorCode);
-#endif /* U_HIDE_DRAFT_API */
/**
* Set the new pattern to cache.
@@ -1736,4 +1739,6 @@ inline int32_t UnicodeSet::spanBack(const UnicodeString &s, int32_t limit, USetS
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/unistr.h b/deps/icu-small/source/common/unicode/unistr.h
index 8fd144425e..da79053765 100644
--- a/deps/icu-small/source/common/unicode/unistr.h
+++ b/deps/icu-small/source/common/unicode/unistr.h
@@ -28,8 +28,11 @@
* \brief C++ API: Unicode String
*/
-#include <cstddef>
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
+#include <cstddef>
#include "unicode/char16ptr.h"
#include "unicode/rep.h"
#include "unicode/std_string.h"
@@ -209,7 +212,9 @@ class UnicodeStringAppendable; // unicode/appendable.h
* similar functionality as the Java String and StringBuffer/StringBuilder classes.
* It is a concrete implementation of the abstract class Replaceable (for transliteration).
*
- * A UnicodeString may also "alias" an external array of characters
+ * The UnicodeString equivalent of std::string’s clear() is remove().
+ *
+ * A UnicodeString may "alias" an external array of characters
* (that is, point to it, rather than own the array)
* whose lifetime must then at least match the lifetime of the aliasing object.
* This aliasing may be preserved when returning a UnicodeString by value,
@@ -2092,8 +2097,7 @@ public:
* s.truncate(0); // set to an empty string (complete truncation), or
* s=UnicodeString(); // assign an empty string, or
* s.setTo((UChar32)-1); // set to a pseudo code point that is out of range, or
- * static const char16_t nul=0;
- * s.setTo(&nul, 0); // set to an empty C Unicode string
+ * s.setTo(u"", 0); // set to an empty C Unicode string
* }
* \endcode
*
@@ -2534,11 +2538,14 @@ public:
/* Remove operations */
/**
- * Remove all characters from the UnicodeString object.
+ * Removes all characters from the UnicodeString object and clears the bogus flag.
+ * This is the UnicodeString equivalent of std::string’s clear().
+ *
* @return a reference to this
+ * @see setToBogus
* @stable ICU 2.0
*/
- inline UnicodeString& remove(void);
+ inline UnicodeString& remove();
/**
* Remove the characters in the range
@@ -3034,11 +3041,11 @@ public:
* uint16_t * constructor.
* Delegates to UnicodeString(const char16_t *, int32_t).
* @param text UTF-16 string
- * @param length string length
+ * @param textLength string length
* @stable ICU 59
*/
- UnicodeString(const uint16_t *text, int32_t length) :
- UnicodeString(ConstChar16Ptr(text), length) {}
+ UnicodeString(const uint16_t *text, int32_t textLength) :
+ UnicodeString(ConstChar16Ptr(text), textLength) {}
#endif
#if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN)
@@ -3047,21 +3054,21 @@ public:
* (Only defined if U_SIZEOF_WCHAR_T==2.)
* Delegates to UnicodeString(const char16_t *, int32_t).
* @param text NUL-terminated UTF-16 string
- * @param length string length
+ * @param textLength string length
* @stable ICU 59
*/
- UnicodeString(const wchar_t *text, int32_t length) :
- UnicodeString(ConstChar16Ptr(text), length) {}
+ UnicodeString(const wchar_t *text, int32_t textLength) :
+ UnicodeString(ConstChar16Ptr(text), textLength) {}
#endif
/**
* nullptr_t constructor.
* Effectively the same as the default constructor, makes an empty string object.
* @param text nullptr
- * @param length ignored
+ * @param textLength ignored
* @stable ICU 59
*/
- inline UnicodeString(const std::nullptr_t text, int32_t length);
+ inline UnicodeString(const std::nullptr_t text, int32_t textLength);
/**
* Readonly-aliasing char16_t* constructor.
@@ -3266,13 +3273,13 @@ public:
* }
* \endcode
* @param src String using only invariant characters.
- * @param length Length of src, or -1 if NUL-terminated.
+ * @param textLength Length of src, or -1 if NUL-terminated.
* @param inv Signature-distinguishing paramater, use US_INV.
*
* @see US_INV
* @stable ICU 3.2
*/
- UnicodeString(const char *src, int32_t length, enum EInvariant inv);
+ UnicodeString(const char *src, int32_t textLength, enum EInvariant inv);
/**
@@ -3323,9 +3330,6 @@ public:
* Clones can be used concurrently in multiple threads.
* If a subclass does not implement clone(), or if an error occurs,
* then NULL is returned.
- * The clone functions in all subclasses return a pointer to a Replaceable
- * because some compilers do not support covariant (same-as-this)
- * return types; cast to the appropriate subclass if necessary.
* The caller must delete the clone.
*
* @return a clone of this object
@@ -3334,7 +3338,7 @@ public:
* @see getDynamicClassID
* @stable ICU 2.6
*/
- virtual Replaceable *clone() const;
+ virtual UnicodeString *clone() const;
/** Destructor.
* @stable ICU 2.0
@@ -4748,4 +4752,6 @@ UnicodeString::reverse(int32_t start,
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/unorm.h b/deps/icu-small/source/common/unicode/unorm.h
index 3839de1295..09dd366a96 100644
--- a/deps/icu-small/source/common/unicode/unorm.h
+++ b/deps/icu-small/source/common/unicode/unorm.h
@@ -131,6 +131,8 @@
// Do not conditionalize the following enum with #ifndef U_HIDE_DEPRECATED_API,
// it is needed for layout of Normalizer object.
+#ifndef U_FORCE_HIDE_DEPRECATED_API
+
/**
* Constants for normalization modes.
* @deprecated ICU 56 Use unorm2.h instead.
@@ -155,6 +157,8 @@ typedef enum {
UNORM_MODE_COUNT
} UNormalizationMode;
+#endif // U_FORCE_HIDE_DEPRECATED_API
+
#ifndef U_HIDE_DEPRECATED_API
/**
diff --git a/deps/icu-small/source/common/unicode/uobject.h b/deps/icu-small/source/common/unicode/uobject.h
index 53b8eb005f..6a137af83c 100644
--- a/deps/icu-small/source/common/unicode/uobject.h
+++ b/deps/icu-small/source/common/unicode/uobject.h
@@ -20,6 +20,9 @@
#define __UOBJECT_H__
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/platform.h"
/**
@@ -43,7 +46,7 @@
* @stable ICU 4.2. Since ICU 64, Use U_NOEXCEPT instead. See ICU-20422.
*/
#ifndef U_NO_THROW
-#define U_NO_THROW throw()
+#define U_NO_THROW U_NOEXCEPT
#endif
/*===========================================================================*/
@@ -212,11 +215,8 @@ public:
* The clone() function is not available in UObject because it is not
* implemented by all ICU classes.
* Many ICU services provide a clone() function for their class trees,
- * defined on the service's C++ base class, and all subclasses within that
- * service class tree return a pointer to the service base class
+ * defined on the service's C++ base class
* (which itself is a subclass of UObject).
- * This is because some compilers do not support covariant (same-as-this)
- * return types; cast to the appropriate subclass if necessary.
*
* @stable ICU 2.2
*/
@@ -319,4 +319,6 @@ protected:
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/urename.h b/deps/icu-small/source/common/unicode/urename.h
index eaf56c9614..e302bf0976 100644
--- a/deps/icu-small/source/common/unicode/urename.h
+++ b/deps/icu-small/source/common/unicode/urename.h
@@ -193,10 +193,13 @@
#define res_getAlias U_ICU_ENTRY_POINT_RENAME(res_getAlias)
#define res_getArrayItem U_ICU_ENTRY_POINT_RENAME(res_getArrayItem)
#define res_getBinary U_ICU_ENTRY_POINT_RENAME(res_getBinary)
+#define res_getBinaryNoTrace U_ICU_ENTRY_POINT_RENAME(res_getBinaryNoTrace)
#define res_getIntVector U_ICU_ENTRY_POINT_RENAME(res_getIntVector)
+#define res_getIntVectorNoTrace U_ICU_ENTRY_POINT_RENAME(res_getIntVectorNoTrace)
#define res_getPublicType U_ICU_ENTRY_POINT_RENAME(res_getPublicType)
#define res_getResource U_ICU_ENTRY_POINT_RENAME(res_getResource)
#define res_getString U_ICU_ENTRY_POINT_RENAME(res_getString)
+#define res_getStringNoTrace U_ICU_ENTRY_POINT_RENAME(res_getStringNoTrace)
#define res_getTableItemByIndex U_ICU_ENTRY_POINT_RENAME(res_getTableItemByIndex)
#define res_getTableItemByKey U_ICU_ENTRY_POINT_RENAME(res_getTableItemByKey)
#define res_load U_ICU_ENTRY_POINT_RENAME(res_load)
@@ -523,6 +526,7 @@
#define ucal_getDefaultTimeZone U_ICU_ENTRY_POINT_RENAME(ucal_getDefaultTimeZone)
#define ucal_getFieldDifference U_ICU_ENTRY_POINT_RENAME(ucal_getFieldDifference)
#define ucal_getGregorianChange U_ICU_ENTRY_POINT_RENAME(ucal_getGregorianChange)
+#define ucal_getHostTimeZone U_ICU_ENTRY_POINT_RENAME(ucal_getHostTimeZone)
#define ucal_getKeywordValuesForLocale U_ICU_ENTRY_POINT_RENAME(ucal_getKeywordValuesForLocale)
#define ucal_getLimit U_ICU_ENTRY_POINT_RENAME(ucal_getLimit)
#define ucal_getLocaleByType U_ICU_ENTRY_POINT_RENAME(ucal_getLocaleByType)
@@ -575,7 +579,6 @@
#define ucasemap_getLocale U_ICU_ENTRY_POINT_RENAME(ucasemap_getLocale)
#define ucasemap_getOptions U_ICU_ENTRY_POINT_RENAME(ucasemap_getOptions)
#define ucasemap_internalUTF8ToTitle U_ICU_ENTRY_POINT_RENAME(ucasemap_internalUTF8ToTitle)
-#define ucasemap_mapUTF8 U_ICU_ENTRY_POINT_RENAME(ucasemap_mapUTF8)
#define ucasemap_open U_ICU_ENTRY_POINT_RENAME(ucasemap_open)
#define ucasemap_setBreakIterator U_ICU_ENTRY_POINT_RENAME(ucasemap_setBreakIterator)
#define ucasemap_setLocale U_ICU_ENTRY_POINT_RENAME(ucasemap_setLocale)
@@ -930,16 +933,9 @@
#define ufieldpositer_close U_ICU_ENTRY_POINT_RENAME(ufieldpositer_close)
#define ufieldpositer_next U_ICU_ENTRY_POINT_RENAME(ufieldpositer_next)
#define ufieldpositer_open U_ICU_ENTRY_POINT_RENAME(ufieldpositer_open)
-#define ufile_close_translit U_ICU_ENTRY_POINT_RENAME(ufile_close_translit)
-#define ufile_fill_uchar_buffer U_ICU_ENTRY_POINT_RENAME(ufile_fill_uchar_buffer)
-#define ufile_flush_io U_ICU_ENTRY_POINT_RENAME(ufile_flush_io)
-#define ufile_flush_translit U_ICU_ENTRY_POINT_RENAME(ufile_flush_translit)
#define ufile_getch U_ICU_ENTRY_POINT_RENAME(ufile_getch)
#define ufile_getch32 U_ICU_ENTRY_POINT_RENAME(ufile_getch32)
-#define ufmt_64tou U_ICU_ENTRY_POINT_RENAME(ufmt_64tou)
#define ufmt_close U_ICU_ENTRY_POINT_RENAME(ufmt_close)
-#define ufmt_defaultCPToUnicode U_ICU_ENTRY_POINT_RENAME(ufmt_defaultCPToUnicode)
-#define ufmt_digitvalue U_ICU_ENTRY_POINT_RENAME(ufmt_digitvalue)
#define ufmt_getArrayItemByIndex U_ICU_ENTRY_POINT_RENAME(ufmt_getArrayItemByIndex)
#define ufmt_getArrayLength U_ICU_ENTRY_POINT_RENAME(ufmt_getArrayLength)
#define ufmt_getDate U_ICU_ENTRY_POINT_RENAME(ufmt_getDate)
@@ -951,11 +947,7 @@
#define ufmt_getType U_ICU_ENTRY_POINT_RENAME(ufmt_getType)
#define ufmt_getUChars U_ICU_ENTRY_POINT_RENAME(ufmt_getUChars)
#define ufmt_isNumeric U_ICU_ENTRY_POINT_RENAME(ufmt_isNumeric)
-#define ufmt_isdigit U_ICU_ENTRY_POINT_RENAME(ufmt_isdigit)
#define ufmt_open U_ICU_ENTRY_POINT_RENAME(ufmt_open)
-#define ufmt_ptou U_ICU_ENTRY_POINT_RENAME(ufmt_ptou)
-#define ufmt_uto64 U_ICU_ENTRY_POINT_RENAME(ufmt_uto64)
-#define ufmt_utop U_ICU_ENTRY_POINT_RENAME(ufmt_utop)
#define ufmtval_getString U_ICU_ENTRY_POINT_RENAME(ufmtval_getString)
#define ufmtval_nextPosition U_ICU_ENTRY_POINT_RENAME(ufmtval_nextPosition)
#define ugender_getInstance U_ICU_ENTRY_POINT_RENAME(ugender_getInstance)
@@ -1103,6 +1095,7 @@
#define uloc_getVariant U_ICU_ENTRY_POINT_RENAME(uloc_getVariant)
#define uloc_isRightToLeft U_ICU_ENTRY_POINT_RENAME(uloc_isRightToLeft)
#define uloc_minimizeSubtags U_ICU_ENTRY_POINT_RENAME(uloc_minimizeSubtags)
+#define uloc_openAvailableByType U_ICU_ENTRY_POINT_RENAME(uloc_openAvailableByType)
#define uloc_openKeywordList U_ICU_ENTRY_POINT_RENAME(uloc_openKeywordList)
#define uloc_openKeywords U_ICU_ENTRY_POINT_RENAME(uloc_openKeywords)
#define uloc_setDefault U_ICU_ENTRY_POINT_RENAME(uloc_setDefault)
@@ -1159,9 +1152,6 @@
#define umsg_toPattern U_ICU_ENTRY_POINT_RENAME(umsg_toPattern)
#define umsg_vformat U_ICU_ENTRY_POINT_RENAME(umsg_vformat)
#define umsg_vparse U_ICU_ENTRY_POINT_RENAME(umsg_vparse)
-#define umtx_condBroadcast U_ICU_ENTRY_POINT_RENAME(umtx_condBroadcast)
-#define umtx_condSignal U_ICU_ENTRY_POINT_RENAME(umtx_condSignal)
-#define umtx_condWait U_ICU_ENTRY_POINT_RENAME(umtx_condWait)
#define umtx_lock U_ICU_ENTRY_POINT_RENAME(umtx_lock)
#define umtx_unlock U_ICU_ENTRY_POINT_RENAME(umtx_unlock)
#define umutablecptrie_buildImmutable U_ICU_ENTRY_POINT_RENAME(umutablecptrie_buildImmutable)
@@ -1327,7 +1317,6 @@
#define uprv_decNumberAbs U_ICU_ENTRY_POINT_RENAME(uprv_decNumberAbs)
#define uprv_decNumberAdd U_ICU_ENTRY_POINT_RENAME(uprv_decNumberAdd)
#define uprv_decNumberAnd U_ICU_ENTRY_POINT_RENAME(uprv_decNumberAnd)
-#define uprv_decNumberClass U_ICU_ENTRY_POINT_RENAME(uprv_decNumberClass)
#define uprv_decNumberClassToString U_ICU_ENTRY_POINT_RENAME(uprv_decNumberClassToString)
#define uprv_decNumberCompare U_ICU_ENTRY_POINT_RENAME(uprv_decNumberCompare)
#define uprv_decNumberCompareSignal U_ICU_ENTRY_POINT_RENAME(uprv_decNumberCompareSignal)
@@ -1393,6 +1382,7 @@
#define uprv_dlsym_func U_ICU_ENTRY_POINT_RENAME(uprv_dlsym_func)
#define uprv_eastrncpy U_ICU_ENTRY_POINT_RENAME(uprv_eastrncpy)
#define uprv_ebcdicFromAscii U_ICU_ENTRY_POINT_RENAME(uprv_ebcdicFromAscii)
+#define uprv_ebcdicToAscii U_ICU_ENTRY_POINT_RENAME(uprv_ebcdicToAscii)
#define uprv_ebcdicToLowercaseAscii U_ICU_ENTRY_POINT_RENAME(uprv_ebcdicToLowercaseAscii)
#define uprv_ebcdictolower U_ICU_ENTRY_POINT_RENAME(uprv_ebcdictolower)
#define uprv_fabs U_ICU_ENTRY_POINT_RENAME(uprv_fabs)
@@ -1412,6 +1402,7 @@
#define uprv_getUTCtime U_ICU_ENTRY_POINT_RENAME(uprv_getUTCtime)
#define uprv_int32Comparator U_ICU_ENTRY_POINT_RENAME(uprv_int32Comparator)
#define uprv_isASCIILetter U_ICU_ENTRY_POINT_RENAME(uprv_isASCIILetter)
+#define uprv_isEbcdicAtSign U_ICU_ENTRY_POINT_RENAME(uprv_isEbcdicAtSign)
#define uprv_isInfinite U_ICU_ENTRY_POINT_RENAME(uprv_isInfinite)
#define uprv_isInvariantString U_ICU_ENTRY_POINT_RENAME(uprv_isInvariantString)
#define uprv_isInvariantUString U_ICU_ENTRY_POINT_RENAME(uprv_isInvariantUString)
@@ -1579,6 +1570,7 @@
#define ures_getUTF8String U_ICU_ENTRY_POINT_RENAME(ures_getUTF8String)
#define ures_getUTF8StringByIndex U_ICU_ENTRY_POINT_RENAME(ures_getUTF8StringByIndex)
#define ures_getUTF8StringByKey U_ICU_ENTRY_POINT_RENAME(ures_getUTF8StringByKey)
+#define ures_getValueWithFallback U_ICU_ENTRY_POINT_RENAME(ures_getValueWithFallback)
#define ures_getVersion U_ICU_ENTRY_POINT_RENAME(ures_getVersion)
#define ures_getVersionByKey U_ICU_ENTRY_POINT_RENAME(ures_getVersionByKey)
#define ures_getVersionNumber U_ICU_ENTRY_POINT_RENAME(ures_getVersionNumber)
diff --git a/deps/icu-small/source/common/unicode/usetiter.h b/deps/icu-small/source/common/unicode/usetiter.h
index 057adbc04f..f3f470f95a 100644
--- a/deps/icu-small/source/common/unicode/usetiter.h
+++ b/deps/icu-small/source/common/unicode/usetiter.h
@@ -10,6 +10,9 @@
#define USETITER_H
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/uobject.h"
#include "unicode/unistr.h"
@@ -317,4 +320,6 @@ inline UChar32 UnicodeSetIterator::getCodepointEnd() const {
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/common/unicode/utext.h b/deps/icu-small/source/common/unicode/utext.h
index ff78784c61..6f1e3409d8 100644
--- a/deps/icu-small/source/common/unicode/utext.h
+++ b/deps/icu-small/source/common/unicode/utext.h
@@ -766,12 +766,14 @@ utext_extract(UText *ut,
*
* @stable ICU 3.8
*/
-#define UTEXT_SETNATIVEINDEX(ut, ix) \
- { int64_t __offset = (ix) - (ut)->chunkNativeStart; \
- if (__offset>=0 && __offset<(int64_t)(ut)->nativeIndexingLimit && (ut)->chunkContents[__offset]<0xdc00) { \
- (ut)->chunkOffset=(int32_t)__offset; \
- } else { \
- utext_setNativeIndex((ut), (ix)); } }
+#define UTEXT_SETNATIVEINDEX(ut, ix) UPRV_BLOCK_MACRO_BEGIN { \
+ int64_t __offset = (ix) - (ut)->chunkNativeStart; \
+ if (__offset>=0 && __offset<(int64_t)(ut)->nativeIndexingLimit && (ut)->chunkContents[__offset]<0xdc00) { \
+ (ut)->chunkOffset=(int32_t)__offset; \
+ } else { \
+ utext_setNativeIndex((ut), (ix)); \
+ } \
+} UPRV_BLOCK_MACRO_END
diff --git a/deps/icu-small/source/common/unicode/utf16.h b/deps/icu-small/source/common/unicode/utf16.h
index 0908b4f00e..3315214ae6 100644
--- a/deps/icu-small/source/common/unicode/utf16.h
+++ b/deps/icu-small/source/common/unicode/utf16.h
@@ -163,7 +163,7 @@
* @see U16_GET
* @stable ICU 2.4
*/
-#define U16_GET_UNSAFE(s, i, c) { \
+#define U16_GET_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[i]; \
if(U16_IS_SURROGATE(c)) { \
if(U16_IS_SURROGATE_LEAD(c)) { \
@@ -172,7 +172,7 @@
(c)=U16_GET_SUPPLEMENTARY((s)[(i)-1], (c)); \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Get a code point from a string at a random-access offset,
@@ -197,7 +197,7 @@
* @see U16_GET_UNSAFE
* @stable ICU 2.4
*/
-#define U16_GET(s, start, i, length, c) { \
+#define U16_GET(s, start, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[i]; \
if(U16_IS_SURROGATE(c)) { \
uint16_t __c2; \
@@ -211,7 +211,7 @@
} \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Get a code point from a string at a random-access offset,
@@ -236,7 +236,7 @@
* @see U16_GET_UNSAFE
* @stable ICU 60
*/
-#define U16_GET_OR_FFFD(s, start, i, length, c) { \
+#define U16_GET_OR_FFFD(s, start, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[i]; \
if(U16_IS_SURROGATE(c)) { \
uint16_t __c2; \
@@ -254,7 +254,7 @@
} \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/* definitions with forward iteration --------------------------------------- */
@@ -277,12 +277,12 @@
* @see U16_NEXT
* @stable ICU 2.4
*/
-#define U16_NEXT_UNSAFE(s, i, c) { \
+#define U16_NEXT_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[(i)++]; \
if(U16_IS_LEAD(c)) { \
(c)=U16_GET_SUPPLEMENTARY((c), (s)[(i)++]); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Get a code point from a string at a code point boundary offset,
@@ -305,7 +305,7 @@
* @see U16_NEXT_UNSAFE
* @stable ICU 2.4
*/
-#define U16_NEXT(s, i, length, c) { \
+#define U16_NEXT(s, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[(i)++]; \
if(U16_IS_LEAD(c)) { \
uint16_t __c2; \
@@ -314,7 +314,7 @@
(c)=U16_GET_SUPPLEMENTARY((c), __c2); \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Get a code point from a string at a code point boundary offset,
@@ -337,7 +337,7 @@
* @see U16_NEXT_UNSAFE
* @stable ICU 60
*/
-#define U16_NEXT_OR_FFFD(s, i, length, c) { \
+#define U16_NEXT_OR_FFFD(s, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[(i)++]; \
if(U16_IS_SURROGATE(c)) { \
uint16_t __c2; \
@@ -348,7 +348,7 @@
(c)=0xfffd; \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Append a code point to a string, overwriting 1 or 2 code units.
@@ -363,14 +363,14 @@
* @see U16_APPEND
* @stable ICU 2.4
*/
-#define U16_APPEND_UNSAFE(s, i, c) { \
+#define U16_APPEND_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
if((uint32_t)(c)<=0xffff) { \
(s)[(i)++]=(uint16_t)(c); \
} else { \
(s)[(i)++]=(uint16_t)(((c)>>10)+0xd7c0); \
(s)[(i)++]=(uint16_t)(((c)&0x3ff)|0xdc00); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Append a code point to a string, overwriting 1 or 2 code units.
@@ -389,7 +389,7 @@
* @see U16_APPEND_UNSAFE
* @stable ICU 2.4
*/
-#define U16_APPEND(s, i, capacity, c, isError) { \
+#define U16_APPEND(s, i, capacity, c, isError) UPRV_BLOCK_MACRO_BEGIN { \
if((uint32_t)(c)<=0xffff) { \
(s)[(i)++]=(uint16_t)(c); \
} else if((uint32_t)(c)<=0x10ffff && (i)+1<(capacity)) { \
@@ -398,7 +398,7 @@
} else /* c>0x10ffff or not enough space */ { \
(isError)=TRUE; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Advance the string offset from one code point boundary to the next.
@@ -410,11 +410,11 @@
* @see U16_FWD_1
* @stable ICU 2.4
*/
-#define U16_FWD_1_UNSAFE(s, i) { \
+#define U16_FWD_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
if(U16_IS_LEAD((s)[(i)++])) { \
++(i); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Advance the string offset from one code point boundary to the next.
@@ -429,11 +429,11 @@
* @see U16_FWD_1_UNSAFE
* @stable ICU 2.4
*/
-#define U16_FWD_1(s, i, length) { \
+#define U16_FWD_1(s, i, length) UPRV_BLOCK_MACRO_BEGIN { \
if(U16_IS_LEAD((s)[(i)++]) && (i)!=(length) && U16_IS_TRAIL((s)[i])) { \
++(i); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Advance the string offset from one code point boundary to the n-th next one,
@@ -447,13 +447,13 @@
* @see U16_FWD_N
* @stable ICU 2.4
*/
-#define U16_FWD_N_UNSAFE(s, i, n) { \
+#define U16_FWD_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
int32_t __N=(n); \
while(__N>0) { \
U16_FWD_1_UNSAFE(s, i); \
--__N; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Advance the string offset from one code point boundary to the n-th next one,
@@ -470,13 +470,13 @@
* @see U16_FWD_N_UNSAFE
* @stable ICU 2.4
*/
-#define U16_FWD_N(s, i, length, n) { \
+#define U16_FWD_N(s, i, length, n) UPRV_BLOCK_MACRO_BEGIN { \
int32_t __N=(n); \
while(__N>0 && ((i)<(length) || ((length)<0 && (s)[i]!=0))) { \
U16_FWD_1(s, i, length); \
--__N; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Adjust a random-access offset to a code point boundary
@@ -491,11 +491,11 @@
* @see U16_SET_CP_START
* @stable ICU 2.4
*/
-#define U16_SET_CP_START_UNSAFE(s, i) { \
+#define U16_SET_CP_START_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
if(U16_IS_TRAIL((s)[i])) { \
--(i); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Adjust a random-access offset to a code point boundary
@@ -511,11 +511,11 @@
* @see U16_SET_CP_START_UNSAFE
* @stable ICU 2.4
*/
-#define U16_SET_CP_START(s, start, i) { \
+#define U16_SET_CP_START(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \
if(U16_IS_TRAIL((s)[i]) && (i)>(start) && U16_IS_LEAD((s)[(i)-1])) { \
--(i); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/* definitions with backward iteration -------------------------------------- */
@@ -539,12 +539,12 @@
* @see U16_PREV
* @stable ICU 2.4
*/
-#define U16_PREV_UNSAFE(s, i, c) { \
+#define U16_PREV_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[--(i)]; \
if(U16_IS_TRAIL(c)) { \
(c)=U16_GET_SUPPLEMENTARY((s)[--(i)], (c)); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Move the string offset from one code point boundary to the previous one
@@ -566,7 +566,7 @@
* @see U16_PREV_UNSAFE
* @stable ICU 2.4
*/
-#define U16_PREV(s, start, i, c) { \
+#define U16_PREV(s, start, i, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[--(i)]; \
if(U16_IS_TRAIL(c)) { \
uint16_t __c2; \
@@ -575,7 +575,7 @@
(c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Move the string offset from one code point boundary to the previous one
@@ -597,7 +597,7 @@
* @see U16_PREV_UNSAFE
* @stable ICU 60
*/
-#define U16_PREV_OR_FFFD(s, start, i, c) { \
+#define U16_PREV_OR_FFFD(s, start, i, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[--(i)]; \
if(U16_IS_SURROGATE(c)) { \
uint16_t __c2; \
@@ -608,7 +608,7 @@
(c)=0xfffd; \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Move the string offset from one code point boundary to the previous one.
@@ -621,11 +621,11 @@
* @see U16_BACK_1
* @stable ICU 2.4
*/
-#define U16_BACK_1_UNSAFE(s, i) { \
+#define U16_BACK_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
if(U16_IS_TRAIL((s)[--(i)])) { \
--(i); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Move the string offset from one code point boundary to the previous one.
@@ -639,11 +639,11 @@
* @see U16_BACK_1_UNSAFE
* @stable ICU 2.4
*/
-#define U16_BACK_1(s, start, i) { \
+#define U16_BACK_1(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \
if(U16_IS_TRAIL((s)[--(i)]) && (i)>(start) && U16_IS_LEAD((s)[(i)-1])) { \
--(i); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Move the string offset from one code point boundary to the n-th one before it,
@@ -658,13 +658,13 @@
* @see U16_BACK_N
* @stable ICU 2.4
*/
-#define U16_BACK_N_UNSAFE(s, i, n) { \
+#define U16_BACK_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
int32_t __N=(n); \
while(__N>0) { \
U16_BACK_1_UNSAFE(s, i); \
--__N; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Move the string offset from one code point boundary to the n-th one before it,
@@ -680,13 +680,13 @@
* @see U16_BACK_N_UNSAFE
* @stable ICU 2.4
*/
-#define U16_BACK_N(s, start, i, n) { \
+#define U16_BACK_N(s, start, i, n) UPRV_BLOCK_MACRO_BEGIN { \
int32_t __N=(n); \
while(__N>0 && (i)>(start)) { \
U16_BACK_1(s, start, i); \
--__N; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Adjust a random-access offset to a code point boundary after a code point.
@@ -701,11 +701,11 @@
* @see U16_SET_CP_LIMIT
* @stable ICU 2.4
*/
-#define U16_SET_CP_LIMIT_UNSAFE(s, i) { \
+#define U16_SET_CP_LIMIT_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
if(U16_IS_LEAD((s)[(i)-1])) { \
++(i); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Adjust a random-access offset to a code point boundary after a code point.
@@ -724,10 +724,10 @@
* @see U16_SET_CP_LIMIT_UNSAFE
* @stable ICU 2.4
*/
-#define U16_SET_CP_LIMIT(s, start, i, length) { \
+#define U16_SET_CP_LIMIT(s, start, i, length) UPRV_BLOCK_MACRO_BEGIN { \
if((start)<(i) && ((i)<(length) || (length)<0) && U16_IS_LEAD((s)[(i)-1]) && U16_IS_TRAIL((s)[i])) { \
++(i); \
} \
-}
+} UPRV_BLOCK_MACRO_END
#endif
diff --git a/deps/icu-small/source/common/unicode/utf8.h b/deps/icu-small/source/common/unicode/utf8.h
index 41155f119b..bb00130374 100644
--- a/deps/icu-small/source/common/unicode/utf8.h
+++ b/deps/icu-small/source/common/unicode/utf8.h
@@ -229,11 +229,11 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_GET
* @stable ICU 2.4
*/
-#define U8_GET_UNSAFE(s, i, c) { \
+#define U8_GET_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
int32_t _u8_get_unsafe_index=(int32_t)(i); \
U8_SET_CP_START_UNSAFE(s, _u8_get_unsafe_index); \
U8_NEXT_UNSAFE(s, _u8_get_unsafe_index, c); \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Get a code point from a string at a random-access offset,
@@ -256,11 +256,11 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_GET_UNSAFE
* @stable ICU 2.4
*/
-#define U8_GET(s, start, i, length, c) { \
+#define U8_GET(s, start, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
int32_t _u8_get_index=(i); \
U8_SET_CP_START(s, start, _u8_get_index); \
U8_NEXT(s, _u8_get_index, length, c); \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Get a code point from a string at a random-access offset,
@@ -287,11 +287,11 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_GET
* @stable ICU 51
*/
-#define U8_GET_OR_FFFD(s, start, i, length, c) { \
+#define U8_GET_OR_FFFD(s, start, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
int32_t _u8_get_index=(i); \
U8_SET_CP_START(s, start, _u8_get_index); \
U8_NEXT_OR_FFFD(s, _u8_get_index, length, c); \
-}
+} UPRV_BLOCK_MACRO_END
/* definitions with forward iteration --------------------------------------- */
@@ -312,7 +312,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_NEXT
* @stable ICU 2.4
*/
-#define U8_NEXT_UNSAFE(s, i, c) { \
+#define U8_NEXT_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(uint8_t)(s)[(i)++]; \
if(!U8_IS_SINGLE(c)) { \
if((c)<0xe0) { \
@@ -326,7 +326,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
(i)+=3; \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Get a code point from a string at a code point boundary offset,
@@ -377,7 +377,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
#define U8_NEXT_OR_FFFD(s, i, length, c) U8_INTERNAL_NEXT_OR_SUB(s, i, length, c, 0xfffd)
/** @internal */
-#define U8_INTERNAL_NEXT_OR_SUB(s, i, length, c, sub) { \
+#define U8_INTERNAL_NEXT_OR_SUB(s, i, length, c, sub) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(uint8_t)(s)[(i)++]; \
if(!U8_IS_SINGLE(c)) { \
uint8_t __t = 0; \
@@ -403,7 +403,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
(c)=(sub); /* ill-formed*/ \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Append a code point to a string, overwriting 1 to 4 bytes.
@@ -418,7 +418,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_APPEND
* @stable ICU 2.4
*/
-#define U8_APPEND_UNSAFE(s, i, c) { \
+#define U8_APPEND_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
uint32_t __uc=(c); \
if(__uc<=0x7f) { \
(s)[(i)++]=(uint8_t)__uc; \
@@ -436,7 +436,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
} \
(s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Append a code point to a string, overwriting 1 to 4 bytes.
@@ -455,7 +455,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_APPEND_UNSAFE
* @stable ICU 2.4
*/
-#define U8_APPEND(s, i, capacity, c, isError) { \
+#define U8_APPEND(s, i, capacity, c, isError) UPRV_BLOCK_MACRO_BEGIN { \
uint32_t __uc=(c); \
if(__uc<=0x7f) { \
(s)[(i)++]=(uint8_t)__uc; \
@@ -474,7 +474,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
} else { \
(isError)=TRUE; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Advance the string offset from one code point boundary to the next.
@@ -486,9 +486,9 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_FWD_1
* @stable ICU 2.4
*/
-#define U8_FWD_1_UNSAFE(s, i) { \
+#define U8_FWD_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
(i)+=1+U8_COUNT_TRAIL_BYTES_UNSAFE((s)[i]); \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Advance the string offset from one code point boundary to the next.
@@ -503,7 +503,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_FWD_1_UNSAFE
* @stable ICU 2.4
*/
-#define U8_FWD_1(s, i, length) { \
+#define U8_FWD_1(s, i, length) UPRV_BLOCK_MACRO_BEGIN { \
uint8_t __b=(s)[(i)++]; \
if(U8_IS_LEAD(__b) && (i)!=(length)) { \
uint8_t __t1=(s)[i]; \
@@ -524,7 +524,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
} \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Advance the string offset from one code point boundary to the n-th next one,
@@ -538,13 +538,13 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_FWD_N
* @stable ICU 2.4
*/
-#define U8_FWD_N_UNSAFE(s, i, n) { \
+#define U8_FWD_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
int32_t __N=(n); \
while(__N>0) { \
U8_FWD_1_UNSAFE(s, i); \
--__N; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Advance the string offset from one code point boundary to the n-th next one,
@@ -561,13 +561,13 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_FWD_N_UNSAFE
* @stable ICU 2.4
*/
-#define U8_FWD_N(s, i, length, n) { \
+#define U8_FWD_N(s, i, length, n) UPRV_BLOCK_MACRO_BEGIN { \
int32_t __N=(n); \
while(__N>0 && ((i)<(length) || ((length)<0 && (s)[i]!=0))) { \
U8_FWD_1(s, i, length); \
--__N; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Adjust a random-access offset to a code point boundary
@@ -582,9 +582,9 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_SET_CP_START
* @stable ICU 2.4
*/
-#define U8_SET_CP_START_UNSAFE(s, i) { \
+#define U8_SET_CP_START_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
while(U8_IS_TRAIL((s)[i])) { --(i); } \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Adjust a random-access offset to a code point boundary
@@ -603,11 +603,11 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_TRUNCATE_IF_INCOMPLETE
* @stable ICU 2.4
*/
-#define U8_SET_CP_START(s, start, i) { \
+#define U8_SET_CP_START(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \
if(U8_IS_TRAIL((s)[(i)])) { \
(i)=utf8_back1SafeBody(s, start, (i)); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* If the string ends with a UTF-8 byte sequence that is valid so far
@@ -635,7 +635,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_SET_CP_START
* @stable ICU 61
*/
-#define U8_TRUNCATE_IF_INCOMPLETE(s, start, length) \
+#define U8_TRUNCATE_IF_INCOMPLETE(s, start, length) UPRV_BLOCK_MACRO_BEGIN { \
if((length)>(start)) { \
uint8_t __b1=s[(length)-1]; \
if(U8_IS_SINGLE(__b1)) { \
@@ -656,7 +656,8 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
} \
} \
} \
- }
+ } \
+} UPRV_BLOCK_MACRO_END
/* definitions with backward iteration -------------------------------------- */
@@ -679,7 +680,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_PREV
* @stable ICU 2.4
*/
-#define U8_PREV_UNSAFE(s, i, c) { \
+#define U8_PREV_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(uint8_t)(s)[--(i)]; \
if(U8_IS_TRAIL(c)) { \
uint8_t __b, __count=1, __shift=6; \
@@ -699,7 +700,7 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
} \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Move the string offset from one code point boundary to the previous one
@@ -721,12 +722,12 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_PREV_UNSAFE
* @stable ICU 2.4
*/
-#define U8_PREV(s, start, i, c) { \
+#define U8_PREV(s, start, i, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(uint8_t)(s)[--(i)]; \
if(!U8_IS_SINGLE(c)) { \
(c)=utf8_prevCharSafeBody((const uint8_t *)s, start, &(i), c, -1); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Move the string offset from one code point boundary to the previous one
@@ -752,12 +753,12 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_PREV
* @stable ICU 51
*/
-#define U8_PREV_OR_FFFD(s, start, i, c) { \
+#define U8_PREV_OR_FFFD(s, start, i, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(uint8_t)(s)[--(i)]; \
if(!U8_IS_SINGLE(c)) { \
(c)=utf8_prevCharSafeBody((const uint8_t *)s, start, &(i), c, -3); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Move the string offset from one code point boundary to the previous one.
@@ -770,9 +771,9 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_BACK_1
* @stable ICU 2.4
*/
-#define U8_BACK_1_UNSAFE(s, i) { \
+#define U8_BACK_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
while(U8_IS_TRAIL((s)[--(i)])) {} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Move the string offset from one code point boundary to the previous one.
@@ -786,11 +787,11 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_BACK_1_UNSAFE
* @stable ICU 2.4
*/
-#define U8_BACK_1(s, start, i) { \
+#define U8_BACK_1(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \
if(U8_IS_TRAIL((s)[--(i)])) { \
(i)=utf8_back1SafeBody(s, start, (i)); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Move the string offset from one code point boundary to the n-th one before it,
@@ -805,13 +806,13 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_BACK_N
* @stable ICU 2.4
*/
-#define U8_BACK_N_UNSAFE(s, i, n) { \
+#define U8_BACK_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
int32_t __N=(n); \
while(__N>0) { \
U8_BACK_1_UNSAFE(s, i); \
--__N; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Move the string offset from one code point boundary to the n-th one before it,
@@ -827,13 +828,13 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_BACK_N_UNSAFE
* @stable ICU 2.4
*/
-#define U8_BACK_N(s, start, i, n) { \
+#define U8_BACK_N(s, start, i, n) UPRV_BLOCK_MACRO_BEGIN { \
int32_t __N=(n); \
while(__N>0 && (i)>(start)) { \
U8_BACK_1(s, start, i); \
--__N; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Adjust a random-access offset to a code point boundary after a code point.
@@ -848,10 +849,10 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_SET_CP_LIMIT
* @stable ICU 2.4
*/
-#define U8_SET_CP_LIMIT_UNSAFE(s, i) { \
+#define U8_SET_CP_LIMIT_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
U8_BACK_1_UNSAFE(s, i); \
U8_FWD_1_UNSAFE(s, i); \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Adjust a random-access offset to a code point boundary after a code point.
@@ -870,11 +871,11 @@ utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);
* @see U8_SET_CP_LIMIT_UNSAFE
* @stable ICU 2.4
*/
-#define U8_SET_CP_LIMIT(s, start, i, length) { \
+#define U8_SET_CP_LIMIT(s, start, i, length) UPRV_BLOCK_MACRO_BEGIN { \
if((start)<(i) && ((i)<(length) || (length)<0)) { \
U8_BACK_1(s, start, i); \
U8_FWD_1(s, i, length); \
} \
-}
+} UPRV_BLOCK_MACRO_END
#endif
diff --git a/deps/icu-small/source/common/unicode/utf_old.h b/deps/icu-small/source/common/unicode/utf_old.h
index 55c17c01df..b2428e6b31 100644
--- a/deps/icu-small/source/common/unicode/utf_old.h
+++ b/deps/icu-small/source/common/unicode/utf_old.h
@@ -19,9 +19,6 @@
/**
* \file
* \brief C API: Deprecated macros for Unicode string handling
- */
-
-/**
*
* The macros in utf_old.h are all deprecated and their use discouraged.
* Some of the design principles behind the set of UTF macros
@@ -139,12 +136,16 @@
*
* <hr>
*
- * @deprecated ICU 2.4. Use the macros in utf.h, utf16.h, utf8.h instead.
+ * Deprecated ICU 2.4. Use the macros in utf.h, utf16.h, utf8.h instead.
*/
#ifndef __UTF_OLD_H__
#define __UTF_OLD_H__
+#include "unicode/utf.h"
+#include "unicode/utf8.h"
+#include "unicode/utf16.h"
+
/**
* \def U_HIDE_OBSOLETE_UTF_OLD_H
*
@@ -162,10 +163,6 @@
#if !defined(U_HIDE_DEPRECATED_API) && !U_HIDE_OBSOLETE_UTF_OLD_H
-#include "unicode/utf.h"
-#include "unicode/utf8.h"
-#include "unicode/utf16.h"
-
/* Formerly utf.h, part 1 --------------------------------------------------- */
#ifdef U_USE_UTF_DEPRECATES
@@ -365,21 +362,21 @@ U_CFUNC U_IMPORT const uint8_t utf8_countTrailBytes[]; /* U_IMPORT2? */ /*U_I
#define UTF8_ARRAY_SIZE(size) ((5*(size))/2)
/** @deprecated ICU 2.4. Renamed to U8_GET_UNSAFE, see utf_old.h. */
-#define UTF8_GET_CHAR_UNSAFE(s, i, c) { \
+#define UTF8_GET_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
int32_t _utf8_get_char_unsafe_index=(int32_t)(i); \
UTF8_SET_CHAR_START_UNSAFE(s, _utf8_get_char_unsafe_index); \
UTF8_NEXT_CHAR_UNSAFE(s, _utf8_get_char_unsafe_index, c); \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Use U8_GET instead, see utf_old.h. */
-#define UTF8_GET_CHAR_SAFE(s, start, i, length, c, strict) { \
+#define UTF8_GET_CHAR_SAFE(s, start, i, length, c, strict) UPRV_BLOCK_MACRO_BEGIN { \
int32_t _utf8_get_char_safe_index=(int32_t)(i); \
UTF8_SET_CHAR_START_SAFE(s, start, _utf8_get_char_safe_index); \
UTF8_NEXT_CHAR_SAFE(s, _utf8_get_char_safe_index, length, c, strict); \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U8_NEXT_UNSAFE, see utf_old.h. */
-#define UTF8_NEXT_CHAR_UNSAFE(s, i, c) { \
+#define UTF8_NEXT_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[(i)++]; \
if((uint8_t)((c)-0xc0)<0x35) { \
uint8_t __count=UTF8_COUNT_TRAIL_BYTES(c); \
@@ -396,10 +393,10 @@ U_CFUNC U_IMPORT const uint8_t utf8_countTrailBytes[]; /* U_IMPORT2? */ /*U_I
break; \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U8_APPEND_UNSAFE, see utf_old.h. */
-#define UTF8_APPEND_CHAR_UNSAFE(s, i, c) { \
+#define UTF8_APPEND_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
if((uint32_t)(c)<=0x7f) { \
(s)[(i)++]=(uint8_t)(c); \
} else { \
@@ -416,29 +413,29 @@ U_CFUNC U_IMPORT const uint8_t utf8_countTrailBytes[]; /* U_IMPORT2? */ /*U_I
} \
(s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U8_FWD_1_UNSAFE, see utf_old.h. */
-#define UTF8_FWD_1_UNSAFE(s, i) { \
+#define UTF8_FWD_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
(i)+=1+UTF8_COUNT_TRAIL_BYTES((s)[i]); \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U8_FWD_N_UNSAFE, see utf_old.h. */
-#define UTF8_FWD_N_UNSAFE(s, i, n) { \
+#define UTF8_FWD_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
int32_t __N=(n); \
while(__N>0) { \
UTF8_FWD_1_UNSAFE(s, i); \
--__N; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U8_SET_CP_START_UNSAFE, see utf_old.h. */
-#define UTF8_SET_CHAR_START_UNSAFE(s, i) { \
+#define UTF8_SET_CHAR_START_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
while(UTF8_IS_TRAIL((s)[i])) { --(i); } \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Use U8_NEXT instead, see utf_old.h. */
-#define UTF8_NEXT_CHAR_SAFE(s, i, length, c, strict) { \
+#define UTF8_NEXT_CHAR_SAFE(s, i, length, c, strict) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[(i)++]; \
if((c)>=0x80) { \
if(UTF8_IS_LEAD(c)) { \
@@ -447,16 +444,16 @@ U_CFUNC U_IMPORT const uint8_t utf8_countTrailBytes[]; /* U_IMPORT2? */ /*U_I
(c)=UTF8_ERROR_VALUE_1; \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Use U8_APPEND instead, see utf_old.h. */
-#define UTF8_APPEND_CHAR_SAFE(s, i, length, c) { \
+#define UTF8_APPEND_CHAR_SAFE(s, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
if((uint32_t)(c)<=0x7f) { \
(s)[(i)++]=(uint8_t)(c); \
} else { \
(i)=utf8_appendCharSafeBody(s, (int32_t)(i), (int32_t)(length), c, NULL); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U8_FWD_1, see utf_old.h. */
#define UTF8_FWD_1_SAFE(s, i, length) U8_FWD_1(s, i, length)
@@ -468,7 +465,7 @@ U_CFUNC U_IMPORT const uint8_t utf8_countTrailBytes[]; /* U_IMPORT2? */ /*U_I
#define UTF8_SET_CHAR_START_SAFE(s, start, i) U8_SET_CP_START(s, start, i)
/** @deprecated ICU 2.4. Renamed to U8_PREV_UNSAFE, see utf_old.h. */
-#define UTF8_PREV_CHAR_UNSAFE(s, i, c) { \
+#define UTF8_PREV_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[--(i)]; \
if(UTF8_IS_TRAIL(c)) { \
uint8_t __b, __count=1, __shift=6; \
@@ -488,30 +485,30 @@ U_CFUNC U_IMPORT const uint8_t utf8_countTrailBytes[]; /* U_IMPORT2? */ /*U_I
} \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U8_BACK_1_UNSAFE, see utf_old.h. */
-#define UTF8_BACK_1_UNSAFE(s, i) { \
+#define UTF8_BACK_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
while(UTF8_IS_TRAIL((s)[--(i)])) {} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U8_BACK_N_UNSAFE, see utf_old.h. */
-#define UTF8_BACK_N_UNSAFE(s, i, n) { \
+#define UTF8_BACK_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
int32_t __N=(n); \
while(__N>0) { \
UTF8_BACK_1_UNSAFE(s, i); \
--__N; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U8_SET_CP_LIMIT_UNSAFE, see utf_old.h. */
-#define UTF8_SET_CHAR_LIMIT_UNSAFE(s, i) { \
+#define UTF8_SET_CHAR_LIMIT_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
UTF8_BACK_1_UNSAFE(s, i); \
UTF8_FWD_1_UNSAFE(s, i); \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Use U8_PREV instead, see utf_old.h. */
-#define UTF8_PREV_CHAR_SAFE(s, start, i, c, strict) { \
+#define UTF8_PREV_CHAR_SAFE(s, start, i, c, strict) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[--(i)]; \
if((c)>=0x80) { \
if((c)<=0xbf) { \
@@ -520,7 +517,7 @@ U_CFUNC U_IMPORT const uint8_t utf8_countTrailBytes[]; /* U_IMPORT2? */ /*U_I
(c)=UTF8_ERROR_VALUE_1; \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U8_BACK_1, see utf_old.h. */
#define UTF8_BACK_1_SAFE(s, start, i) U8_BACK_1(s, start, i)
@@ -593,7 +590,7 @@ U_CFUNC U_IMPORT const uint8_t utf8_countTrailBytes[]; /* U_IMPORT2? */ /*U_I
* UTF16_PREV_CHAR[_UNSAFE]() is more efficient for that.
* @deprecated ICU 2.4. Renamed to U16_GET_UNSAFE, see utf_old.h.
*/
-#define UTF16_GET_CHAR_UNSAFE(s, i, c) { \
+#define UTF16_GET_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[i]; \
if(UTF_IS_SURROGATE(c)) { \
if(UTF_IS_SURROGATE_FIRST(c)) { \
@@ -602,10 +599,10 @@ U_CFUNC U_IMPORT const uint8_t utf8_countTrailBytes[]; /* U_IMPORT2? */ /*U_I
(c)=UTF16_GET_PAIR_VALUE((s)[(i)-1], (c)); \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Use U16_GET instead, see utf_old.h. */
-#define UTF16_GET_CHAR_SAFE(s, start, i, length, c, strict) { \
+#define UTF16_GET_CHAR_SAFE(s, start, i, length, c, strict) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[i]; \
if(UTF_IS_SURROGATE(c)) { \
uint16_t __c2; \
@@ -629,51 +626,51 @@ U_CFUNC U_IMPORT const uint8_t utf8_countTrailBytes[]; /* U_IMPORT2? */ /*U_I
} else if((strict) && !UTF_IS_UNICODE_CHAR(c)) { \
(c)=UTF_ERROR_VALUE; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U16_NEXT_UNSAFE, see utf_old.h. */
-#define UTF16_NEXT_CHAR_UNSAFE(s, i, c) { \
+#define UTF16_NEXT_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[(i)++]; \
if(UTF_IS_FIRST_SURROGATE(c)) { \
(c)=UTF16_GET_PAIR_VALUE((c), (s)[(i)++]); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U16_APPEND_UNSAFE, see utf_old.h. */
-#define UTF16_APPEND_CHAR_UNSAFE(s, i, c) { \
+#define UTF16_APPEND_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
if((uint32_t)(c)<=0xffff) { \
(s)[(i)++]=(uint16_t)(c); \
} else { \
(s)[(i)++]=(uint16_t)(((c)>>10)+0xd7c0); \
(s)[(i)++]=(uint16_t)(((c)&0x3ff)|0xdc00); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U16_FWD_1_UNSAFE, see utf_old.h. */
-#define UTF16_FWD_1_UNSAFE(s, i) { \
+#define UTF16_FWD_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
if(UTF_IS_FIRST_SURROGATE((s)[(i)++])) { \
++(i); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U16_FWD_N_UNSAFE, see utf_old.h. */
-#define UTF16_FWD_N_UNSAFE(s, i, n) { \
+#define UTF16_FWD_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
int32_t __N=(n); \
while(__N>0) { \
UTF16_FWD_1_UNSAFE(s, i); \
--__N; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U16_SET_CP_START_UNSAFE, see utf_old.h. */
-#define UTF16_SET_CHAR_START_UNSAFE(s, i) { \
+#define UTF16_SET_CHAR_START_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
if(UTF_IS_SECOND_SURROGATE((s)[i])) { \
--(i); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Use U16_NEXT instead, see utf_old.h. */
-#define UTF16_NEXT_CHAR_SAFE(s, i, length, c, strict) { \
+#define UTF16_NEXT_CHAR_SAFE(s, i, length, c, strict) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[(i)++]; \
if(UTF_IS_FIRST_SURROGATE(c)) { \
uint16_t __c2; \
@@ -689,10 +686,10 @@ U_CFUNC U_IMPORT const uint8_t utf8_countTrailBytes[]; /* U_IMPORT2? */ /*U_I
/* unmatched second surrogate or other non-character */ \
(c)=UTF_ERROR_VALUE; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Use U16_APPEND instead, see utf_old.h. */
-#define UTF16_APPEND_CHAR_SAFE(s, i, length, c) { \
+#define UTF16_APPEND_CHAR_SAFE(s, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
if((uint32_t)(c)<=0xffff) { \
(s)[(i)++]=(uint16_t)(c); \
} else if((uint32_t)(c)<=0x10ffff) { \
@@ -705,7 +702,7 @@ U_CFUNC U_IMPORT const uint8_t utf8_countTrailBytes[]; /* U_IMPORT2? */ /*U_I
} else /* c>0x10ffff, write error value */ { \
(s)[(i)++]=UTF_ERROR_VALUE; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U16_FWD_1, see utf_old.h. */
#define UTF16_FWD_1_SAFE(s, i, length) U16_FWD_1(s, i, length)
@@ -717,38 +714,38 @@ U_CFUNC U_IMPORT const uint8_t utf8_countTrailBytes[]; /* U_IMPORT2? */ /*U_I
#define UTF16_SET_CHAR_START_SAFE(s, start, i) U16_SET_CP_START(s, start, i)
/** @deprecated ICU 2.4. Renamed to U16_PREV_UNSAFE, see utf_old.h. */
-#define UTF16_PREV_CHAR_UNSAFE(s, i, c) { \
+#define UTF16_PREV_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[--(i)]; \
if(UTF_IS_SECOND_SURROGATE(c)) { \
(c)=UTF16_GET_PAIR_VALUE((s)[--(i)], (c)); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U16_BACK_1_UNSAFE, see utf_old.h. */
-#define UTF16_BACK_1_UNSAFE(s, i) { \
+#define UTF16_BACK_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
if(UTF_IS_SECOND_SURROGATE((s)[--(i)])) { \
--(i); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U16_BACK_N_UNSAFE, see utf_old.h. */
-#define UTF16_BACK_N_UNSAFE(s, i, n) { \
+#define UTF16_BACK_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
int32_t __N=(n); \
while(__N>0) { \
UTF16_BACK_1_UNSAFE(s, i); \
--__N; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U16_SET_CP_LIMIT_UNSAFE, see utf_old.h. */
-#define UTF16_SET_CHAR_LIMIT_UNSAFE(s, i) { \
+#define UTF16_SET_CHAR_LIMIT_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
if(UTF_IS_FIRST_SURROGATE((s)[(i)-1])) { \
++(i); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Use U16_PREV instead, see utf_old.h. */
-#define UTF16_PREV_CHAR_SAFE(s, start, i, c, strict) { \
+#define UTF16_PREV_CHAR_SAFE(s, start, i, c, strict) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[--(i)]; \
if(UTF_IS_SECOND_SURROGATE(c)) { \
uint16_t __c2; \
@@ -764,7 +761,7 @@ U_CFUNC U_IMPORT const uint8_t utf8_countTrailBytes[]; /* U_IMPORT2? */ /*U_I
/* unmatched first surrogate or other non-character */ \
(c)=UTF_ERROR_VALUE; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Renamed to U16_BACK_1, see utf_old.h. */
#define UTF16_BACK_1_SAFE(s, start, i) U16_BACK_1(s, start, i)
@@ -830,122 +827,122 @@ U_CFUNC U_IMPORT const uint8_t utf8_countTrailBytes[]; /* U_IMPORT2? */ /*U_I
#define UTF32_ARRAY_SIZE(size) (size)
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_GET_CHAR_UNSAFE(s, i, c) { \
+#define UTF32_GET_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[i]; \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_GET_CHAR_SAFE(s, start, i, length, c, strict) { \
+#define UTF32_GET_CHAR_SAFE(s, start, i, length, c, strict) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[i]; \
if(!UTF32_IS_SAFE(c, strict)) { \
(c)=UTF_ERROR_VALUE; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/* definitions with forward iteration --------------------------------------- */
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_NEXT_CHAR_UNSAFE(s, i, c) { \
+#define UTF32_NEXT_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[(i)++]; \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_APPEND_CHAR_UNSAFE(s, i, c) { \
+#define UTF32_APPEND_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
(s)[(i)++]=(c); \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_FWD_1_UNSAFE(s, i) { \
+#define UTF32_FWD_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
++(i); \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_FWD_N_UNSAFE(s, i, n) { \
+#define UTF32_FWD_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
(i)+=(n); \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_SET_CHAR_START_UNSAFE(s, i) { \
-}
+#define UTF32_SET_CHAR_START_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_NEXT_CHAR_SAFE(s, i, length, c, strict) { \
+#define UTF32_NEXT_CHAR_SAFE(s, i, length, c, strict) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[(i)++]; \
if(!UTF32_IS_SAFE(c, strict)) { \
(c)=UTF_ERROR_VALUE; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_APPEND_CHAR_SAFE(s, i, length, c) { \
+#define UTF32_APPEND_CHAR_SAFE(s, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \
if((uint32_t)(c)<=0x10ffff) { \
(s)[(i)++]=(c); \
} else /* c>0x10ffff, write 0xfffd */ { \
(s)[(i)++]=0xfffd; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_FWD_1_SAFE(s, i, length) { \
+#define UTF32_FWD_1_SAFE(s, i, length) UPRV_BLOCK_MACRO_BEGIN { \
++(i); \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_FWD_N_SAFE(s, i, length, n) { \
+#define UTF32_FWD_N_SAFE(s, i, length, n) UPRV_BLOCK_MACRO_BEGIN { \
if(((i)+=(n))>(length)) { \
(i)=(length); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_SET_CHAR_START_SAFE(s, start, i) { \
-}
+#define UTF32_SET_CHAR_START_SAFE(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \
+} UPRV_BLOCK_MACRO_END
/* definitions with backward iteration -------------------------------------- */
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_PREV_CHAR_UNSAFE(s, i, c) { \
+#define UTF32_PREV_CHAR_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[--(i)]; \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_BACK_1_UNSAFE(s, i) { \
+#define UTF32_BACK_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
--(i); \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_BACK_N_UNSAFE(s, i, n) { \
+#define UTF32_BACK_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \
(i)-=(n); \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_SET_CHAR_LIMIT_UNSAFE(s, i) { \
-}
+#define UTF32_SET_CHAR_LIMIT_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_PREV_CHAR_SAFE(s, start, i, c, strict) { \
+#define UTF32_PREV_CHAR_SAFE(s, start, i, c, strict) UPRV_BLOCK_MACRO_BEGIN { \
(c)=(s)[--(i)]; \
if(!UTF32_IS_SAFE(c, strict)) { \
(c)=UTF_ERROR_VALUE; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_BACK_1_SAFE(s, start, i) { \
+#define UTF32_BACK_1_SAFE(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \
--(i); \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_BACK_N_SAFE(s, start, i, n) { \
+#define UTF32_BACK_N_SAFE(s, start, i, n) UPRV_BLOCK_MACRO_BEGIN { \
(i)-=(n); \
if((i)<(start)) { \
(i)=(start); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */
-#define UTF32_SET_CHAR_LIMIT_SAFE(s, i, length) { \
-}
+#define UTF32_SET_CHAR_LIMIT_SAFE(s, i, length) UPRV_BLOCK_MACRO_BEGIN { \
+} UPRV_BLOCK_MACRO_END
/* Formerly utf.h, part 2 --------------------------------------------------- */
diff --git a/deps/icu-small/source/common/unicode/utrace.h b/deps/icu-small/source/common/unicode/utrace.h
index bf6fd036f0..0af050756f 100644
--- a/deps/icu-small/source/common/unicode/utrace.h
+++ b/deps/icu-small/source/common/unicode/utrace.h
@@ -66,6 +66,7 @@ typedef enum UTraceFunctionNumber {
UTRACE_FUNCTION_START=0,
UTRACE_U_INIT=UTRACE_FUNCTION_START,
UTRACE_U_CLEANUP,
+
#ifndef U_HIDE_DEPRECATED_API
/**
* One more than the highest normal collation trace location.
@@ -83,6 +84,7 @@ typedef enum UTraceFunctionNumber {
UTRACE_UCNV_FLUSH_CACHE,
UTRACE_UCNV_LOAD,
UTRACE_UCNV_UNLOAD,
+
#ifndef U_HIDE_DEPRECATED_API
/**
* One more than the highest normal collation trace location.
@@ -101,13 +103,80 @@ typedef enum UTraceFunctionNumber {
UTRACE_UCOL_STRCOLLITER,
UTRACE_UCOL_OPEN_FROM_SHORT_STRING,
UTRACE_UCOL_STRCOLLUTF8, /**< @stable ICU 50 */
+
#ifndef U_HIDE_DEPRECATED_API
/**
* One more than the highest normal collation trace location.
* @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
*/
- UTRACE_COLLATION_LIMIT
+ UTRACE_COLLATION_LIMIT,
#endif // U_HIDE_DEPRECATED_API
+
+#ifndef U_HIDE_DRAFT_API
+
+ /**
+ * The lowest resource/data location.
+ * @draft ICU 65
+ */
+ UTRACE_UDATA_START=0x3000,
+
+ /**
+ * Indicates that a value was read from a resource bundle. Provides three
+ * C-style strings to UTraceData: type, file name, and resource path. The
+ * possible types are:
+ *
+ * - "string" (a string value was accessed)
+ * - "binary" (a binary value was accessed)
+ * - "intvector" (a integer vector value was accessed)
+ * - "int" (a signed integer value was accessed)
+ * - "uint" (a unsigned integer value was accessed)
+ * - "get" (a path was loaded, but the value was not accessed)
+ * - "getalias" (a path was loaded, and an alias was resolved)
+ *
+ * @draft ICU 65
+ */
+ UTRACE_UDATA_RESOURCE=UTRACE_UDATA_START,
+
+ /**
+ * Indicates that a resource bundle was opened.
+ *
+ * Provides one C-style string to UTraceData: file name.
+ * @draft ICU 65
+ */
+ UTRACE_UDATA_BUNDLE,
+
+ /**
+ * Indicates that a data file was opened, but not *.res files.
+ *
+ * Provides one C-style string to UTraceData: file name.
+ *
+ * @draft ICU 65
+ */
+ UTRACE_UDATA_DATA_FILE,
+
+ /**
+ * Indicates that a *.res file was opened.
+ *
+ * This differs from UTRACE_UDATA_BUNDLE because a res file is typically
+ * opened only once per application runtime, but the bundle corresponding
+ * to that res file may be opened many times.
+ *
+ * Provides one C-style string to UTraceData: file name.
+ *
+ * @draft ICU 65
+ */
+ UTRACE_UDATA_RES_FILE,
+
+#endif // U_HIDE_DRAFT_API
+
+#ifndef U_HIDE_INTERNAL_API
+ /**
+ * One more than the highest normal resource/data trace location.
+ * @internal The numeric value may change over time, see ICU ticket #12420.
+ */
+ UTRACE_RES_DATA_LIMIT,
+#endif // U_HIDE_INTERNAL_API
+
} UTraceFunctionNumber;
/**
diff --git a/deps/icu-small/source/common/unicode/utypes.h b/deps/icu-small/source/common/unicode/utypes.h
index 49eb12cd40..c98de9e6fc 100644
--- a/deps/icu-small/source/common/unicode/utypes.h
+++ b/deps/icu-small/source/common/unicode/utypes.h
@@ -385,17 +385,31 @@ typedef double UDate;
/*===========================================================================*/
/**
- * Error code to replace exception handling, so that the code is compatible with all C++ compilers,
- * and to use the same mechanism for C and C++.
+ * Standard ICU4C error code type, a substitute for exceptions.
+ *
+ * Initialize the UErrorCode with U_ZERO_ERROR, and check for success or
+ * failure using U_SUCCESS() or U_FAILURE():
+ *
+ * UErrorCode errorCode = U_ZERO_ERROR;
+ * // call ICU API that needs an error code parameter.
+ * if (U_FAILURE(errorCode)) {
+ * // An error occurred. Handle it here.
+ * }
+ *
+ * C++ code should use icu::ErrorCode, available in unicode/errorcode.h, or a
+ * suitable subclass.
+ *
+ * For more information, see:
+ * http://icu-project.org/userguide/conventions
+ *
+ * Note: By convention, ICU functions that take a reference (C++) or a pointer
+ * (C) to a UErrorCode first test:
+ *
+ * if (U_FAILURE(errorCode)) { return immediately; }
*
- * \par
- * ICU functions that take a reference (C++) or a pointer (C) to a UErrorCode
- * first test if(U_FAILURE(errorCode)) { return immediately; }
* so that in a chain of such functions the first one that sets an error code
* causes the following ones to not perform any operations.
*
- * \par
- * Error codes should be tested using U_FAILURE() and U_SUCCESS().
* @stable ICU 2.0
*/
typedef enum UErrorCode {
diff --git a/deps/icu-small/source/common/unicode/uvernum.h b/deps/icu-small/source/common/unicode/uvernum.h
index 7c114be2cc..0923c1d918 100644
--- a/deps/icu-small/source/common/unicode/uvernum.h
+++ b/deps/icu-small/source/common/unicode/uvernum.h
@@ -60,13 +60,13 @@
* This value will change in the subsequent releases of ICU
* @stable ICU 2.4
*/
-#define U_ICU_VERSION_MAJOR_NUM 64
+#define U_ICU_VERSION_MAJOR_NUM 65
/** The current ICU minor version as an integer.
* This value will change in the subsequent releases of ICU
* @stable ICU 2.6
*/
-#define U_ICU_VERSION_MINOR_NUM 2
+#define U_ICU_VERSION_MINOR_NUM 1
/** The current ICU patchlevel 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 _64
+#define U_ICU_VERSION_SUFFIX _65
/**
* \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 "64.2"
+#define U_ICU_VERSION "65.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 "64"
+#define U_ICU_VERSION_SHORT "65"
#ifndef U_HIDE_INTERNAL_API
/** Data version in ICU4C.
* @internal ICU 4.4 Internal Use Only
**/
-#define U_ICU_DATA_VERSION "64.2"
+#define U_ICU_DATA_VERSION "65.1"
#endif /* U_HIDE_INTERNAL_API */
/*===========================================================================
diff --git a/deps/icu-small/source/common/unicode/uversion.h b/deps/icu-small/source/common/unicode/uversion.h
index 3f0251d399..c8c7a374c8 100644
--- a/deps/icu-small/source/common/unicode/uversion.h
+++ b/deps/icu-small/source/common/unicode/uversion.h
@@ -62,26 +62,22 @@ typedef uint8_t UVersionInfo[U_MAX_VERSION_LENGTH];
/* C++ namespace if supported. Versioned unless versioning is disabled. */
/*===========================================================================*/
+/* Define C++ namespace symbols. */
+#ifdef __cplusplus
+
/**
* \def U_NAMESPACE_BEGIN
- * This is used to begin a declaration of a public ICU C++ API.
- * When not compiling for C++, it does nothing.
- * When compiling for C++, it begins an extern "C++" linkage block (to protect
- * against cases in which an external client includes ICU header files inside
- * an extern "C" linkage block).
+ * This is used to begin a declaration of a public ICU C++ API within
+ * versioned-ICU-namespace block.
*
- * It also begins a versioned-ICU-namespace block.
* @stable ICU 2.4
*/
/**
* \def U_NAMESPACE_END
* This is used to end a declaration of a public ICU C++ API.
- * When not compiling for C++, it does nothing.
- * When compiling for C++, it ends the extern "C++" block begun by
- * U_NAMESPACE_BEGIN.
+ * It ends the versioned-ICU-namespace block begun by U_NAMESPACE_BEGIN.
*
- * It also ends the versioned-ICU-namespace block begun by U_NAMESPACE_BEGIN.
* @stable ICU 2.4
*/
@@ -89,9 +85,6 @@ typedef uint8_t UVersionInfo[U_MAX_VERSION_LENGTH];
* \def U_NAMESPACE_USE
* This is used to specify that the rest of the code uses the
* public ICU C++ API namespace.
- * This is invoked by default; we recommend that you turn it off:
- * See the "Recommended Build Options" section of the ICU4C readme
- * (http://source.icu-project.org/repos/icu/icu/trunk/readme.html#RecBuild)
* @stable ICU 2.4
*/
@@ -105,8 +98,6 @@ typedef uint8_t UVersionInfo[U_MAX_VERSION_LENGTH];
* @stable ICU 2.4
*/
-/* Define C++ namespace symbols. */
-#ifdef __cplusplus
# if U_DISABLE_RENAMING
# define U_ICU_NAMESPACE icu
namespace U_ICU_NAMESPACE { }
@@ -116,8 +107,8 @@ typedef uint8_t UVersionInfo[U_MAX_VERSION_LENGTH];
namespace icu = U_ICU_NAMESPACE;
# endif
-# define U_NAMESPACE_BEGIN extern "C++" { namespace U_ICU_NAMESPACE {
-# define U_NAMESPACE_END } }
+# define U_NAMESPACE_BEGIN namespace U_ICU_NAMESPACE {
+# define U_NAMESPACE_END }
# define U_NAMESPACE_USE using namespace U_ICU_NAMESPACE;
# define U_NAMESPACE_QUALIFIER U_ICU_NAMESPACE::
@@ -133,12 +124,7 @@ typedef uint8_t UVersionInfo[U_MAX_VERSION_LENGTH];
# if U_USING_ICU_NAMESPACE
U_NAMESPACE_USE
# endif
-#else
-# define U_NAMESPACE_BEGIN
-# define U_NAMESPACE_END
-# define U_NAMESPACE_USE
-# define U_NAMESPACE_QUALIFIER
-#endif
+#endif /* __cplusplus */
/*===========================================================================*/
/* General version helper functions. Definitions in putil.c */
diff --git a/deps/icu-small/source/common/unifiedcache.cpp b/deps/icu-small/source/common/unifiedcache.cpp
index 641f4ec659..f2dd916559 100644
--- a/deps/icu-small/source/common/unifiedcache.cpp
+++ b/deps/icu-small/source/common/unifiedcache.cpp
@@ -13,22 +13,15 @@
#include "unifiedcache.h"
#include <algorithm> // For std::max()
+#include <mutex>
-#include "mutex.h"
#include "uassert.h"
#include "uhash.h"
#include "ucln_cmn.h"
-#include "umutex.h"
static icu::UnifiedCache *gCache = NULL;
-static icu::UMutex *gCacheMutex() {
- static icu::UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
-static icu::UConditionVar *gInProgressValueAddedCond() {
- static icu::UConditionVar cv = U_CONDITION_INITIALIZER;
- return &cv;
-}
+static std::mutex *gCacheMutex = nullptr;
+static std::condition_variable *gInProgressValueAddedCond;
static icu::UInitOnce gCacheInitOnce = U_INITONCE_INITIALIZER;
static const int32_t MAX_EVICT_ITERATIONS = 10;
@@ -39,10 +32,12 @@ static const int32_t DEFAULT_PERCENTAGE_OF_IN_USE = 100;
U_CDECL_BEGIN
static UBool U_CALLCONV unifiedcache_cleanup() {
gCacheInitOnce.reset();
- if (gCache) {
- delete gCache;
- gCache = NULL;
- }
+ delete gCache;
+ gCache = nullptr;
+ gCacheMutex->~mutex();
+ gCacheMutex = nullptr;
+ gInProgressValueAddedCond->~condition_variable();
+ gInProgressValueAddedCond = nullptr;
return TRUE;
}
U_CDECL_END
@@ -77,6 +72,8 @@ static void U_CALLCONV cacheInit(UErrorCode &status) {
ucln_common_registerCleanup(
UCLN_COMMON_UNIFIED_CACHE, unifiedcache_cleanup);
+ gCacheMutex = STATIC_NEW(std::mutex);
+ gInProgressValueAddedCond = STATIC_NEW(std::condition_variable);
gCache = new UnifiedCache(status);
if (gCache == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
@@ -138,28 +135,28 @@ void UnifiedCache::setEvictionPolicy(
status = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
- Mutex lock(gCacheMutex());
+ std::lock_guard<std::mutex> lock(*gCacheMutex);
fMaxUnused = count;
fMaxPercentageOfInUse = percentageOfInUseItems;
}
int32_t UnifiedCache::unusedCount() const {
- Mutex lock(gCacheMutex());
+ std::lock_guard<std::mutex> lock(*gCacheMutex);
return uhash_count(fHashtable) - fNumValuesInUse;
}
int64_t UnifiedCache::autoEvictedCount() const {
- Mutex lock(gCacheMutex());
+ std::lock_guard<std::mutex> lock(*gCacheMutex);
return fAutoEvictedCount;
}
int32_t UnifiedCache::keyCount() const {
- Mutex lock(gCacheMutex());
+ std::lock_guard<std::mutex> lock(*gCacheMutex);
return uhash_count(fHashtable);
}
void UnifiedCache::flush() const {
- Mutex lock(gCacheMutex());
+ std::lock_guard<std::mutex> lock(*gCacheMutex);
// Use a loop in case cache items that are flushed held hard references to
// other cache items making those additional cache items eligible for
@@ -168,7 +165,7 @@ void UnifiedCache::flush() const {
}
void UnifiedCache::handleUnreferencedObject() const {
- Mutex lock(gCacheMutex());
+ std::lock_guard<std::mutex> lock(*gCacheMutex);
--fNumValuesInUse;
_runEvictionSlice();
}
@@ -187,7 +184,7 @@ void UnifiedCache::dump() {
}
void UnifiedCache::dumpContents() const {
- Mutex lock(gCacheMutex());
+ std::lock_guard<std::mutex> lock(*gCacheMutex);
_dumpContents();
}
@@ -227,7 +224,7 @@ UnifiedCache::~UnifiedCache() {
// Now all that should be left in the cache are entries that refer to
// each other and entries with hard references from outside the cache.
// Nothing we can do about these so proceed to wipe out the cache.
- Mutex lock(gCacheMutex());
+ std::lock_guard<std::mutex> lock(*gCacheMutex);
_flush(TRUE);
}
uhash_close(fHashtable);
@@ -328,7 +325,7 @@ void UnifiedCache::_putIfAbsentAndGet(
const CacheKeyBase &key,
const SharedObject *&value,
UErrorCode &status) const {
- Mutex lock(gCacheMutex());
+ std::lock_guard<std::mutex> lock(*gCacheMutex);
const UHashElement *element = uhash_find(fHashtable, &key);
if (element != NULL && !_inProgress(element)) {
_fetch(element, value, status);
@@ -353,15 +350,15 @@ UBool UnifiedCache::_poll(
UErrorCode &status) const {
U_ASSERT(value == NULL);
U_ASSERT(status == U_ZERO_ERROR);
- Mutex lock(gCacheMutex());
+ std::unique_lock<std::mutex> lock(*gCacheMutex);
const UHashElement *element = uhash_find(fHashtable, &key);
// If the hash table contains an inProgress placeholder entry for this key,
// this means that another thread is currently constructing the value object.
// Loop, waiting for that construction to complete.
while (element != NULL && _inProgress(element)) {
- umtx_condWait(gInProgressValueAddedCond(), gCacheMutex());
- element = uhash_find(fHashtable, &key);
+ gInProgressValueAddedCond->wait(lock);
+ element = uhash_find(fHashtable, &key);
}
// If the hash table contains an entry for the key,
@@ -433,7 +430,7 @@ void UnifiedCache::_put(
// Tell waiting threads that we replace in-progress status with
// an error.
- umtx_condBroadcast(gInProgressValueAddedCond());
+ gInProgressValueAddedCond->notify_all();
}
void UnifiedCache::_fetch(
diff --git a/deps/icu-small/source/common/uniset.cpp b/deps/icu-small/source/common/uniset.cpp
index 1db382afe6..3807b83747 100644
--- a/deps/icu-small/source/common/uniset.cpp
+++ b/deps/icu-small/source/common/uniset.cpp
@@ -278,11 +278,11 @@ UnicodeSet& UnicodeSet::copyFrom(const UnicodeSet& o, UBool asThawed) {
* to support cloning in order to allow classes using
* UnicodeMatchers, such as Transliterator, to implement cloning.
*/
-UnicodeFunctor* UnicodeSet::clone() const {
+UnicodeSet* UnicodeSet::clone() const {
return new UnicodeSet(*this);
}
-UnicodeFunctor *UnicodeSet::cloneAsThawed() const {
+UnicodeSet *UnicodeSet::cloneAsThawed() const {
return new UnicodeSet(*this, TRUE);
}
@@ -2172,7 +2172,7 @@ void UnicodeSet::setPattern(const char16_t *newPat, int32_t newPatLen) {
// We can regenerate an equivalent pattern later when requested.
}
-UnicodeFunctor *UnicodeSet::freeze() {
+UnicodeSet *UnicodeSet::freeze() {
if(!isFrozen() && !isBogus()) {
compact();
diff --git a/deps/icu-small/source/common/uniset_props.cpp b/deps/icu-small/source/common/uniset_props.cpp
index 6f7918a91a..45d3dab993 100644
--- a/deps/icu-small/source/common/uniset_props.cpp
+++ b/deps/icu-small/source/common/uniset_props.cpp
@@ -802,7 +802,10 @@ static UBool mungeCharName(char* dst, const char* src, int32_t dstCapacity) {
// Property set API
//----------------------------------------------------------------
-#define FAIL(ec) {ec=U_ILLEGAL_ARGUMENT_ERROR; return *this;}
+#define FAIL(ec) UPRV_BLOCK_MACRO_BEGIN { \
+ ec=U_ILLEGAL_ARGUMENT_ERROR; \
+ return *this; \
+} UPRV_BLOCK_MACRO_END
UnicodeSet&
UnicodeSet::applyIntPropertyValue(UProperty prop, int32_t value, UErrorCode& ec) {
diff --git a/deps/icu-small/source/common/unisetspan.cpp b/deps/icu-small/source/common/unisetspan.cpp
index 0a8893472f..68e44d91ee 100644
--- a/deps/icu-small/source/common/unisetspan.cpp
+++ b/deps/icu-small/source/common/unisetspan.cpp
@@ -400,7 +400,7 @@ UnicodeSetStringSpan::UnicodeSetStringSpan(const UnicodeSetStringSpan &otherStri
if(otherStringSpan.pSpanNotSet==&otherStringSpan.spanSet) {
pSpanNotSet=&spanSet;
} else {
- pSpanNotSet=(UnicodeSet *)otherStringSpan.pSpanNotSet->clone();
+ pSpanNotSet=otherStringSpan.pSpanNotSet->clone();
}
// Allocate a block of meta data.
@@ -436,7 +436,7 @@ void UnicodeSetStringSpan::addToSpanNotSet(UChar32 c) {
if(spanSet.contains(c)) {
return; // Nothing to do.
}
- UnicodeSet *newSet=(UnicodeSet *)spanSet.cloneAsThawed();
+ UnicodeSet *newSet=spanSet.cloneAsThawed();
if(newSet==NULL) {
return; // Out of memory.
} else {
diff --git a/deps/icu-small/source/common/unistr.cpp b/deps/icu-small/source/common/unistr.cpp
index 31b0ed84be..eeb0c3a679 100644
--- a/deps/icu-small/source/common/unistr.cpp
+++ b/deps/icu-small/source/common/unistr.cpp
@@ -332,7 +332,7 @@ Replaceable::clone() const {
}
// UnicodeString overrides clone() with a real implementation
-Replaceable *
+UnicodeString *
UnicodeString::clone() const {
return new UnicodeString(*this);
}
diff --git a/deps/icu-small/source/common/uresbund.cpp b/deps/icu-small/source/common/uresbund.cpp
index c9f2c860da..3a9b4340bb 100644
--- a/deps/icu-small/source/common/uresbund.cpp
+++ b/deps/icu-small/source/common/uresbund.cpp
@@ -31,6 +31,7 @@
#include "ucln_cmn.h"
#include "cmemory.h"
#include "cstring.h"
+#include "mutex.h"
#include "uhash.h"
#include "unicode/uenum.h"
#include "uenumimp.h"
@@ -38,6 +39,7 @@
#include "umutex.h"
#include "putilimp.h"
#include "uassert.h"
+#include "uresdata.h"
using namespace icu;
@@ -47,12 +49,9 @@ TODO: This cache should probably be removed when the deprecated code is
completely removed.
*/
static UHashtable *cache = NULL;
-static icu::UInitOnce gCacheInitOnce;
+static icu::UInitOnce gCacheInitOnce = U_INITONCE_INITIALIZER;
-static UMutex *resbMutex() {
- static UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static UMutex resbMutex;
/* INTERNAL: hashes an entry */
static int32_t U_CALLCONV hashEntry(const UHashTok parm) {
@@ -96,13 +95,12 @@ static UBool chopLocale(char *name) {
* Internal function
*/
static void entryIncrease(UResourceDataEntry *entry) {
- umtx_lock(resbMutex());
+ Mutex lock(&resbMutex);
entry->fCountExisting++;
while(entry->fParent != NULL) {
entry = entry->fParent;
entry->fCountExisting++;
}
- umtx_unlock(resbMutex());
}
/**
@@ -184,9 +182,8 @@ static int32_t ures_flushCache()
/*if shared data hasn't even been lazy evaluated yet
* return 0
*/
- umtx_lock(resbMutex());
+ Mutex lock(&resbMutex);
if (cache == NULL) {
- umtx_unlock(resbMutex());
return 0;
}
@@ -218,7 +215,6 @@ static int32_t ures_flushCache()
* got decremented by free_entry().
*/
} while(deletedMore);
- umtx_unlock(resbMutex());
return rbDeletedNum;
}
@@ -232,9 +228,8 @@ U_CAPI UBool U_EXPORT2 ures_dumpCacheContents(void) {
const UHashElement *e;
UResourceDataEntry *resB;
- umtx_lock(resbMutex());
+ Mutex lock(&resbMutex);
if (cache == NULL) {
- umtx_unlock(resbMutex());
fprintf(stderr,"%s:%d: RB Cache is NULL.\n", __FILE__, __LINE__);
return FALSE;
}
@@ -253,9 +248,6 @@ U_CAPI UBool U_EXPORT2 ures_dumpCacheContents(void) {
}
fprintf(stderr,"%s:%d: RB Cache still contains %d items.\n", __FILE__, __LINE__, uhash_count(cache));
-
- umtx_unlock(resbMutex());
-
return cacheNotEmpty;
}
@@ -401,7 +393,8 @@ static UResourceDataEntry *init_entry(const char *localeID, const char *path, UE
/* We'll try to get alias string from the bundle */
aliasres = res_getResource(&(r->fData), "%%ALIAS");
if (aliasres != RES_BOGUS) {
- const UChar *alias = res_getString(&(r->fData), aliasres, &aliasLen);
+ // No tracing: called during initial data loading
+ const UChar *alias = res_getStringNoTrace(&(r->fData), aliasres, &aliasLen);
if(alias != NULL && aliasLen > 0) { /* if there is actual alias - unload and load new data */
u_UCharsToChars(alias, aliasName, aliasLen+1);
r->fAlias = init_entry(aliasName, path, status);
@@ -542,7 +535,8 @@ loadParentsExceptRoot(UResourceDataEntry *&t1,
Resource parentRes = res_getResource(&t1->fData, "%%Parent");
if (parentRes != RES_BOGUS) { // An explicit parent was found.
int32_t parentLocaleLen = 0;
- const UChar *parentLocaleName = res_getString(&(t1->fData), parentRes, &parentLocaleLen);
+ // No tracing: called during initial data loading
+ const UChar *parentLocaleName = res_getStringNoTrace(&(t1->fData), parentRes, &parentLocaleLen);
if(parentLocaleName != NULL && 0 < parentLocaleLen && parentLocaleLen < nameCapacity) {
u_UCharsToChars(parentLocaleName, name, parentLocaleLen + 1);
if (uprv_strcmp(name, kRootLocaleName) == 0) {
@@ -666,107 +660,105 @@ static UResourceDataEntry *entryOpen(const char* path, const char* localeID,
}
}
- umtx_lock(resbMutex());
- { /* umtx_lock */
- /* We're going to skip all the locales that do not have any data */
- r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault, &intStatus);
+ Mutex lock(&resbMutex); // Lock resbMutex until the end of this function.
+
+ /* We're going to skip all the locales that do not have any data */
+ r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault, &intStatus);
+
+ // If we failed due to out-of-memory, report the failure and exit early.
+ if (intStatus == U_MEMORY_ALLOCATION_ERROR) {
+ *status = intStatus;
+ goto finish;
+ }
+
+ if(r != NULL) { /* if there is one real locale, we can look for parents. */
+ t1 = r;
+ hasRealData = TRUE;
+ if ( usingUSRData ) { /* This code inserts user override data into the inheritance chain */
+ UErrorCode usrStatus = U_ZERO_ERROR;
+ UResourceDataEntry *u1 = init_entry(t1->fName, usrDataPath, &usrStatus);
+ // If we failed due to out-of-memory, report the failure and exit early.
+ if (intStatus == U_MEMORY_ALLOCATION_ERROR) {
+ *status = intStatus;
+ goto finish;
+ }
+ if ( u1 != NULL ) {
+ if(u1->fBogus == U_ZERO_ERROR) {
+ u1->fParent = t1;
+ r = u1;
+ } else {
+ /* the USR override data wasn't found, set it to be deleted */
+ u1->fCountExisting = 0;
+ }
+ }
+ }
+ if (hasChopped && !isRoot) {
+ if (!loadParentsExceptRoot(t1, name, UPRV_LENGTHOF(name), usingUSRData, usrDataPath, status)) {
+ goto finish;
+ }
+ }
+ }
+ /* we could have reached this point without having any real data */
+ /* if that is the case, we need to chain in the default locale */
+ if(r==NULL && openType == URES_OPEN_LOCALE_DEFAULT_ROOT && !isDefault && !isRoot) {
+ /* insert default locale */
+ uprv_strcpy(name, uloc_getDefault());
+ r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault, &intStatus);
// If we failed due to out-of-memory, report the failure and exit early.
if (intStatus == U_MEMORY_ALLOCATION_ERROR) {
*status = intStatus;
- goto finishUnlock;
+ goto finish;
}
-
- if(r != NULL) { /* if there is one real locale, we can look for parents. */
+ intStatus = U_USING_DEFAULT_WARNING;
+ if(r != NULL) { /* the default locale exists */
t1 = r;
hasRealData = TRUE;
- if ( usingUSRData ) { /* This code inserts user override data into the inheritance chain */
- UErrorCode usrStatus = U_ZERO_ERROR;
- UResourceDataEntry *u1 = init_entry(t1->fName, usrDataPath, &usrStatus);
- // If we failed due to out-of-memory, report the failure and exit early.
- if (intStatus == U_MEMORY_ALLOCATION_ERROR) {
- *status = intStatus;
- goto finishUnlock;
- }
- if ( u1 != NULL ) {
- if(u1->fBogus == U_ZERO_ERROR) {
- u1->fParent = t1;
- r = u1;
- } else {
- /* the USR override data wasn't found, set it to be deleted */
- u1->fCountExisting = 0;
- }
- }
- }
+ isDefault = TRUE;
+ // TODO: Why not if (usingUSRData) { ... } like in the non-default-locale code path?
if (hasChopped && !isRoot) {
if (!loadParentsExceptRoot(t1, name, UPRV_LENGTHOF(name), usingUSRData, usrDataPath, status)) {
- goto finishUnlock;
+ goto finish;
}
}
}
+ }
- /* we could have reached this point without having any real data */
- /* if that is the case, we need to chain in the default locale */
- if(r==NULL && openType == URES_OPEN_LOCALE_DEFAULT_ROOT && !isDefault && !isRoot) {
- /* insert default locale */
- uprv_strcpy(name, uloc_getDefault());
- r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault, &intStatus);
- // If we failed due to out-of-memory, report the failure and exit early.
- if (intStatus == U_MEMORY_ALLOCATION_ERROR) {
- *status = intStatus;
- goto finishUnlock;
- }
+ /* we could still have r == NULL at this point - maybe even default locale is not */
+ /* present */
+ if(r == NULL) {
+ uprv_strcpy(name, kRootLocaleName);
+ r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault, &intStatus);
+ // If we failed due to out-of-memory, report the failure and exit early.
+ if (intStatus == U_MEMORY_ALLOCATION_ERROR) {
+ *status = intStatus;
+ goto finish;
+ }
+ if(r != NULL) {
+ t1 = r;
intStatus = U_USING_DEFAULT_WARNING;
- if(r != NULL) { /* the default locale exists */
- t1 = r;
- hasRealData = TRUE;
- isDefault = TRUE;
- // TODO: Why not if (usingUSRData) { ... } like in the non-default-locale code path?
- if (hasChopped && !isRoot) {
- if (!loadParentsExceptRoot(t1, name, UPRV_LENGTHOF(name), usingUSRData, usrDataPath, status)) {
- goto finishUnlock;
- }
- }
- }
+ hasRealData = TRUE;
+ } else { /* we don't even have the root locale */
+ *status = U_MISSING_RESOURCE_ERROR;
+ goto finish;
}
-
- /* we could still have r == NULL at this point - maybe even default locale is not */
- /* present */
- if(r == NULL) {
- uprv_strcpy(name, kRootLocaleName);
- r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault, &intStatus);
- // If we failed due to out-of-memory, report the failure and exit early.
- if (intStatus == U_MEMORY_ALLOCATION_ERROR) {
- *status = intStatus;
- goto finishUnlock;
- }
- if(r != NULL) {
- t1 = r;
- intStatus = U_USING_DEFAULT_WARNING;
- hasRealData = TRUE;
- } else { /* we don't even have the root locale */
- *status = U_MISSING_RESOURCE_ERROR;
- goto finishUnlock;
- }
- } else if(!isRoot && uprv_strcmp(t1->fName, kRootLocaleName) != 0 &&
- t1->fParent == NULL && !r->fData.noFallback) {
- if (!insertRootBundle(t1, status)) {
- goto finishUnlock;
- }
- if(!hasRealData) {
- r->fBogus = U_USING_DEFAULT_WARNING;
- }
+ } else if(!isRoot && uprv_strcmp(t1->fName, kRootLocaleName) != 0 &&
+ t1->fParent == NULL && !r->fData.noFallback) {
+ if (!insertRootBundle(t1, status)) {
+ goto finish;
}
-
- // TODO: Does this ever loop?
- while(r != NULL && !isRoot && t1->fParent != NULL) {
- t1->fParent->fCountExisting++;
- t1 = t1->fParent;
+ if(!hasRealData) {
+ r->fBogus = U_USING_DEFAULT_WARNING;
}
- } /* umtx_lock */
-finishUnlock:
- umtx_unlock(resbMutex());
+ }
+ // TODO: Does this ever loop?
+ while(r != NULL && !isRoot && t1->fParent != NULL) {
+ t1->fParent->fCountExisting++;
+ t1 = t1->fParent;
+ }
+
+finish:
if(U_SUCCESS(*status)) {
if(intStatus != U_ZERO_ERROR) {
*status = intStatus;
@@ -790,7 +782,7 @@ entryOpenDirect(const char* path, const char* localeID, UErrorCode* status) {
return NULL;
}
- umtx_lock(resbMutex());
+ Mutex lock(&resbMutex);
// findFirstExisting() without fallbacks.
UResourceDataEntry *r = init_entry(localeID, path, status);
if(U_SUCCESS(*status)) {
@@ -828,7 +820,6 @@ entryOpenDirect(const char* path, const char* localeID, UErrorCode* status) {
t1 = t1->fParent;
}
}
- umtx_unlock(resbMutex());
return r;
}
@@ -871,9 +862,8 @@ static void entryCloseInt(UResourceDataEntry *resB) {
*/
static void entryClose(UResourceDataEntry *resB) {
- umtx_lock(resbMutex());
+ Mutex lock(&resbMutex);
entryCloseInt(resB);
- umtx_unlock(resbMutex());
}
/*
@@ -1177,6 +1167,7 @@ static UResourceBundle *init_resb_result(const ResourceData *rdata, Resource r,
if(mainRes != result) {
ures_close(mainRes);
}
+ ResourceTracer(resB).maybeTrace("getalias");
return result;
}
} else {
@@ -1256,6 +1247,7 @@ static UResourceBundle *init_resb_result(const ResourceData *rdata, Resource r,
/*resB->fParent = parent->fRes;*/
uprv_memmove(&resB->fResData, rdata, sizeof(ResourceData));
resB->fSize = res_countArrayItems(&(resB->fResData), resB->fRes);
+ ResourceTracer(resB).trace("get");
return resB;
}
@@ -1304,7 +1296,7 @@ U_CAPI const UChar* U_EXPORT2 ures_getString(const UResourceBundle* resB, int32_
*status = U_ILLEGAL_ARGUMENT_ERROR;
return NULL;
}
- s = res_getString(&(resB->fResData), resB->fRes, len);
+ s = res_getString({resB}, &(resB->fResData), resB->fRes, len);
if (s == NULL) {
*status = U_RESOURCE_TYPE_MISMATCH;
}
@@ -1393,7 +1385,7 @@ U_CAPI const uint8_t* U_EXPORT2 ures_getBinary(const UResourceBundle* resB, int3
*status = U_ILLEGAL_ARGUMENT_ERROR;
return NULL;
}
- p = res_getBinary(&(resB->fResData), resB->fRes, len);
+ p = res_getBinary({resB}, &(resB->fResData), resB->fRes, len);
if (p == NULL) {
*status = U_RESOURCE_TYPE_MISMATCH;
}
@@ -1410,7 +1402,7 @@ U_CAPI const int32_t* U_EXPORT2 ures_getIntVector(const UResourceBundle* resB, i
*status = U_ILLEGAL_ARGUMENT_ERROR;
return NULL;
}
- p = res_getIntVector(&(resB->fResData), resB->fRes, len);
+ p = res_getIntVector({resB}, &(resB->fResData), resB->fRes, len);
if (p == NULL) {
*status = U_RESOURCE_TYPE_MISMATCH;
}
@@ -1431,7 +1423,7 @@ U_CAPI int32_t U_EXPORT2 ures_getInt(const UResourceBundle* resB, UErrorCode *st
*status = U_RESOURCE_TYPE_MISMATCH;
return 0xffffffff;
}
- return RES_GET_INT(resB->fRes);
+ return res_getInt({resB}, resB->fRes);
}
U_CAPI uint32_t U_EXPORT2 ures_getUInt(const UResourceBundle* resB, UErrorCode *status) {
@@ -1446,7 +1438,7 @@ U_CAPI uint32_t U_EXPORT2 ures_getUInt(const UResourceBundle* resB, UErrorCode *
*status = U_RESOURCE_TYPE_MISMATCH;
return 0xffffffff;
}
- return RES_GET_UINT(resB->fRes);
+ return res_getUInt({resB}, resB->fRes);
}
U_CAPI UResType U_EXPORT2 ures_getType(const UResourceBundle *resB) {
@@ -1457,10 +1449,18 @@ U_CAPI UResType U_EXPORT2 ures_getType(const UResourceBundle *resB) {
}
U_CAPI const char * U_EXPORT2 ures_getKey(const UResourceBundle *resB) {
+ //
+ // TODO: Trace ures_getKey? I guess not usually.
+ //
+ // We usually get the key string to decide whether we want the value, or to
+ // make a key-value pair. Tracing the value should suffice.
+ //
+ // However, I believe we have some data (e.g., in res_index) where the key
+ // strings are the data. Tracing the enclosing table should suffice.
+ //
if(resB == NULL) {
return NULL;
}
-
return(resB->fKey);
}
@@ -1480,7 +1480,7 @@ static const UChar* ures_getStringWithAlias(const UResourceBundle *resB, Resourc
ures_close(tempRes);
return result;
} else {
- return res_getString(&(resB->fResData), r, len);
+ return res_getString({resB, sIndex}, &(resB->fResData), r, len);
}
}
@@ -1516,7 +1516,7 @@ U_CAPI const UChar* U_EXPORT2 ures_getNextString(UResourceBundle *resB, int32_t*
switch(RES_GET_TYPE(resB->fRes)) {
case URES_STRING:
case URES_STRING_V2:
- return res_getString(&(resB->fResData), resB->fRes, len);
+ return res_getString({resB}, &(resB->fResData), resB->fRes, len);
case URES_TABLE:
case URES_TABLE16:
case URES_TABLE32:
@@ -1661,7 +1661,7 @@ U_CAPI const UChar* U_EXPORT2 ures_getStringByIndex(const UResourceBundle *resB,
switch(RES_GET_TYPE(resB->fRes)) {
case URES_STRING:
case URES_STRING_V2:
- return res_getString(&(resB->fResData), resB->fRes, len);
+ return res_getString({resB}, &(resB->fResData), resB->fRes, len);
case URES_TABLE:
case URES_TABLE16:
case URES_TABLE32:
@@ -1953,10 +1953,10 @@ void getAllItemsWithFallback(
// When the sink sees the no-fallback/no-inheritance marker,
// then it would remove the parent's item.
// We would deserialize parent values even though they are overridden in a child bundle.
- value.pResData = &bundle->fResData;
+ value.setData(&bundle->fResData);
UResourceDataEntry *parentEntry = bundle->fData->fParent;
UBool hasParent = parentEntry != NULL && U_SUCCESS(parentEntry->fBogus);
- value.setResource(bundle->fRes);
+ value.setResource(bundle->fRes, ResourceTracer(bundle));
sink.put(bundle->fKey, value, !hasParent, errorCode);
if (hasParent) {
// We might try to query the sink whether
@@ -2001,31 +2001,60 @@ void getAllItemsWithFallback(
} // namespace
+// Requires a ResourceDataValue fill-in, so that we need not cast from a ResourceValue.
+// Unfortunately, the caller must know which subclass to make and pass in.
+// Alternatively, we could make it as polymorphic as in Java by
+// returning a ResourceValue pointer (possibly wrapped into a LocalPointer)
+// that the caller then owns.
+//
+// Also requires a UResourceBundle fill-in, so that the value's ResourceTracer
+// can point to a non-local bundle.
+// Without tracing, the child bundle could be a function-local object.
+U_CAPI void U_EXPORT2
+ures_getValueWithFallback(const UResourceBundle *bundle, const char *path,
+ UResourceBundle *tempFillIn,
+ ResourceDataValue &value, UErrorCode &errorCode) {
+ if (U_FAILURE(errorCode)) { return; }
+ if (path == nullptr) {
+ errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+ return;
+ }
+ const UResourceBundle *rb;
+ if (*path == 0) {
+ // empty path
+ rb = bundle;
+ } else {
+ rb = ures_getByKeyWithFallback(bundle, path, tempFillIn, &errorCode);
+ if (U_FAILURE(errorCode)) {
+ return;
+ }
+ }
+ value.setData(&rb->fResData);
+ value.setResource(rb->fRes, ResourceTracer(rb));
+}
+
U_CAPI void U_EXPORT2
ures_getAllItemsWithFallback(const UResourceBundle *bundle, const char *path,
icu::ResourceSink &sink, UErrorCode &errorCode) {
if (U_FAILURE(errorCode)) { return; }
- if (path == NULL) {
+ if (path == nullptr) {
errorCode = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
- UResourceBundle stackBundle;
- ures_initStackObject(&stackBundle);
+ StackUResourceBundle stackBundle;
const UResourceBundle *rb;
if (*path == 0) {
// empty path
rb = bundle;
} else {
- rb = ures_getByKeyWithFallback(bundle, path, &stackBundle, &errorCode);
+ rb = ures_getByKeyWithFallback(bundle, path, stackBundle.getAlias(), &errorCode);
if (U_FAILURE(errorCode)) {
- ures_close(&stackBundle);
return;
}
}
// Get all table items with fallback.
ResourceDataValue value;
getAllItemsWithFallback(rb, value, sink, errorCode);
- ures_close(&stackBundle);
}
U_CAPI UResourceBundle* U_EXPORT2 ures_getByKey(const UResourceBundle *resB, const char* inKey, UResourceBundle *fillIn, UErrorCode *status) {
@@ -2108,7 +2137,7 @@ U_CAPI const UChar* U_EXPORT2 ures_getStringByKey(const UResourceBundle *resB, c
switch (RES_GET_TYPE(res)) {
case URES_STRING:
case URES_STRING_V2:
- return res_getString(rd, res, len);
+ return res_getString({resB, key}, rd, res, len);
case URES_ALIAS:
{
const UChar* result = 0;
@@ -2130,7 +2159,7 @@ U_CAPI const UChar* U_EXPORT2 ures_getStringByKey(const UResourceBundle *resB, c
switch (RES_GET_TYPE(res)) {
case URES_STRING:
case URES_STRING_V2:
- return res_getString(&(resB->fResData), res, len);
+ return res_getString({resB, key}, &(resB->fResData), res, len);
case URES_ALIAS:
{
const UChar* result = 0;
@@ -2151,6 +2180,7 @@ U_CAPI const UChar* U_EXPORT2 ures_getStringByKey(const UResourceBundle *resB, c
/* here should go a first attempt to locate the key using index table */
const ResourceData *rd = getFallbackData(resB, &key, &realData, &res, status);
if(U_SUCCESS(*status)) {
+ // TODO: Tracing
return res_getString(rd, res, len);
} else {
*status = U_MISSING_RESOURCE_ERROR;
@@ -2296,6 +2326,8 @@ ures_openWithType(UResourceBundle *r, const char* path, const char* localeID,
r->fSize = res_countArrayItems(&(r->fResData), r->fRes);
r->fIndex = -1;
+ ResourceTracer(r).traceOpen();
+
return r;
}
diff --git a/deps/icu-small/source/common/uresdata.cpp b/deps/icu-small/source/common/uresdata.cpp
index a0b8d3ba90..1bb938be62 100644
--- a/deps/icu-small/source/common/uresdata.cpp
+++ b/deps/icu-small/source/common/uresdata.cpp
@@ -33,6 +33,7 @@
#include "uinvchar.h"
#include "uresdata.h"
#include "uresimp.h"
+#include "utracimp.h"
/*
* Resource access helpers
@@ -307,7 +308,7 @@ res_getPublicType(Resource res) {
}
U_CAPI const UChar * U_EXPORT2
-res_getString(const ResourceData *pResData, Resource res, int32_t *pLength) {
+res_getStringNoTrace(const ResourceData *pResData, Resource res, int32_t *pLength) {
const UChar *p;
uint32_t offset=RES_GET_OFFSET(res);
int32_t length;
@@ -402,7 +403,8 @@ int32_t getStringArray(const ResourceData *pResData, const icu::ResourceArray &a
}
for(int32_t i = 0; i < length; ++i) {
int32_t sLength;
- const UChar *s = res_getString(pResData, array.internalGetResource(pResData, i), &sLength);
+ // No tracing: handled by the caller
+ const UChar *s = res_getStringNoTrace(pResData, array.internalGetResource(pResData, i), &sLength);
if(s == NULL) {
errorCode = U_RESOURCE_TYPE_MISMATCH;
return 0;
@@ -434,7 +436,7 @@ res_getAlias(const ResourceData *pResData, Resource res, int32_t *pLength) {
}
U_CAPI const uint8_t * U_EXPORT2
-res_getBinary(const ResourceData *pResData, Resource res, int32_t *pLength) {
+res_getBinaryNoTrace(const ResourceData *pResData, Resource res, int32_t *pLength) {
const uint8_t *p;
uint32_t offset=RES_GET_OFFSET(res);
int32_t length;
@@ -454,7 +456,7 @@ res_getBinary(const ResourceData *pResData, Resource res, int32_t *pLength) {
U_CAPI const int32_t * U_EXPORT2
-res_getIntVector(const ResourceData *pResData, Resource res, int32_t *pLength) {
+res_getIntVectorNoTrace(const ResourceData *pResData, Resource res, int32_t *pLength) {
const int32_t *p;
uint32_t offset=RES_GET_OFFSET(res);
int32_t length;
@@ -507,7 +509,7 @@ const UChar *ResourceDataValue::getString(int32_t &length, UErrorCode &errorCode
if(U_FAILURE(errorCode)) {
return NULL;
}
- const UChar *s = res_getString(pResData, res, &length);
+ const UChar *s = res_getString(fTraceInfo, &getData(), res, &length);
if(s == NULL) {
errorCode = U_RESOURCE_TYPE_MISMATCH;
}
@@ -518,7 +520,7 @@ const UChar *ResourceDataValue::getAliasString(int32_t &length, UErrorCode &erro
if(U_FAILURE(errorCode)) {
return NULL;
}
- const UChar *s = res_getAlias(pResData, res, &length);
+ const UChar *s = res_getAlias(&getData(), res, &length);
if(s == NULL) {
errorCode = U_RESOURCE_TYPE_MISMATCH;
}
@@ -532,7 +534,7 @@ int32_t ResourceDataValue::getInt(UErrorCode &errorCode) const {
if(RES_GET_TYPE(res) != URES_INT) {
errorCode = U_RESOURCE_TYPE_MISMATCH;
}
- return RES_GET_INT(res);
+ return res_getInt(fTraceInfo, res);
}
uint32_t ResourceDataValue::getUInt(UErrorCode &errorCode) const {
@@ -542,14 +544,14 @@ uint32_t ResourceDataValue::getUInt(UErrorCode &errorCode) const {
if(RES_GET_TYPE(res) != URES_INT) {
errorCode = U_RESOURCE_TYPE_MISMATCH;
}
- return RES_GET_UINT(res);
+ return res_getUInt(fTraceInfo, res);
}
const int32_t *ResourceDataValue::getIntVector(int32_t &length, UErrorCode &errorCode) const {
if(U_FAILURE(errorCode)) {
return NULL;
}
- const int32_t *iv = res_getIntVector(pResData, res, &length);
+ const int32_t *iv = res_getIntVector(fTraceInfo, &getData(), res, &length);
if(iv == NULL) {
errorCode = U_RESOURCE_TYPE_MISMATCH;
}
@@ -560,7 +562,7 @@ const uint8_t *ResourceDataValue::getBinary(int32_t &length, UErrorCode &errorCo
if(U_FAILURE(errorCode)) {
return NULL;
}
- const uint8_t *b = res_getBinary(pResData, res, &length);
+ const uint8_t *b = res_getBinary(fTraceInfo, &getData(), res, &length);
if(b == NULL) {
errorCode = U_RESOURCE_TYPE_MISMATCH;
}
@@ -578,19 +580,19 @@ ResourceArray ResourceDataValue::getArray(UErrorCode &errorCode) const {
switch(RES_GET_TYPE(res)) {
case URES_ARRAY:
if (offset!=0) { // empty if offset==0
- items32 = (const Resource *)pResData->pRoot+offset;
+ items32 = (const Resource *)getData().pRoot+offset;
length = *items32++;
}
break;
case URES_ARRAY16:
- items16 = pResData->p16BitUnits+offset;
+ items16 = getData().p16BitUnits+offset;
length = *items16++;
break;
default:
errorCode = U_RESOURCE_TYPE_MISMATCH;
return ResourceArray();
}
- return ResourceArray(items16, items32, length);
+ return ResourceArray(items16, items32, length, fTraceInfo);
}
ResourceTable ResourceDataValue::getTable(UErrorCode &errorCode) const {
@@ -606,19 +608,19 @@ ResourceTable ResourceDataValue::getTable(UErrorCode &errorCode) const {
switch(RES_GET_TYPE(res)) {
case URES_TABLE:
if (offset != 0) { // empty if offset==0
- keys16 = (const uint16_t *)(pResData->pRoot+offset);
+ keys16 = (const uint16_t *)(getData().pRoot+offset);
length = *keys16++;
items32 = (const Resource *)(keys16+length+(~length&1));
}
break;
case URES_TABLE16:
- keys16 = pResData->p16BitUnits+offset;
+ keys16 = getData().p16BitUnits+offset;
length = *keys16++;
items16 = keys16 + length;
break;
case URES_TABLE32:
if (offset != 0) { // empty if offset==0
- keys32 = pResData->pRoot+offset;
+ keys32 = getData().pRoot+offset;
length = *keys32++;
items32 = (const Resource *)keys32 + length;
}
@@ -627,22 +629,22 @@ ResourceTable ResourceDataValue::getTable(UErrorCode &errorCode) const {
errorCode = U_RESOURCE_TYPE_MISMATCH;
return ResourceTable();
}
- return ResourceTable(keys16, keys32, items16, items32, length);
+ return ResourceTable(keys16, keys32, items16, items32, length, fTraceInfo);
}
UBool ResourceDataValue::isNoInheritanceMarker() const {
- return ::isNoInheritanceMarker(pResData, res);
+ return ::isNoInheritanceMarker(&getData(), res);
}
int32_t ResourceDataValue::getStringArray(UnicodeString *dest, int32_t capacity,
UErrorCode &errorCode) const {
- return ::getStringArray(pResData, getArray(errorCode), dest, capacity, errorCode);
+ return ::getStringArray(&getData(), getArray(errorCode), dest, capacity, errorCode);
}
int32_t ResourceDataValue::getStringArrayOrStringAsArray(UnicodeString *dest, int32_t capacity,
UErrorCode &errorCode) const {
if(URES_IS_ARRAY(res)) {
- return ::getStringArray(pResData, getArray(errorCode), dest, capacity, errorCode);
+ return ::getStringArray(&getData(), getArray(errorCode), dest, capacity, errorCode);
}
if(U_FAILURE(errorCode)) {
return 0;
@@ -656,7 +658,7 @@ int32_t ResourceDataValue::getStringArrayOrStringAsArray(UnicodeString *dest, in
return 1;
}
int32_t sLength;
- const UChar *s = res_getString(pResData, res, &sLength);
+ const UChar *s = res_getString(fTraceInfo, &getData(), res, &sLength);
if(s != NULL) {
dest[0].setTo(TRUE, s, sLength);
return 1;
@@ -671,7 +673,7 @@ UnicodeString ResourceDataValue::getStringOrFirstOfArray(UErrorCode &errorCode)
return us;
}
int32_t sLength;
- const UChar *s = res_getString(pResData, res, &sLength);
+ const UChar *s = res_getString(fTraceInfo, &getData(), res, &sLength);
if(s != NULL) {
us.setTo(TRUE, s, sLength);
return us;
@@ -681,7 +683,8 @@ UnicodeString ResourceDataValue::getStringOrFirstOfArray(UErrorCode &errorCode)
return us;
}
if(array.getSize() > 0) {
- s = res_getString(pResData, array.internalGetResource(pResData, 0), &sLength);
+ // Tracing is already performed above (unimportant for trace that this is an array)
+ s = res_getStringNoTrace(&getData(), array.internalGetResource(&getData(), 0), &sLength);
if(s != NULL) {
us.setTo(TRUE, s, sLength);
return us;
@@ -818,18 +821,45 @@ UBool icu::ResourceTable::getKeyAndValue(int32_t i,
const char *&key, icu::ResourceValue &value) const {
if(0 <= i && i < length) {
icu::ResourceDataValue &rdValue = static_cast<icu::ResourceDataValue &>(value);
- if (keys16 != NULL) {
- key = RES_GET_KEY16(rdValue.pResData, keys16[i]);
+ if (keys16 != nullptr) {
+ key = RES_GET_KEY16(&rdValue.getData(), keys16[i]);
} else {
- key = RES_GET_KEY32(rdValue.pResData, keys32[i]);
+ key = RES_GET_KEY32(&rdValue.getData(), keys32[i]);
}
Resource res;
- if (items16 != NULL) {
- res = makeResourceFrom16(rdValue.pResData, items16[i]);
+ if (items16 != nullptr) {
+ res = makeResourceFrom16(&rdValue.getData(), items16[i]);
} else {
res = items32[i];
}
- rdValue.setResource(res);
+ // Note: the ResourceTracer keeps a reference to the field of this
+ // ResourceTable. This is OK because the ResourceTable should remain
+ // alive for the duration that fields are being read from it
+ // (including nested fields).
+ rdValue.setResource(res, ResourceTracer(fTraceInfo, key));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+UBool icu::ResourceTable::findValue(const char *key, ResourceValue &value) const {
+ icu::ResourceDataValue &rdValue = static_cast<icu::ResourceDataValue &>(value);
+ const char *realKey = nullptr;
+ int32_t i;
+ if (keys16 != nullptr) {
+ i = _res_findTableItem(&rdValue.getData(), keys16, length, key, &realKey);
+ } else {
+ i = _res_findTable32Item(&rdValue.getData(), keys32, length, key, &realKey);
+ }
+ if (i >= 0) {
+ Resource res;
+ if (items16 != nullptr) {
+ res = makeResourceFrom16(&rdValue.getData(), items16[i]);
+ } else {
+ res = items32[i];
+ }
+ // Same note about lifetime as in getKeyAndValue().
+ rdValue.setResource(res, ResourceTracer(fTraceInfo, key));
return TRUE;
}
return FALSE;
@@ -875,7 +905,13 @@ uint32_t icu::ResourceArray::internalGetResource(const ResourceData *pResData, i
UBool icu::ResourceArray::getValue(int32_t i, icu::ResourceValue &value) const {
if(0 <= i && i < length) {
icu::ResourceDataValue &rdValue = static_cast<icu::ResourceDataValue &>(value);
- rdValue.setResource(internalGetResource(rdValue.pResData, i));
+ // Note: the ResourceTracer keeps a reference to the field of this
+ // ResourceArray. This is OK because the ResourceArray should remain
+ // alive for the duration that fields are being read from it
+ // (including nested fields).
+ rdValue.setResource(
+ internalGetResource(&rdValue.getData(), i),
+ ResourceTracer(fTraceInfo, i));
return TRUE;
}
return FALSE;
diff --git a/deps/icu-small/source/common/uresdata.h b/deps/icu-small/source/common/uresdata.h
index 4e28ddccf6..d1b67babf2 100644
--- a/deps/icu-small/source/common/uresdata.h
+++ b/deps/icu-small/source/common/uresdata.h
@@ -69,14 +69,16 @@ typedef uint32_t Resource;
#define RES_GET_OFFSET(res) ((res)&0x0fffffff)
#define RES_GET_POINTER(pRoot, res) ((pRoot)+RES_GET_OFFSET(res))
-/* get signed and unsigned integer values directly from the Resource handle */
+/* get signed and unsigned integer values directly from the Resource handle
+ * NOTE: For proper logging, please use the res_getInt() constexpr
+ */
#if U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC
-# define RES_GET_INT(res) (((int32_t)((res)<<4L))>>4L)
+# define RES_GET_INT_NO_TRACE(res) (((int32_t)((res)<<4L))>>4L)
#else
-# define RES_GET_INT(res) (int32_t)(((res)&0x08000000) ? (res)|0xf0000000 : (res)&0x07ffffff)
+# define RES_GET_INT_NO_TRACE(res) (int32_t)(((res)&0x08000000) ? (res)|0xf0000000 : (res)&0x07ffffff)
#endif
-#define RES_GET_UINT(res) ((res)&0x0fffffff)
+#define RES_GET_UINT_NO_TRACE(res) ((res)&0x0fffffff)
#define URES_IS_ARRAY(type) ((int32_t)(type)==URES_ARRAY || (int32_t)(type)==URES_ARRAY16)
#define URES_IS_TABLE(type) ((int32_t)(type)==URES_TABLE || (int32_t)(type)==URES_TABLE16 || (int32_t)(type)==URES_TABLE32)
@@ -423,22 +425,26 @@ res_unload(ResourceData *pResData);
U_INTERNAL UResType U_EXPORT2
res_getPublicType(Resource res);
+///////////////////////////////////////////////////////////////////////////
+// To enable tracing, use the inline versions of the res_get* functions. //
+///////////////////////////////////////////////////////////////////////////
+
/*
* Return a pointer to a zero-terminated, const UChar* string
* and set its length in *pLength.
* Returns NULL if not found.
*/
U_INTERNAL const UChar * U_EXPORT2
-res_getString(const ResourceData *pResData, Resource res, int32_t *pLength);
-
-U_INTERNAL const UChar * U_EXPORT2
-res_getAlias(const ResourceData *pResData, Resource res, int32_t *pLength);
+res_getStringNoTrace(const ResourceData *pResData, Resource res, int32_t *pLength);
U_INTERNAL const uint8_t * U_EXPORT2
-res_getBinary(const ResourceData *pResData, Resource res, int32_t *pLength);
+res_getBinaryNoTrace(const ResourceData *pResData, Resource res, int32_t *pLength);
U_INTERNAL const int32_t * U_EXPORT2
-res_getIntVector(const ResourceData *pResData, Resource res, int32_t *pLength);
+res_getIntVectorNoTrace(const ResourceData *pResData, Resource res, int32_t *pLength);
+
+U_INTERNAL const UChar * U_EXPORT2
+res_getAlias(const ResourceData *pResData, Resource res, int32_t *pLength);
U_INTERNAL Resource U_EXPORT2
res_getResource(const ResourceData *pResData, const char *key);
@@ -470,17 +476,55 @@ U_CFUNC Resource res_findResource(const ResourceData *pResData, Resource r,
#ifdef __cplusplus
#include "resource.h"
+#include "restrace.h"
U_NAMESPACE_BEGIN
+inline const UChar* res_getString(const ResourceTracer& traceInfo,
+ const ResourceData *pResData, Resource res, int32_t *pLength) {
+ traceInfo.trace("string");
+ return res_getStringNoTrace(pResData, res, pLength);
+}
+
+inline const uint8_t* res_getBinary(const ResourceTracer& traceInfo,
+ const ResourceData *pResData, Resource res, int32_t *pLength) {
+ traceInfo.trace("binary");
+ return res_getBinaryNoTrace(pResData, res, pLength);
+}
+
+inline const int32_t* res_getIntVector(const ResourceTracer& traceInfo,
+ const ResourceData *pResData, Resource res, int32_t *pLength) {
+ traceInfo.trace("intvector");
+ return res_getIntVectorNoTrace(pResData, res, pLength);
+}
+
+inline int32_t res_getInt(const ResourceTracer& traceInfo, Resource res) {
+ traceInfo.trace("int");
+ return RES_GET_INT_NO_TRACE(res);
+}
+
+inline uint32_t res_getUInt(const ResourceTracer& traceInfo, Resource res) {
+ traceInfo.trace("uint");
+ return RES_GET_UINT_NO_TRACE(res);
+}
+
class ResourceDataValue : public ResourceValue {
public:
- ResourceDataValue() : pResData(NULL), res(static_cast<Resource>(URES_NONE)) {}
+ ResourceDataValue() :
+ res(static_cast<Resource>(URES_NONE)),
+ fTraceInfo() {}
virtual ~ResourceDataValue();
- void setData(const ResourceData *data) { pResData = data; }
- void setResource(Resource r) { res = r; }
+ void setData(const ResourceData *data) {
+ resData = *data;
+ }
+ void setResource(Resource r, ResourceTracer&& traceInfo) {
+ res = r;
+ fTraceInfo = traceInfo;
+ }
+
+ const ResourceData &getData() const { return resData; }
virtual UResType getType() const;
virtual const UChar *getString(int32_t &length, UErrorCode &errorCode) const;
virtual const UChar *getAliasString(int32_t &length, UErrorCode &errorCode) const;
@@ -497,10 +541,12 @@ public:
UErrorCode &errorCode) const;
virtual UnicodeString getStringOrFirstOfArray(UErrorCode &errorCode) const;
- const ResourceData *pResData;
-
private:
+ // TODO(ICU-20769): If UResourceBundle.fResData becomes a pointer,
+ // then remove this value field again and just store a pResData pointer.
+ ResourceData resData;
Resource res;
+ ResourceTracer fTraceInfo;
};
U_NAMESPACE_END
diff --git a/deps/icu-small/source/common/uresimp.h b/deps/icu-small/source/common/uresimp.h
index 16144012a5..2e477dfad3 100644
--- a/deps/icu-small/source/common/uresimp.h
+++ b/deps/icu-small/source/common/uresimp.h
@@ -67,6 +67,9 @@ struct UResourceBundle {
char *fVersion;
UResourceDataEntry *fTopLevelData; /* for getting the valid locale */
char *fResPath; /* full path to the resource: "zh_TW/CollationElements/Sequence" */
+ // TODO(ICU-20769): Try to change the by-value fResData into a pointer,
+ // with the struct in only one place for each bundle.
+ // Also replace class ResourceDataValue.resData with a pResData pointer again.
ResourceData fResData;
char fResBuf[RES_BUFSIZE];
int32_t fResPathLen;
@@ -282,6 +285,11 @@ ures_getStringByKeyWithFallback(const UResourceBundle *resB,
#ifdef __cplusplus
U_CAPI void U_EXPORT2
+ures_getValueWithFallback(const UResourceBundle *bundle, const char *path,
+ UResourceBundle *tempFillIn,
+ icu::ResourceDataValue &value, UErrorCode &errorCode);
+
+U_CAPI void U_EXPORT2
ures_getAllItemsWithFallback(const UResourceBundle *bundle, const char *path,
icu::ResourceSink &sink, UErrorCode &errorCode);
diff --git a/deps/icu-small/source/common/usprep.cpp b/deps/icu-small/source/common/usprep.cpp
index 9155ae077b..f1c075a391 100644
--- a/deps/icu-small/source/common/usprep.cpp
+++ b/deps/icu-small/source/common/usprep.cpp
@@ -45,13 +45,9 @@ U_CDECL_BEGIN
Static cache for already opened StringPrep profiles
*/
static UHashtable *SHARED_DATA_HASHTABLE = NULL;
-static icu::UInitOnce gSharedDataInitOnce;
-
-static UMutex *usprepMutex() {
- static UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static icu::UInitOnce gSharedDataInitOnce = U_INITONCE_INITIALIZER;
+static UMutex usprepMutex;
/* format version of spp file */
//static uint8_t formatVersion[4]={ 0, 0, 0, 0 };
@@ -151,9 +147,9 @@ usprep_internal_flushCache(UBool noRefCount){
* if shared data hasn't even been lazy evaluated yet
* return 0
*/
- umtx_lock(usprepMutex());
+ umtx_lock(&usprepMutex);
if (SHARED_DATA_HASHTABLE == NULL) {
- umtx_unlock(usprepMutex());
+ umtx_unlock(&usprepMutex);
return 0;
}
@@ -184,7 +180,7 @@ usprep_internal_flushCache(UBool noRefCount){
}
}
- umtx_unlock(usprepMutex());
+ umtx_unlock(&usprepMutex);
return deletedNum;
}
@@ -262,7 +258,7 @@ loadData(UStringPrepProfile* profile,
}
/* in the mutex block, set the data for this process */
- umtx_lock(usprepMutex());
+ umtx_lock(&usprepMutex);
if(profile->sprepData==NULL) {
profile->sprepData=dataMemory;
dataMemory=NULL;
@@ -271,7 +267,7 @@ loadData(UStringPrepProfile* profile,
} else {
p=(const int32_t *)udata_getMemory(profile->sprepData);
}
- umtx_unlock(usprepMutex());
+ umtx_unlock(&usprepMutex);
/* initialize some variables */
profile->mappingData=(uint16_t *)((uint8_t *)(p+_SPREP_INDEX_TOP)+profile->indexes[_SPREP_INDEX_TRIE_SIZE]);
@@ -328,12 +324,12 @@ usprep_getProfile(const char* path,
stackKey.path = (char*) path;
/* fetch the data from the cache */
- umtx_lock(usprepMutex());
+ umtx_lock(&usprepMutex);
profile = (UStringPrepProfile*) (uhash_get(SHARED_DATA_HASHTABLE,&stackKey));
if(profile != NULL) {
profile->refCount++;
}
- umtx_unlock(usprepMutex());
+ umtx_unlock(&usprepMutex);
if(profile == NULL) {
/* else load the data and put the data in the cache */
@@ -365,7 +361,7 @@ usprep_getProfile(const char* path,
return NULL;
}
- umtx_lock(usprepMutex());
+ umtx_lock(&usprepMutex);
// If another thread already inserted the same key/value, refcount and cleanup our thread data
profile = (UStringPrepProfile*) (uhash_get(SHARED_DATA_HASHTABLE,&stackKey));
if(profile != NULL) {
@@ -386,7 +382,7 @@ usprep_getProfile(const char* path,
profile->refCount = 1;
uhash_put(SHARED_DATA_HASHTABLE, key.orphan(), profile, status);
}
- umtx_unlock(usprepMutex());
+ umtx_unlock(&usprepMutex);
}
return profile;
@@ -425,12 +421,12 @@ usprep_close(UStringPrepProfile* profile){
return;
}
- umtx_lock(usprepMutex());
+ umtx_lock(&usprepMutex);
/* decrement the ref count*/
if(profile->refCount > 0){
profile->refCount--;
}
- umtx_unlock(usprepMutex());
+ umtx_unlock(&usprepMutex);
}
diff --git a/deps/icu-small/source/common/ustr_titlecase_brkiter.cpp b/deps/icu-small/source/common/ustr_titlecase_brkiter.cpp
index 056b40eb41..457905eb60 100644
--- a/deps/icu-small/source/common/ustr_titlecase_brkiter.cpp
+++ b/deps/icu-small/source/common/ustr_titlecase_brkiter.cpp
@@ -45,7 +45,7 @@ public:
WholeStringBreakIterator() : BreakIterator(), length(0) {}
~WholeStringBreakIterator() U_OVERRIDE;
UBool operator==(const BreakIterator&) const U_OVERRIDE;
- BreakIterator *clone() const U_OVERRIDE;
+ WholeStringBreakIterator *clone() const U_OVERRIDE;
static UClassID U_EXPORT2 getStaticClassID();
UClassID getDynamicClassID() const U_OVERRIDE;
CharacterIterator &getText() const U_OVERRIDE;
@@ -62,9 +62,9 @@ public:
int32_t preceding(int32_t offset) U_OVERRIDE;
UBool isBoundary(int32_t offset) U_OVERRIDE;
int32_t next(int32_t n) U_OVERRIDE;
- BreakIterator *createBufferClone(void *stackBuffer, int32_t &BufferSize,
- UErrorCode &errorCode) U_OVERRIDE;
- BreakIterator &refreshInputText(UText *input, UErrorCode &errorCode) U_OVERRIDE;
+ WholeStringBreakIterator *createBufferClone(void *stackBuffer, int32_t &BufferSize,
+ UErrorCode &errorCode) U_OVERRIDE;
+ WholeStringBreakIterator &refreshInputText(UText *input, UErrorCode &errorCode) U_OVERRIDE;
private:
int32_t length;
@@ -74,7 +74,7 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(WholeStringBreakIterator)
WholeStringBreakIterator::~WholeStringBreakIterator() {}
UBool WholeStringBreakIterator::operator==(const BreakIterator&) const { return FALSE; }
-BreakIterator *WholeStringBreakIterator::clone() const { return nullptr; }
+WholeStringBreakIterator *WholeStringBreakIterator::clone() const { return nullptr; }
CharacterIterator &WholeStringBreakIterator::getText() const {
UPRV_UNREACHABLE; // really should not be called
@@ -113,14 +113,14 @@ int32_t WholeStringBreakIterator::preceding(int32_t /*offset*/) { return 0; }
UBool WholeStringBreakIterator::isBoundary(int32_t /*offset*/) { return FALSE; }
int32_t WholeStringBreakIterator::next(int32_t /*n*/) { return length; }
-BreakIterator *WholeStringBreakIterator::createBufferClone(
+WholeStringBreakIterator *WholeStringBreakIterator::createBufferClone(
void * /*stackBuffer*/, int32_t & /*BufferSize*/, UErrorCode &errorCode) {
if (U_SUCCESS(errorCode)) {
errorCode = U_UNSUPPORTED_ERROR;
}
return nullptr;
}
-BreakIterator &WholeStringBreakIterator::refreshInputText(
+WholeStringBreakIterator &WholeStringBreakIterator::refreshInputText(
UText * /*input*/, UErrorCode &errorCode) {
if (U_SUCCESS(errorCode)) {
errorCode = U_UNSUPPORTED_ERROR;
diff --git a/deps/icu-small/source/common/ustring.cpp b/deps/icu-small/source/common/ustring.cpp
index a1a51f4b1e..6886c145d9 100644
--- a/deps/icu-small/source/common/ustring.cpp
+++ b/deps/icu-small/source/common/ustring.cpp
@@ -1428,7 +1428,7 @@ u_unescape(const char *src, UChar *dest, int32_t destCapacity) {
* NUL-terminate a string no matter what its type.
* Set warning and error codes accordingly.
*/
-#define __TERMINATE_STRING(dest, destCapacity, length, pErrorCode) \
+#define __TERMINATE_STRING(dest, destCapacity, length, pErrorCode) UPRV_BLOCK_MACRO_BEGIN { \
if(pErrorCode!=NULL && U_SUCCESS(*pErrorCode)) { \
/* not a public function, so no complete argument checking */ \
\
@@ -1448,7 +1448,8 @@ u_unescape(const char *src, UChar *dest, int32_t destCapacity) {
/* even the string itself did not fit - set an error code */ \
*pErrorCode=U_BUFFER_OVERFLOW_ERROR; \
} \
- }
+ } \
+} UPRV_BLOCK_MACRO_END
U_CAPI int32_t U_EXPORT2
u_terminateUChars(UChar *dest, int32_t destCapacity, int32_t length, UErrorCode *pErrorCode) {
@@ -1488,7 +1489,7 @@ u_terminateWChars(wchar_t *dest, int32_t destCapacity, int32_t length, UErrorCod
the output range. [LIU]
*/
-#define STRING_HASH(TYPE, STR, STRLEN, DEREF) \
+#define STRING_HASH(TYPE, STR, STRLEN, DEREF) UPRV_BLOCK_MACRO_BEGIN { \
uint32_t hash = 0; \
const TYPE *p = (const TYPE*) STR; \
if (p != NULL) { \
@@ -1500,7 +1501,8 @@ u_terminateWChars(wchar_t *dest, int32_t destCapacity, int32_t length, UErrorCod
p += inc; \
} \
} \
- return static_cast<int32_t>(hash)
+ return static_cast<int32_t>(hash); \
+} UPRV_BLOCK_MACRO_END
/* Used by UnicodeString to compute its hashcode - Not public API. */
U_CAPI int32_t U_EXPORT2
diff --git a/deps/icu-small/source/common/utext.cpp b/deps/icu-small/source/common/utext.cpp
index 5e3a005626..324341f1ba 100644
--- a/deps/icu-small/source/common/utext.cpp
+++ b/deps/icu-small/source/common/utext.cpp
@@ -567,7 +567,7 @@ enum {
struct ExtendedUText {
UText ut;
- UAlignedMemory extension;
+ max_align_t extension;
};
static const UText emptyText = UTEXT_INITIALIZER;
@@ -582,7 +582,7 @@ utext_setup(UText *ut, int32_t extraSpace, UErrorCode *status) {
// We need to heap-allocate storage for the new UText
int32_t spaceRequired = sizeof(UText);
if (extraSpace > 0) {
- spaceRequired = sizeof(ExtendedUText) + extraSpace - sizeof(UAlignedMemory);
+ spaceRequired = sizeof(ExtendedUText) + extraSpace - sizeof(max_align_t);
}
ut = (UText *)uprv_malloc(spaceRequired);
if (ut == NULL) {
diff --git a/deps/icu-small/source/common/util.cpp b/deps/icu-small/source/common/util.cpp
index 838a201a73..56dd4f1bfa 100644
--- a/deps/icu-small/source/common/util.cpp
+++ b/deps/icu-small/source/common/util.cpp
@@ -276,6 +276,16 @@ int32_t ICU_Utility::parsePattern(const UnicodeString& pat,
return -1; // text ended before end of pat
}
+int32_t ICU_Utility::parseAsciiInteger(const UnicodeString& str, int32_t& pos) {
+ int32_t result = 0;
+ UChar c;
+ while (pos < str.length() && (c = str.charAt(pos)) >= u'0' && c <= u'9') {
+ result = result * 10 + (c - u'0');
+ pos++;
+ }
+ return result;
+}
+
/**
* Append a character to a rule that is being built up. To flush
* the quoteBuf to rule, make one final call with isLiteral == TRUE.
diff --git a/deps/icu-small/source/common/util.h b/deps/icu-small/source/common/util.h
index 92cdc9ef69..a2be25056e 100644
--- a/deps/icu-small/source/common/util.h
+++ b/deps/icu-small/source/common/util.h
@@ -179,13 +179,22 @@ class U_COMMON_API ICU_Utility /* not : public UObject because all methods are s
* Parse an integer at pos, either of the form \d+ or of the form
* 0x[0-9A-Fa-f]+ or 0[0-7]+, that is, in standard decimal, hex,
* or octal format.
- * @param pos INPUT-OUTPUT parameter. On input, the first
- * character to parse. On output, the character after the last
- * parsed character.
+ * @param pos INPUT-OUTPUT parameter. On input, the index of the first
+ * character to parse. On output, the index of the character after the
+ * last parsed character.
*/
static int32_t parseInteger(const UnicodeString& rule, int32_t& pos, int32_t limit);
/**
+ * Parse an integer at pos using only ASCII digits.
+ * Base 10 only.
+ * @param pos INPUT-OUTPUT parameter. On input, the index of the first
+ * character to parse. On output, the index of the character after the
+ * last parsed character.
+ */
+ static int32_t parseAsciiInteger(const UnicodeString& str, int32_t& pos);
+
+ /**
* Parse a Unicode identifier from the given string at the given
* position. Return the identifier, or an empty string if there
* is no identifier.
diff --git a/deps/icu-small/source/common/utrace.cpp b/deps/icu-small/source/common/utrace.cpp
index 01bdb38e90..04488d06a0 100644
--- a/deps/icu-small/source/common/utrace.cpp
+++ b/deps/icu-small/source/common/utrace.cpp
@@ -477,6 +477,16 @@ trCollNames[] = {
};
+static const char* const
+trResDataNames[] = {
+ "resc",
+ "bundle-open",
+ "file-open",
+ "res-open",
+ NULL
+};
+
+
U_CAPI const char * U_EXPORT2
utrace_functionName(int32_t fnNumber) {
if(UTRACE_FUNCTION_START <= fnNumber && fnNumber < UTRACE_FUNCTION_LIMIT) {
@@ -485,6 +495,8 @@ utrace_functionName(int32_t fnNumber) {
return trConvNames[fnNumber - UTRACE_CONVERSION_START];
} else if(UTRACE_COLLATION_START <= fnNumber && fnNumber < UTRACE_COLLATION_LIMIT){
return trCollNames[fnNumber - UTRACE_COLLATION_START];
+ } else if(UTRACE_UDATA_START <= fnNumber && fnNumber < UTRACE_RES_DATA_LIMIT){
+ return trResDataNames[fnNumber - UTRACE_UDATA_START];
} else {
return "[BOGUS Trace Function Number]";
}
diff --git a/deps/icu-small/source/common/utracimp.h b/deps/icu-small/source/common/utracimp.h
index c2819830e1..84e7031da8 100644
--- a/deps/icu-small/source/common/utracimp.h
+++ b/deps/icu-small/source/common/utracimp.h
@@ -144,10 +144,12 @@ U_CDECL_END
*/
#define UTRACE_ENTRY(fnNumber) \
int32_t utraceFnNumber=(fnNumber); \
+UPRV_BLOCK_MACRO_BEGIN { \
if(utrace_getLevel()>=UTRACE_INFO) { \
utrace_entry(fnNumber); \
utraceFnNumber |= UTRACE_TRACED_ENTRY; \
- }
+ } \
+} UPRV_BLOCK_MACRO_END
/**
@@ -162,10 +164,12 @@ U_CDECL_END
*/
#define UTRACE_ENTRY_OC(fnNumber) \
int32_t utraceFnNumber=(fnNumber); \
+UPRV_BLOCK_MACRO_BEGIN { \
if(utrace_getLevel()>=UTRACE_OPEN_CLOSE) { \
utrace_entry(fnNumber); \
utraceFnNumber |= UTRACE_TRACED_ENTRY; \
- }
+ } \
+} UPRV_BLOCK_MACRO_END
/**
* Trace statement for each exit point of a function that has a UTRACE_ENTRY()
@@ -179,10 +183,11 @@ U_CDECL_END
*
* @internal
*/
-#define UTRACE_EXIT() \
- {if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
+#define UTRACE_EXIT() UPRV_BLOCK_MACRO_BEGIN { \
+ if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
utrace_exit(utraceFnNumber & ~UTRACE_TRACED_ENTRY, UTRACE_EXITV_NONE); \
- }}
+ } \
+} UPRV_BLOCK_MACRO_END
/**
* Trace statement for each exit point of a function that has a UTRACE_ENTRY()
@@ -192,25 +197,29 @@ U_CDECL_END
*
* @internal
*/
-#define UTRACE_EXIT_VALUE(val) \
- {if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
+#define UTRACE_EXIT_VALUE(val) UPRV_BLOCK_MACRO_BEGIN { \
+ if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
utrace_exit(utraceFnNumber & ~UTRACE_TRACED_ENTRY, UTRACE_EXITV_I32, val); \
- }}
+ } \
+} UPRV_BLOCK_MACRO_END
-#define UTRACE_EXIT_STATUS(status) \
- {if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
+#define UTRACE_EXIT_STATUS(status) UPRV_BLOCK_MACRO_BEGIN { \
+ if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
utrace_exit(utraceFnNumber & ~UTRACE_TRACED_ENTRY, UTRACE_EXITV_STATUS, status); \
- }}
+ } \
+} UPRV_BLOCK_MACRO_END
-#define UTRACE_EXIT_VALUE_STATUS(val, status) \
- {if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
+#define UTRACE_EXIT_VALUE_STATUS(val, status) UPRV_BLOCK_MACRO_BEGIN { \
+ if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
utrace_exit(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (UTRACE_EXITV_I32 | UTRACE_EXITV_STATUS), val, status); \
- }}
+ } \
+} UPRV_BLOCK_MACRO_END
-#define UTRACE_EXIT_PTR_STATUS(ptr, status) \
- {if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
+#define UTRACE_EXIT_PTR_STATUS(ptr, status) UPRV_BLOCK_MACRO_BEGIN { \
+ if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \
utrace_exit(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (UTRACE_EXITV_PTR | UTRACE_EXITV_STATUS), ptr, status); \
- }}
+ } \
+} UPRV_BLOCK_MACRO_END
/**
* Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -220,10 +229,11 @@ U_CDECL_END
* Calls utrace_data() if the level is high enough.
* @internal
*/
-#define UTRACE_DATA0(level, fmt) \
+#define UTRACE_DATA0(level, fmt) UPRV_BLOCK_MACRO_BEGIN { \
if(UTRACE_LEVEL(level)) { \
utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt)); \
- }
+ } \
+} UPRV_BLOCK_MACRO_END
/**
* Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -233,10 +243,11 @@ U_CDECL_END
* Calls utrace_data() if the level is high enough.
* @internal
*/
-#define UTRACE_DATA1(level, fmt, a) \
+#define UTRACE_DATA1(level, fmt, a) UPRV_BLOCK_MACRO_BEGIN { \
if(UTRACE_LEVEL(level)) { \
utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY , (level), (fmt), (a)); \
- }
+ } \
+} UPRV_BLOCK_MACRO_END
/**
* Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -246,10 +257,11 @@ U_CDECL_END
* Calls utrace_data() if the level is high enough.
* @internal
*/
-#define UTRACE_DATA2(level, fmt, a, b) \
+#define UTRACE_DATA2(level, fmt, a, b) UPRV_BLOCK_MACRO_BEGIN { \
if(UTRACE_LEVEL(level)) { \
utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY , (level), (fmt), (a), (b)); \
- }
+ } \
+} UPRV_BLOCK_MACRO_END
/**
* Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -259,10 +271,11 @@ U_CDECL_END
* Calls utrace_data() if the level is high enough.
* @internal
*/
-#define UTRACE_DATA3(level, fmt, a, b, c) \
+#define UTRACE_DATA3(level, fmt, a, b, c) UPRV_BLOCK_MACRO_BEGIN { \
if(UTRACE_LEVEL(level)) { \
utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a), (b), (c)); \
- }
+ } \
+} UPRV_BLOCK_MACRO_END
/**
* Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -272,10 +285,11 @@ U_CDECL_END
* Calls utrace_data() if the level is high enough.
* @internal
*/
-#define UTRACE_DATA4(level, fmt, a, b, c, d) \
+#define UTRACE_DATA4(level, fmt, a, b, c, d) UPRV_BLOCK_MACRO_BEGIN { \
if(UTRACE_LEVEL(level)) { \
utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a), (b), (c), (d)); \
- }
+ } \
+} UPRV_BLOCK_MACRO_END
/**
* Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -285,10 +299,11 @@ U_CDECL_END
* Calls utrace_data() if the level is high enough.
* @internal
*/
-#define UTRACE_DATA5(level, fmt, a, b, c, d, e) \
+#define UTRACE_DATA5(level, fmt, a, b, c, d, e) UPRV_BLOCK_MACRO_BEGIN { \
if(UTRACE_LEVEL(level)) { \
utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a), (b), (c), (d), (e)); \
- }
+ } \
+} UPRV_BLOCK_MACRO_END
/**
* Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -298,10 +313,11 @@ U_CDECL_END
* Calls utrace_data() if the level is high enough.
* @internal
*/
-#define UTRACE_DATA6(level, fmt, a, b, c, d, e, f) \
+#define UTRACE_DATA6(level, fmt, a, b, c, d, e, f) UPRV_BLOCK_MACRO_BEGIN { \
if(UTRACE_LEVEL(level)) { \
utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a), (b), (c), (d), (e), (f)); \
- }
+ } \
+} UPRV_BLOCK_MACRO_END
/**
* Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -311,10 +327,11 @@ U_CDECL_END
* Calls utrace_data() if the level is high enough.
* @internal
*/
-#define UTRACE_DATA7(level, fmt, a, b, c, d, e, f, g) \
+#define UTRACE_DATA7(level, fmt, a, b, c, d, e, f, g) UPRV_BLOCK_MACRO_BEGIN { \
if(UTRACE_LEVEL(level)) { \
utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a), (b), (c), (d), (e), (f), (g)); \
- }
+ } \
+} UPRV_BLOCK_MACRO_END
/**
* Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -324,10 +341,11 @@ U_CDECL_END
* Calls utrace_data() if the level is high enough.
* @internal
*/
-#define UTRACE_DATA8(level, fmt, a, b, c, d, e, f, g, h) \
+#define UTRACE_DATA8(level, fmt, a, b, c, d, e, f, g, h) UPRV_BLOCK_MACRO_BEGIN { \
if(UTRACE_LEVEL(level)) { \
utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a), (b), (c), (d), (e), (f), (g), (h)); \
- }
+ } \
+} UPRV_BLOCK_MACRO_END
/**
* Trace statement used inside functions that have a UTRACE_ENTRY() statement.
@@ -337,10 +355,11 @@ U_CDECL_END
* Calls utrace_data() if the level is high enough.
* @internal
*/
-#define UTRACE_DATA9(level, fmt, a, b, c, d, e, f, g, h, i) \
+#define UTRACE_DATA9(level, fmt, a, b, c, d, e, f, g, h, i) UPRV_BLOCK_MACRO_BEGIN { \
if(UTRACE_LEVEL(level)) { \
utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a), (b), (c), (d), (e), (f), (g), (h), (i)); \
- }
+ } \
+} UPRV_BLOCK_MACRO_END
#else
diff --git a/deps/icu-small/source/common/utrie.h b/deps/icu-small/source/common/utrie.h
index 3e2197eda6..532ba778eb 100644
--- a/deps/icu-small/source/common/utrie.h
+++ b/deps/icu-small/source/common/utrie.h
@@ -182,7 +182,7 @@ typedef struct UTrie UTrie;
]
/** Internal trie getter from a pair of surrogates */
-#define _UTRIE_GET_FROM_PAIR(trie, data, c, c2, result, resultType) { \
+#define _UTRIE_GET_FROM_PAIR(trie, data, c, c2, result, resultType) UPRV_BLOCK_MACRO_BEGIN { \
int32_t __offset; \
\
/* get data for lead surrogate */ \
@@ -195,18 +195,18 @@ typedef struct UTrie UTrie;
} else { \
(result)=(resultType)((trie)->initialValue); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** Internal trie getter from a BMP code point, treating a lead surrogate as a normal code point */
#define _UTRIE_GET_FROM_BMP(trie, data, c16) \
- _UTRIE_GET_RAW(trie, data, 0xd800<=(c16) && (c16)<=0xdbff ? UTRIE_LEAD_INDEX_DISP : 0, c16);
+ _UTRIE_GET_RAW(trie, data, 0xd800<=(c16) && (c16)<=0xdbff ? UTRIE_LEAD_INDEX_DISP : 0, c16)
/**
* Internal trie getter from a code point.
* Could be faster(?) but longer with
* if((c32)<=0xd7ff) { (result)=_UTRIE_GET_RAW(trie, data, 0, c32); }
*/
-#define _UTRIE_GET(trie, data, c32, result, resultType) \
+#define _UTRIE_GET(trie, data, c32, result, resultType) UPRV_BLOCK_MACRO_BEGIN { \
if((uint32_t)(c32)<=0xffff) { \
/* BMP code points */ \
(result)=_UTRIE_GET_FROM_BMP(trie, data, c32); \
@@ -217,10 +217,11 @@ typedef struct UTrie UTrie;
} else { \
/* out of range */ \
(result)=(resultType)((trie)->initialValue); \
- }
+ } \
+} UPRV_BLOCK_MACRO_END
/** Internal next-post-increment: get the next code point (c, c2) and its data */
-#define _UTRIE_NEXT(trie, data, src, limit, c, c2, result, resultType) { \
+#define _UTRIE_NEXT(trie, data, src, limit, c, c2, result, resultType) UPRV_BLOCK_MACRO_BEGIN { \
(c)=*(src)++; \
if(!U16_IS_LEAD(c)) { \
(c2)=0; \
@@ -233,10 +234,10 @@ typedef struct UTrie UTrie;
(c2)=0; \
(result)=_UTRIE_GET_RAW((trie), data, UTRIE_LEAD_INDEX_DISP, (c)); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** Internal previous: get the previous code point (c, c2) and its data */
-#define _UTRIE_PREVIOUS(trie, data, start, src, c, c2, result, resultType) { \
+#define _UTRIE_PREVIOUS(trie, data, start, src, c, c2, result, resultType) UPRV_BLOCK_MACRO_BEGIN { \
(c)=*--(src); \
if(!U16_IS_SURROGATE(c)) { \
(c2)=0; \
@@ -257,7 +258,7 @@ typedef struct UTrie UTrie;
(c2)=0; \
(result)=_UTRIE_GET_RAW((trie), data, UTRIE_LEAD_INDEX_DISP, (c)); \
} \
-}
+} UPRV_BLOCK_MACRO_END
/* Public UTrie API ---------------------------------------------------------*/
diff --git a/deps/icu-small/source/common/utrie2.h b/deps/icu-small/source/common/utrie2.h
index 75028ee23a..671f44e16a 100644
--- a/deps/icu-small/source/common/utrie2.h
+++ b/deps/icu-small/source/common/utrie2.h
@@ -871,7 +871,7 @@ utrie2_internalU8PrevIndex(const UTrie2 *trie, UChar32 c,
(trie)->data[_UTRIE2_INDEX_FROM_CP(trie, asciiOffset, c)]
/** Internal next-post-increment: get the next code point (c) and its data. */
-#define _UTRIE2_U16_NEXT(trie, data, src, limit, c, result) { \
+#define _UTRIE2_U16_NEXT(trie, data, src, limit, c, result) UPRV_BLOCK_MACRO_BEGIN { \
{ \
uint16_t __c2; \
(c)=*(src)++; \
@@ -885,10 +885,10 @@ utrie2_internalU8PrevIndex(const UTrie2 *trie, UChar32 c,
(result)=_UTRIE2_GET_FROM_SUPP((trie), data, (c)); \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** Internal pre-decrement-previous: get the previous code point (c) and its data */
-#define _UTRIE2_U16_PREV(trie, data, start, src, c, result) { \
+#define _UTRIE2_U16_PREV(trie, data, start, src, c, result) UPRV_BLOCK_MACRO_BEGIN { \
{ \
uint16_t __c2; \
(c)=*--(src); \
@@ -900,10 +900,10 @@ utrie2_internalU8PrevIndex(const UTrie2 *trie, UChar32 c,
(result)=_UTRIE2_GET_FROM_SUPP((trie), data, (c)); \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** Internal UTF-8 next-post-increment: get the next code point's data. */
-#define _UTRIE2_U8_NEXT(trie, ascii, data, src, limit, result) { \
+#define _UTRIE2_U8_NEXT(trie, ascii, data, src, limit, result) UPRV_BLOCK_MACRO_BEGIN { \
uint8_t __lead=(uint8_t)*(src)++; \
if(U8_IS_SINGLE(__lead)) { \
(result)=(trie)->ascii[__lead]; \
@@ -935,10 +935,10 @@ utrie2_internalU8PrevIndex(const UTrie2 *trie, UChar32 c,
(result)=(trie)->data[__index>>3]; \
} \
} \
-}
+} UPRV_BLOCK_MACRO_END
/** Internal UTF-8 pre-decrement-previous: get the previous code point's data. */
-#define _UTRIE2_U8_PREV(trie, ascii, data, start, src, result) { \
+#define _UTRIE2_U8_PREV(trie, ascii, data, start, src, result) UPRV_BLOCK_MACRO_BEGIN { \
uint8_t __b=(uint8_t)*--(src); \
if(U8_IS_SINGLE(__b)) { \
(result)=(trie)->ascii[__b]; \
@@ -948,7 +948,7 @@ utrie2_internalU8PrevIndex(const UTrie2 *trie, UChar32 c,
(src)-=__index&7; \
(result)=(trie)->data[__index>>3]; \
} \
-}
+} UPRV_BLOCK_MACRO_END
U_CDECL_END
diff --git a/deps/icu-small/source/data/in/icudt64l.dat.bz2 b/deps/icu-small/source/data/in/icudt65l.dat.bz2
index 962fe59750..f55e9252f6 100644
--- a/deps/icu-small/source/data/in/icudt64l.dat.bz2
+++ b/deps/icu-small/source/data/in/icudt65l.dat.bz2
Binary files differ
diff --git a/deps/icu-small/source/i18n/alphaindex.cpp b/deps/icu-small/source/i18n/alphaindex.cpp
index 99f70114cb..532e337383 100644
--- a/deps/icu-small/source/i18n/alphaindex.cpp
+++ b/deps/icu-small/source/i18n/alphaindex.cpp
@@ -260,8 +260,7 @@ AlphabeticIndex::ImmutableIndex *AlphabeticIndex::buildImmutableIndex(UErrorCode
// but that would be worth it only if this method is called multiple times,
// or called after using the old-style bucket iterator API.
LocalPointer<BucketList> immutableBucketList(createBucketList(errorCode));
- LocalPointer<RuleBasedCollator> coll(
- static_cast<RuleBasedCollator *>(collatorPrimaryOnly_->clone()));
+ LocalPointer<RuleBasedCollator> coll(collatorPrimaryOnly_->clone());
if (immutableBucketList.isNull() || coll.isNull()) {
errorCode = U_MEMORY_ALLOCATION_ERROR;
return NULL;
@@ -907,7 +906,7 @@ void AlphabeticIndex::init(const Locale *locale, UErrorCode &status) {
return;
}
}
- collatorPrimaryOnly_ = static_cast<RuleBasedCollator *>(collator_->clone());
+ collatorPrimaryOnly_ = collator_->clone();
if (collatorPrimaryOnly_ == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
return;
@@ -958,7 +957,7 @@ collatorComparator(const void *context, const void *left, const void *right) {
}
if (leftString == NULL) {
return 1;
- };
+ }
if (rightString == NULL) {
return -1;
}
diff --git a/deps/icu-small/source/i18n/anytrans.cpp b/deps/icu-small/source/i18n/anytrans.cpp
index 6e382b824b..167b018528 100644
--- a/deps/icu-small/source/i18n/anytrans.cpp
+++ b/deps/icu-small/source/i18n/anytrans.cpp
@@ -226,7 +226,7 @@ AnyTransliterator::AnyTransliterator(const AnyTransliterator& o) :
/**
* Transliterator API.
*/
-Transliterator* AnyTransliterator::clone() const {
+AnyTransliterator* AnyTransliterator::clone() const {
return new AnyTransliterator(*this);
}
diff --git a/deps/icu-small/source/i18n/anytrans.h b/deps/icu-small/source/i18n/anytrans.h
index 703d42b6d4..627dee3c81 100644
--- a/deps/icu-small/source/i18n/anytrans.h
+++ b/deps/icu-small/source/i18n/anytrans.h
@@ -66,7 +66,7 @@ public:
/**
* Transliterator API.
*/
- virtual Transliterator* clone() const;
+ virtual AnyTransliterator* clone() const;
/**
* Implements {@link Transliterator#handleTransliterate}.
diff --git a/deps/icu-small/source/i18n/astro.cpp b/deps/icu-small/source/i18n/astro.cpp
index 0d521b037d..d28e516472 100644
--- a/deps/icu-small/source/i18n/astro.cpp
+++ b/deps/icu-small/source/i18n/astro.cpp
@@ -65,10 +65,7 @@ static inline UBool isINVALID(double d) {
return(uprv_isNaN(d));
}
-static icu::UMutex *ccLock() {
- static icu::UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static icu::UMutex ccLock;
U_CDECL_BEGIN
static UBool calendar_astro_cleanup(void) {
@@ -1552,12 +1549,12 @@ int32_t CalendarCache::get(CalendarCache** cache, int32_t key, UErrorCode &statu
if(U_FAILURE(status)) {
return 0;
}
- umtx_lock(ccLock());
+ umtx_lock(&ccLock);
if(*cache == NULL) {
createCache(cache, status);
if(U_FAILURE(status)) {
- umtx_unlock(ccLock());
+ umtx_unlock(&ccLock);
return 0;
}
}
@@ -1565,7 +1562,7 @@ int32_t CalendarCache::get(CalendarCache** cache, int32_t key, UErrorCode &statu
res = uhash_igeti((*cache)->fTable, key);
U_DEBUG_ASTRO_MSG(("%p: GET: [%d] == %d\n", (*cache)->fTable, key, res));
- umtx_unlock(ccLock());
+ umtx_unlock(&ccLock);
return res;
}
@@ -1573,12 +1570,12 @@ void CalendarCache::put(CalendarCache** cache, int32_t key, int32_t value, UErro
if(U_FAILURE(status)) {
return;
}
- umtx_lock(ccLock());
+ umtx_lock(&ccLock);
if(*cache == NULL) {
createCache(cache, status);
if(U_FAILURE(status)) {
- umtx_unlock(ccLock());
+ umtx_unlock(&ccLock);
return;
}
}
@@ -1586,7 +1583,7 @@ void CalendarCache::put(CalendarCache** cache, int32_t key, int32_t value, UErro
uhash_iputi((*cache)->fTable, key, value, &status);
U_DEBUG_ASTRO_MSG(("%p: PUT: [%d] := %d\n", (*cache)->fTable, key, value));
- umtx_unlock(ccLock());
+ umtx_unlock(&ccLock);
}
CalendarCache::CalendarCache(int32_t size, UErrorCode &status) {
diff --git a/deps/icu-small/source/i18n/bocsu.h b/deps/icu-small/source/i18n/bocsu.h
index 6b8ed51970..631e29aa76 100644
--- a/deps/icu-small/source/i18n/bocsu.h
+++ b/deps/icu-small/source/i18n/bocsu.h
@@ -144,14 +144,14 @@ U_NAMESPACE_END
* yields negative modulo results and quotients that are one more than
* what we need here.
*/
-#define NEGDIVMOD(n, d, m) { \
+#define NEGDIVMOD(n, d, m) UPRV_BLOCK_MACRO_BEGIN { \
(m)=(n)%(d); \
(n)/=(d); \
if((m)<0) { \
--(n); \
(m)+=(d); \
} \
-}
+} UPRV_BLOCK_MACRO_END
U_CFUNC UChar32
u_writeIdenticalLevelRun(UChar32 prev, const UChar *s, int32_t length, icu::ByteSink &sink);
diff --git a/deps/icu-small/source/i18n/brktrans.cpp b/deps/icu-small/source/i18n/brktrans.cpp
index ac9e2afb7e..46b0e345da 100644
--- a/deps/icu-small/source/i18n/brktrans.cpp
+++ b/deps/icu-small/source/i18n/brktrans.cpp
@@ -64,7 +64,7 @@ BreakTransliterator::BreakTransliterator(const BreakTransliterator& o) :
/**
* Transliterator API.
*/
-Transliterator* BreakTransliterator::clone(void) const {
+BreakTransliterator* BreakTransliterator::clone() const {
return new BreakTransliterator(*this);
}
diff --git a/deps/icu-small/source/i18n/brktrans.h b/deps/icu-small/source/i18n/brktrans.h
index fcc8bdd002..caa1e16ee6 100644
--- a/deps/icu-small/source/i18n/brktrans.h
+++ b/deps/icu-small/source/i18n/brktrans.h
@@ -54,7 +54,7 @@ public:
* Transliterator API.
* @return A copy of the object.
*/
- virtual Transliterator* clone(void) const;
+ virtual BreakTransliterator* clone() const;
virtual const UnicodeString &getInsertion() const;
diff --git a/deps/icu-small/source/i18n/buddhcal.cpp b/deps/icu-small/source/i18n/buddhcal.cpp
index b6ccbc4749..bddfd1768a 100644
--- a/deps/icu-small/source/i18n/buddhcal.cpp
+++ b/deps/icu-small/source/i18n/buddhcal.cpp
@@ -53,7 +53,7 @@ BuddhistCalendar& BuddhistCalendar::operator= ( const BuddhistCalendar& right)
return *this;
}
-Calendar* BuddhistCalendar::clone(void) const
+BuddhistCalendar* BuddhistCalendar::clone() const
{
return new BuddhistCalendar(*this);
}
@@ -133,7 +133,7 @@ void BuddhistCalendar::timeToFields(UDate theTime, UBool quick, UErrorCode& stat
*/
static UDate gSystemDefaultCenturyStart = DBL_MIN;
static int32_t gSystemDefaultCenturyStartYear = -1;
-static icu::UInitOnce gBCInitOnce;
+static icu::UInitOnce gBCInitOnce = U_INITONCE_INITIALIZER;
UBool BuddhistCalendar::haveDefaultCentury() const
diff --git a/deps/icu-small/source/i18n/buddhcal.h b/deps/icu-small/source/i18n/buddhcal.h
index 89e3f3dec3..c3ffa6a41d 100644
--- a/deps/icu-small/source/i18n/buddhcal.h
+++ b/deps/icu-small/source/i18n/buddhcal.h
@@ -94,7 +94,7 @@ public:
* @return return a polymorphic copy of this calendar.
* @internal
*/
- virtual Calendar* clone(void) const;
+ virtual BuddhistCalendar* clone() const;
public:
/**
diff --git a/deps/icu-small/source/i18n/calendar.cpp b/deps/icu-small/source/i18n/calendar.cpp
index 85a387ef49..9462546561 100644
--- a/deps/icu-small/source/i18n/calendar.cpp
+++ b/deps/icu-small/source/i18n/calendar.cpp
@@ -268,6 +268,8 @@ static ECalType getCalendarTypeForLocale(const char *locid) {
// canonicalize, so grandfathered variant will be transformed to keywords
// e.g ja_JP_TRADITIONAL -> ja_JP@calendar=japanese
+ // NOTE: Since ICU-20187, ja_JP_TRADITIONAL no longer canonicalizes, and
+ // the Gregorian calendar is returned instead.
int32_t canonicalLen = uloc_canonicalize(locid, canonicalName, sizeof(canonicalName) - 1, &status);
if (U_FAILURE(status)) {
return CALTYPE_GREGORIAN;
@@ -748,6 +750,7 @@ fSkippedWallTime(UCAL_WALLTIME_LAST)
validLocale[0] = 0;
actualLocale[0] = 0;
if (U_FAILURE(success)) {
+ delete zone;
return;
}
if(zone == 0) {
@@ -2592,7 +2595,7 @@ Calendar::isWeekend(UDate date, UErrorCode &status) const
return FALSE;
}
// clone the calendar so we don't mess with the real one.
- Calendar *work = (Calendar*)this->clone();
+ Calendar *work = this->clone();
if (work == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
return FALSE;
@@ -2752,7 +2755,7 @@ Calendar::getActualMinimum(UCalendarDateFields field, UErrorCode& status) const
// clone the calendar so we don't mess with the real one, and set it to
// accept anything for the field values
- Calendar *work = (Calendar*)this->clone();
+ Calendar *work = this->clone();
if (work == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
return 0;
diff --git a/deps/icu-small/source/i18n/casetrn.cpp b/deps/icu-small/source/i18n/casetrn.cpp
index f08d448881..06750b2983 100644
--- a/deps/icu-small/source/i18n/casetrn.cpp
+++ b/deps/icu-small/source/i18n/casetrn.cpp
@@ -125,7 +125,7 @@ CaseMapTransliterator::CaseMapTransliterator(const CaseMapTransliterator& o) :
/**
* Transliterator API.
*/
-/*Transliterator* CaseMapTransliterator::clone(void) const {
+/*CaseMapTransliterator* CaseMapTransliterator::clone() const {
return new CaseMapTransliterator(*this);
}*/
diff --git a/deps/icu-small/source/i18n/casetrn.h b/deps/icu-small/source/i18n/casetrn.h
index eee443fc81..47914022f8 100644
--- a/deps/icu-small/source/i18n/casetrn.h
+++ b/deps/icu-small/source/i18n/casetrn.h
@@ -58,7 +58,7 @@ public:
* Transliterator API.
* @return a copy of the object.
*/
- virtual Transliterator* clone(void) const = 0;
+ virtual CaseMapTransliterator* clone() const = 0;
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
diff --git a/deps/icu-small/source/i18n/chnsecal.cpp b/deps/icu-small/source/i18n/chnsecal.cpp
index 3c4ad2a846..2ff9f755af 100644
--- a/deps/icu-small/source/i18n/chnsecal.cpp
+++ b/deps/icu-small/source/i18n/chnsecal.cpp
@@ -51,10 +51,7 @@ static void debug_chnsecal_msg(const char *pat, ...)
// --- The cache --
-static icu::UMutex *astroLock() { // Protects access to gChineseCalendarAstro.
- static icu::UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static icu::UMutex astroLock;
static icu::CalendarAstronomer *gChineseCalendarAstro = NULL;
// Lazy Creation & Access synchronized by class CalendarCache with a mutex.
@@ -121,7 +118,7 @@ U_NAMESPACE_BEGIN
//-------------------------------------------------------------------------
-Calendar* ChineseCalendar::clone() const {
+ChineseCalendar* ChineseCalendar::clone() const {
return new ChineseCalendar(*this);
}
@@ -538,14 +535,14 @@ int32_t ChineseCalendar::winterSolstice(int32_t gyear) const {
// PST 1298 with a final result of Dec 14 10:31:59 PST 1299.
double ms = daysToMillis(Grego::fieldsToDay(gyear, UCAL_DECEMBER, 1));
- umtx_lock(astroLock());
+ umtx_lock(&astroLock);
if(gChineseCalendarAstro == NULL) {
gChineseCalendarAstro = new CalendarAstronomer();
ucln_i18n_registerCleanup(UCLN_I18N_CHINESE_CALENDAR, calendar_chinese_cleanup);
}
gChineseCalendarAstro->setTime(ms);
UDate solarLong = gChineseCalendarAstro->getSunTime(CalendarAstronomer::WINTER_SOLSTICE(), TRUE);
- umtx_unlock(astroLock());
+ umtx_unlock(&astroLock);
// Winter solstice is 270 degrees solar longitude aka Dongzhi
cacheValue = (int32_t)millisToDays(solarLong);
@@ -568,14 +565,14 @@ int32_t ChineseCalendar::winterSolstice(int32_t gyear) const {
*/
int32_t ChineseCalendar::newMoonNear(double days, UBool after) const {
- umtx_lock(astroLock());
+ umtx_lock(&astroLock);
if(gChineseCalendarAstro == NULL) {
gChineseCalendarAstro = new CalendarAstronomer();
ucln_i18n_registerCleanup(UCLN_I18N_CHINESE_CALENDAR, calendar_chinese_cleanup);
}
gChineseCalendarAstro->setTime(daysToMillis(days));
UDate newMoon = gChineseCalendarAstro->getMoonTime(CalendarAstronomer::NEW_MOON(), after);
- umtx_unlock(astroLock());
+ umtx_unlock(&astroLock);
return (int32_t) millisToDays(newMoon);
}
@@ -600,14 +597,14 @@ int32_t ChineseCalendar::synodicMonthsBetween(int32_t day1, int32_t day2) const
*/
int32_t ChineseCalendar::majorSolarTerm(int32_t days) const {
- umtx_lock(astroLock());
+ umtx_lock(&astroLock);
if(gChineseCalendarAstro == NULL) {
gChineseCalendarAstro = new CalendarAstronomer();
ucln_i18n_registerCleanup(UCLN_I18N_CHINESE_CALENDAR, calendar_chinese_cleanup);
}
gChineseCalendarAstro->setTime(daysToMillis(days));
UDate solarLongitude = gChineseCalendarAstro->getSunLongitude();
- umtx_unlock(astroLock());
+ umtx_unlock(&astroLock);
// Compute (floor(solarLongitude / (pi/6)) + 2) % 12
int32_t term = ( ((int32_t)(6 * solarLongitude / CalendarAstronomer::PI)) + 2 ) % 12;
diff --git a/deps/icu-small/source/i18n/chnsecal.h b/deps/icu-small/source/i18n/chnsecal.h
index 1b27d2d1bc..c7c0637381 100644
--- a/deps/icu-small/source/i18n/chnsecal.h
+++ b/deps/icu-small/source/i18n/chnsecal.h
@@ -144,7 +144,7 @@ class U_I18N_API ChineseCalendar : public Calendar {
virtual ~ChineseCalendar();
// clone
- virtual Calendar* clone() const;
+ virtual ChineseCalendar* clone() const;
private:
diff --git a/deps/icu-small/source/i18n/choicfmt.cpp b/deps/icu-small/source/i18n/choicfmt.cpp
index 1b846704bf..16880706d3 100644
--- a/deps/icu-small/source/i18n/choicfmt.cpp
+++ b/deps/icu-small/source/i18n/choicfmt.cpp
@@ -563,7 +563,7 @@ ChoiceFormat::matchStringUntilLimitPart(
// -------------------------------------
-Format*
+ChoiceFormat*
ChoiceFormat::clone() const
{
ChoiceFormat *aCopy = new ChoiceFormat(*this);
diff --git a/deps/icu-small/source/i18n/coll.cpp b/deps/icu-small/source/i18n/coll.cpp
index 8bbe133664..984831e761 100644
--- a/deps/icu-small/source/i18n/coll.cpp
+++ b/deps/icu-small/source/i18n/coll.cpp
@@ -67,7 +67,7 @@ static int32_t availableLocaleListCount;
static icu::ICULocaleService* gService = NULL;
static icu::UInitOnce gServiceInitOnce = U_INITONCE_INITIALIZER;
#endif
-static icu::UInitOnce gAvailableLocaleListInitOnce;
+static icu::UInitOnce gAvailableLocaleListInitOnce = U_INITONCE_INITIALIZER;
/**
* Release all static memory held by collator.
diff --git a/deps/icu-small/source/i18n/collationiterator.cpp b/deps/icu-small/source/i18n/collationiterator.cpp
index 961c9e9ace..18ccf014f0 100644
--- a/deps/icu-small/source/i18n/collationiterator.cpp
+++ b/deps/icu-small/source/i18n/collationiterator.cpp
@@ -872,7 +872,7 @@ CollationIterator::previousCE(UVector32 &offsets, UErrorCode &errorCode) {
// consistent with forward iteration.
while(offsets.size() <= ceBuffer.length) {
offsets.addElement(limitOffset, errorCode);
- };
+ }
}
return ceBuffer.get(--ceBuffer.length);
} else {
@@ -932,7 +932,7 @@ CollationIterator::previousCEUnsafe(UChar32 c, UVector32 &offsets, UErrorCode &e
offset = getOffset();
while(offsets.size() < ceBuffer.length) {
offsets.addElement(offset, errorCode);
- };
+ }
}
U_ASSERT(offsets.size() == ceBuffer.length);
// End offset corresponding to just after the unsafe-backwards segment.
diff --git a/deps/icu-small/source/i18n/compactdecimalformat.cpp b/deps/icu-small/source/i18n/compactdecimalformat.cpp
index 4dd2241b23..a4c9dad25c 100644
--- a/deps/icu-small/source/i18n/compactdecimalformat.cpp
+++ b/deps/icu-small/source/i18n/compactdecimalformat.cpp
@@ -30,9 +30,9 @@ CompactDecimalFormat::CompactDecimalFormat(const Locale& inLocale, UNumberCompac
: DecimalFormat(new DecimalFormatSymbols(inLocale, status), status) {
if (U_FAILURE(status)) return;
// Minimal properties: let the non-shim code path do most of the logic for us.
- fields->properties->compactStyle = style;
- fields->properties->groupingSize = -2; // do not forward grouping information
- fields->properties->minimumGroupingDigits = 2;
+ fields->properties.compactStyle = style;
+ fields->properties.groupingSize = -2; // do not forward grouping information
+ fields->properties.minimumGroupingDigits = 2;
touch(status);
}
@@ -45,7 +45,7 @@ CompactDecimalFormat& CompactDecimalFormat::operator=(const CompactDecimalFormat
return *this;
}
-Format* CompactDecimalFormat::clone() const {
+CompactDecimalFormat* CompactDecimalFormat::clone() const {
return new CompactDecimalFormat(*this);
}
diff --git a/deps/icu-small/source/i18n/coptccal.cpp b/deps/icu-small/source/i18n/coptccal.cpp
index 39691217d0..229119bf16 100644
--- a/deps/icu-small/source/i18n/coptccal.cpp
+++ b/deps/icu-small/source/i18n/coptccal.cpp
@@ -40,7 +40,7 @@ CopticCalendar::~CopticCalendar()
{
}
-Calendar*
+CopticCalendar*
CopticCalendar::clone() const
{
return new CopticCalendar(*this);
diff --git a/deps/icu-small/source/i18n/coptccal.h b/deps/icu-small/source/i18n/coptccal.h
index 0b82c36088..dc2d79c89e 100644
--- a/deps/icu-small/source/i18n/coptccal.h
+++ b/deps/icu-small/source/i18n/coptccal.h
@@ -145,7 +145,7 @@ public:
* @return return a polymorphic copy of this calendar.
* @internal
*/
- virtual Calendar* clone(void) const;
+ virtual CopticCalendar* clone() const;
/**
* return the calendar type, "coptic"
diff --git a/deps/icu-small/source/i18n/cpdtrans.cpp b/deps/icu-small/source/i18n/cpdtrans.cpp
index a204de5a53..624ae431d3 100644
--- a/deps/icu-small/source/i18n/cpdtrans.cpp
+++ b/deps/icu-small/source/i18n/cpdtrans.cpp
@@ -323,7 +323,7 @@ CompoundTransliterator& CompoundTransliterator::operator=(
/**
* Transliterator API.
*/
-Transliterator* CompoundTransliterator::clone(void) const {
+CompoundTransliterator* CompoundTransliterator::clone() const {
return new CompoundTransliterator(*this);
}
diff --git a/deps/icu-small/source/i18n/cpdtrans.h b/deps/icu-small/source/i18n/cpdtrans.h
index 29f3ba83fc..e51b209411 100644
--- a/deps/icu-small/source/i18n/cpdtrans.h
+++ b/deps/icu-small/source/i18n/cpdtrans.h
@@ -98,7 +98,7 @@ public:
/**
* Transliterator API.
*/
- virtual Transliterator* clone(void) const;
+ virtual CompoundTransliterator* clone() const;
/**
* Returns the number of transliterators in this chain.
diff --git a/deps/icu-small/source/i18n/csdetect.cpp b/deps/icu-small/source/i18n/csdetect.cpp
index ad3565155d..566333fec6 100644
--- a/deps/icu-small/source/i18n/csdetect.cpp
+++ b/deps/icu-small/source/i18n/csdetect.cpp
@@ -47,7 +47,7 @@ struct CSRecognizerInfo : public UMemory {
U_NAMESPACE_END
static icu::CSRecognizerInfo **fCSRecognizers = NULL;
-static icu::UInitOnce gCSRecognizersInitOnce;
+static icu::UInitOnce gCSRecognizersInitOnce = U_INITONCE_INITIALIZER;
static int32_t fCSRecognizers_size = 0;
U_CDECL_BEGIN
diff --git a/deps/icu-small/source/i18n/curramt.cpp b/deps/icu-small/source/i18n/curramt.cpp
index 019c17df8e..69ab42ace9 100644
--- a/deps/icu-small/source/i18n/curramt.cpp
+++ b/deps/icu-small/source/i18n/curramt.cpp
@@ -38,7 +38,7 @@ CurrencyAmount& CurrencyAmount::operator=(const CurrencyAmount& other) {
return *this;
}
-UObject* CurrencyAmount::clone() const {
+CurrencyAmount* CurrencyAmount::clone() const {
return new CurrencyAmount(*this);
}
diff --git a/deps/icu-small/source/i18n/currfmt.cpp b/deps/icu-small/source/i18n/currfmt.cpp
index 8f20f783d2..0ad0492ee7 100644
--- a/deps/icu-small/source/i18n/currfmt.cpp
+++ b/deps/icu-small/source/i18n/currfmt.cpp
@@ -33,7 +33,7 @@ CurrencyFormat::CurrencyFormat(const CurrencyFormat& other) :
CurrencyFormat::~CurrencyFormat() {
}
-Format* CurrencyFormat::clone() const {
+CurrencyFormat* CurrencyFormat::clone() const {
return new CurrencyFormat(*this);
}
diff --git a/deps/icu-small/source/i18n/currfmt.h b/deps/icu-small/source/i18n/currfmt.h
index cc9bb3c1ba..69a031957b 100644
--- a/deps/icu-small/source/i18n/currfmt.h
+++ b/deps/icu-small/source/i18n/currfmt.h
@@ -57,7 +57,7 @@ class CurrencyFormat : public MeasureFormat {
/**
* Override Format API.
*/
- virtual Format* clone() const;
+ virtual CurrencyFormat* clone() const;
using MeasureFormat::format;
diff --git a/deps/icu-small/source/i18n/currunit.cpp b/deps/icu-small/source/i18n/currunit.cpp
index 39c49e468d..03347604a4 100644
--- a/deps/icu-small/source/i18n/currunit.cpp
+++ b/deps/icu-small/source/i18n/currunit.cpp
@@ -109,7 +109,7 @@ CurrencyUnit& CurrencyUnit::operator=(const CurrencyUnit& other) {
return *this;
}
-UObject* CurrencyUnit::clone() const {
+CurrencyUnit* CurrencyUnit::clone() const {
return new CurrencyUnit(*this);
}
diff --git a/deps/icu-small/source/i18n/dangical.cpp b/deps/icu-small/source/i18n/dangical.cpp
index bc3951f210..54e2e99fa6 100644
--- a/deps/icu-small/source/i18n/dangical.cpp
+++ b/deps/icu-small/source/i18n/dangical.cpp
@@ -65,7 +65,7 @@ DangiCalendar::~DangiCalendar()
{
}
-Calendar*
+DangiCalendar*
DangiCalendar::clone() const
{
return new DangiCalendar(*this);
diff --git a/deps/icu-small/source/i18n/dangical.h b/deps/icu-small/source/i18n/dangical.h
index 1a1e06b902..4f2cf384f5 100644
--- a/deps/icu-small/source/i18n/dangical.h
+++ b/deps/icu-small/source/i18n/dangical.h
@@ -66,7 +66,7 @@ class DangiCalendar : public ChineseCalendar {
* Clone.
* @internal
*/
- virtual Calendar* clone() const;
+ virtual DangiCalendar* clone() const;
//----------------------------------------------------------------------
// Internal methods & astronomical calculations
diff --git a/deps/icu-small/source/i18n/datefmt.cpp b/deps/icu-small/source/i18n/datefmt.cpp
index 039f5bc226..413139db84 100644
--- a/deps/icu-small/source/i18n/datefmt.cpp
+++ b/deps/icu-small/source/i18n/datefmt.cpp
@@ -154,7 +154,7 @@ DateFormat& DateFormat::operator=(const DateFormat& other)
fCalendar = NULL;
}
if(other.fNumberFormat) {
- fNumberFormat = (NumberFormat*)other.fNumberFormat->clone();
+ fNumberFormat = other.fNumberFormat->clone();
} else {
fNumberFormat = NULL;
}
@@ -598,7 +598,7 @@ DateFormat::adoptNumberFormat(NumberFormat* newNumberFormat)
void
DateFormat::setNumberFormat(const NumberFormat& newNumberFormat)
{
- NumberFormat* newNumFmtClone = (NumberFormat*)newNumberFormat.clone();
+ NumberFormat* newNumFmtClone = newNumberFormat.clone();
if (newNumFmtClone != NULL) {
adoptNumberFormat(newNumFmtClone);
}
diff --git a/deps/icu-small/source/i18n/decNumberLocal.h b/deps/icu-small/source/i18n/decNumberLocal.h
index f6c291a9ad..e8d1b38653 100644
--- a/deps/icu-small/source/i18n/decNumberLocal.h
+++ b/deps/icu-small/source/i18n/decNumberLocal.h
@@ -259,7 +259,7 @@
/* 2,000,000,000 (as is needed for negative exponents of */
/* subnormals). The unsigned integer pow is used as a temporary */
/* variable. */
- #define TODIGIT(u, cut, c, pow) { \
+ #define TODIGIT(u, cut, c, pow) UPRV_BLOCK_MACRO_BEGIN { \
*(c)='0'; \
pow=DECPOWERS[cut]*2; \
if ((u)>pow) { \
@@ -272,7 +272,7 @@
if ((u)>=pow) {(u)-=pow; *(c)+=2;} \
pow/=2; \
if ((u)>=pow) {(u)-=pow; *(c)+=1;} \
- }
+ } UPRV_BLOCK_MACRO_END
/* ---------------------------------------------------------------- */
/* Definitions for fixed-precision modules (only valid after */
diff --git a/deps/icu-small/source/i18n/decimfmt.cpp b/deps/icu-small/source/i18n/decimfmt.cpp
index 2a1e9347fa..6a69c9d7a3 100644
--- a/deps/icu-small/source/i18n/decimfmt.cpp
+++ b/deps/icu-small/source/i18n/decimfmt.cpp
@@ -95,7 +95,7 @@ DecimalFormat::DecimalFormat(const UnicodeString& pattern, DecimalFormatSymbols*
new CurrencyPluralInfo(fields->symbols->getLocale(), status),
status);
if (U_FAILURE(status)) { return; }
- fields->properties->currencyPluralInfo.fPtr.adoptInstead(cpi.orphan());
+ fields->properties.currencyPluralInfo.fPtr.adoptInstead(cpi.orphan());
}
touch(status);
}
@@ -111,21 +111,14 @@ DecimalFormat::DecimalFormat(const DecimalFormatSymbols* symbolsToAdopt, UErrorC
status = U_MEMORY_ALLOCATION_ERROR;
return;
}
- fields->formatter.adoptInsteadAndCheckErrorCode(new LocalizedNumberFormatter(), status);
- fields->properties.adoptInsteadAndCheckErrorCode(new DecimalFormatProperties(), status);
- fields->exportedProperties.adoptInsteadAndCheckErrorCode(new DecimalFormatProperties(), status);
if (adoptedSymbols.isNull()) {
fields->symbols.adoptInsteadAndCheckErrorCode(new DecimalFormatSymbols(status), status);
} else {
fields->symbols.adoptInsteadAndCheckErrorCode(adoptedSymbols.orphan(), status);
}
- // In order to simplify error handling logic in the various getters/setters/etc, we do not allow
- // any partially populated DecimalFormatFields object. We must have a fully complete fields object
- // or else we set it to nullptr.
- if (fields->formatter.isNull() || fields->properties.isNull() || fields->exportedProperties.isNull() || fields->symbols.isNull()) {
+ if (U_FAILURE(status)) {
delete fields;
fields = nullptr;
- status = U_MEMORY_ALLOCATION_ERROR;
}
}
@@ -133,8 +126,8 @@ DecimalFormat::DecimalFormat(const DecimalFormatSymbols* symbolsToAdopt, UErrorC
void DecimalFormat::setParseAllInput(UNumberFormatAttributeValue value) {
if (fields == nullptr) { return; }
- if (value == fields->properties->parseAllInput) { return; }
- fields->properties->parseAllInput = value;
+ if (value == fields->properties.parseAllInput) { return; }
+ fields->properties.parseAllInput = value;
}
#endif
@@ -379,9 +372,9 @@ void DecimalFormat::setGroupingUsed(UBool enabled) {
if (fields == nullptr) {
return;
}
- if (UBOOL_TO_BOOL(enabled) == fields->properties->groupingUsed) { return; }
+ if (UBOOL_TO_BOOL(enabled) == fields->properties.groupingUsed) { return; }
NumberFormat::setGroupingUsed(enabled); // to set field for compatibility
- fields->properties->groupingUsed = enabled;
+ fields->properties.groupingUsed = enabled;
touchNoError();
}
@@ -389,9 +382,9 @@ void DecimalFormat::setParseIntegerOnly(UBool value) {
if (fields == nullptr) {
return;
}
- if (UBOOL_TO_BOOL(value) == fields->properties->parseIntegerOnly) { return; }
+ if (UBOOL_TO_BOOL(value) == fields->properties.parseIntegerOnly) { return; }
NumberFormat::setParseIntegerOnly(value); // to set field for compatibility
- fields->properties->parseIntegerOnly = value;
+ fields->properties.parseIntegerOnly = value;
touchNoError();
}
@@ -400,9 +393,9 @@ void DecimalFormat::setLenient(UBool enable) {
return;
}
ParseMode mode = enable ? PARSE_MODE_LENIENT : PARSE_MODE_STRICT;
- if (!fields->properties->parseMode.isNull() && mode == fields->properties->parseMode.getNoError()) { return; }
+ if (!fields->properties.parseMode.isNull() && mode == fields->properties.parseMode.getNoError()) { return; }
NumberFormat::setLenient(enable); // to set field for compatibility
- fields->properties->parseMode = mode;
+ fields->properties.parseMode = mode;
touchNoError();
}
@@ -441,19 +434,16 @@ DecimalFormat::DecimalFormat(const DecimalFormat& source) : NumberFormat(source)
// Note: it is not safe to copy fields->formatter or fWarehouse directly because fields->formatter might have
// dangling pointers to fields inside fWarehouse. The safe thing is to re-construct fields->formatter from
// the property bag, despite being somewhat slower.
- fields = new DecimalFormatFields();
+ fields = new DecimalFormatFields(source.fields->properties);
if (fields == nullptr) {
return; // no way to report an error.
}
UErrorCode status = U_ZERO_ERROR;
- fields->formatter.adoptInsteadAndCheckErrorCode(new LocalizedNumberFormatter(), status);
- fields->properties.adoptInsteadAndCheckErrorCode(new DecimalFormatProperties(*source.fields->properties), status);
fields->symbols.adoptInsteadAndCheckErrorCode(new DecimalFormatSymbols(*source.fields->symbols), status);
- fields->exportedProperties.adoptInsteadAndCheckErrorCode(new DecimalFormatProperties(), status);
// In order to simplify error handling logic in the various getters/setters/etc, we do not allow
// any partially populated DecimalFormatFields object. We must have a fully complete fields object
// or else we set it to nullptr.
- if (fields->formatter.isNull() || fields->properties.isNull() || fields->exportedProperties.isNull() || fields->symbols.isNull()) {
+ if (U_FAILURE(status)) {
delete fields;
fields = nullptr;
return;
@@ -470,8 +460,8 @@ DecimalFormat& DecimalFormat::operator=(const DecimalFormat& rhs) {
if (fields == nullptr || rhs.fields == nullptr) {
return *this; // unfortunately, no way to report an error.
}
- *fields->properties = *rhs.fields->properties;
- fields->exportedProperties->clear();
+ fields->properties = rhs.fields->properties;
+ fields->exportedProperties.clear();
UErrorCode status = U_ZERO_ERROR;
LocalPointer<DecimalFormatSymbols> dfs(new DecimalFormatSymbols(*rhs.fields->symbols), status);
if (U_FAILURE(status)) {
@@ -495,7 +485,7 @@ DecimalFormat::~DecimalFormat() {
delete fields;
}
-Format* DecimalFormat::clone() const {
+DecimalFormat* DecimalFormat::clone() const {
// can only clone valid objects.
if (fields == nullptr) {
return nullptr;
@@ -517,7 +507,7 @@ UBool DecimalFormat::operator==(const Format& other) const {
if (fields == nullptr || otherDF->fields == nullptr) {
return false;
}
- return *fields->properties == *otherDF->fields->properties && *fields->symbols == *otherDF->fields->symbols;
+ return fields->properties == otherDF->fields->properties && *fields->symbols == *otherDF->fields->symbols;
}
UnicodeString& DecimalFormat::format(double number, UnicodeString& appendTo, FieldPosition& pos) const {
@@ -529,7 +519,7 @@ UnicodeString& DecimalFormat::format(double number, UnicodeString& appendTo, Fie
return appendTo;
}
UErrorCode localStatus = U_ZERO_ERROR;
- FormattedNumber output = fields->formatter->formatDouble(number, localStatus);
+ FormattedNumber output = fields->formatter.formatDouble(number, localStatus);
fieldPositionHelper(output, pos, appendTo.length(), localStatus);
auto appendable = UnicodeStringAppendable(appendTo);
output.appendTo(appendable, localStatus);
@@ -550,7 +540,7 @@ UnicodeString& DecimalFormat::format(double number, UnicodeString& appendTo, Fie
if (pos.getField() == FieldPosition::DONT_CARE && fastFormatDouble(number, appendTo)) {
return appendTo;
}
- FormattedNumber output = fields->formatter->formatDouble(number, status);
+ FormattedNumber output = fields->formatter.formatDouble(number, status);
fieldPositionHelper(output, pos, appendTo.length(), status);
auto appendable = UnicodeStringAppendable(appendTo);
output.appendTo(appendable, status);
@@ -572,7 +562,7 @@ DecimalFormat::format(double number, UnicodeString& appendTo, FieldPositionItera
if (posIter == nullptr && fastFormatDouble(number, appendTo)) {
return appendTo;
}
- FormattedNumber output = fields->formatter->formatDouble(number, status);
+ FormattedNumber output = fields->formatter.formatDouble(number, status);
fieldPositionIteratorHelper(output, posIter, appendTo.length(), status);
auto appendable = UnicodeStringAppendable(appendTo);
output.appendTo(appendable, status);
@@ -603,7 +593,7 @@ UnicodeString& DecimalFormat::format(int64_t number, UnicodeString& appendTo, Fi
return appendTo;
}
UErrorCode localStatus = U_ZERO_ERROR;
- FormattedNumber output = fields->formatter->formatInt(number, localStatus);
+ FormattedNumber output = fields->formatter.formatInt(number, localStatus);
fieldPositionHelper(output, pos, appendTo.length(), localStatus);
auto appendable = UnicodeStringAppendable(appendTo);
output.appendTo(appendable, localStatus);
@@ -624,7 +614,7 @@ UnicodeString& DecimalFormat::format(int64_t number, UnicodeString& appendTo, Fi
if (pos.getField() == FieldPosition::DONT_CARE && fastFormatInt64(number, appendTo)) {
return appendTo;
}
- FormattedNumber output = fields->formatter->formatInt(number, status);
+ FormattedNumber output = fields->formatter.formatInt(number, status);
fieldPositionHelper(output, pos, appendTo.length(), status);
auto appendable = UnicodeStringAppendable(appendTo);
output.appendTo(appendable, status);
@@ -646,7 +636,7 @@ DecimalFormat::format(int64_t number, UnicodeString& appendTo, FieldPositionIter
if (posIter == nullptr && fastFormatInt64(number, appendTo)) {
return appendTo;
}
- FormattedNumber output = fields->formatter->formatInt(number, status);
+ FormattedNumber output = fields->formatter.formatInt(number, status);
fieldPositionIteratorHelper(output, posIter, appendTo.length(), status);
auto appendable = UnicodeStringAppendable(appendTo);
output.appendTo(appendable, status);
@@ -665,7 +655,7 @@ DecimalFormat::format(StringPiece number, UnicodeString& appendTo, FieldPosition
appendTo.setToBogus();
return appendTo;
}
- FormattedNumber output = fields->formatter->formatDecimal(number, status);
+ FormattedNumber output = fields->formatter.formatDecimal(number, status);
fieldPositionIteratorHelper(output, posIter, appendTo.length(), status);
auto appendable = UnicodeStringAppendable(appendTo);
output.appendTo(appendable, status);
@@ -683,7 +673,7 @@ UnicodeString& DecimalFormat::format(const DecimalQuantity& number, UnicodeStrin
appendTo.setToBogus();
return appendTo;
}
- FormattedNumber output = fields->formatter->formatDecimalQuantity(number, status);
+ FormattedNumber output = fields->formatter.formatDecimalQuantity(number, status);
fieldPositionIteratorHelper(output, posIter, appendTo.length(), status);
auto appendable = UnicodeStringAppendable(appendTo);
output.appendTo(appendable, status);
@@ -702,7 +692,7 @@ DecimalFormat::format(const DecimalQuantity& number, UnicodeString& appendTo, Fi
appendTo.setToBogus();
return appendTo;
}
- FormattedNumber output = fields->formatter->formatDecimalQuantity(number, status);
+ FormattedNumber output = fields->formatter.formatDecimalQuantity(number, status);
fieldPositionHelper(output, pos, appendTo.length(), status);
auto appendable = UnicodeStringAppendable(appendTo);
output.appendTo(appendable, status);
@@ -823,7 +813,7 @@ const CurrencyPluralInfo* DecimalFormat::getCurrencyPluralInfo(void) const {
if (fields == nullptr) {
return nullptr;
}
- return fields->properties->currencyPluralInfo.fPtr.getAlias();
+ return fields->properties.currencyPluralInfo.fPtr.getAlias();
}
void DecimalFormat::adoptCurrencyPluralInfo(CurrencyPluralInfo* toAdopt) {
@@ -833,7 +823,7 @@ void DecimalFormat::adoptCurrencyPluralInfo(CurrencyPluralInfo* toAdopt) {
if (fields == nullptr) {
return;
}
- fields->properties->currencyPluralInfo.fPtr.adoptInstead(cpi.orphan());
+ fields->properties.currencyPluralInfo.fPtr.adoptInstead(cpi.orphan());
touchNoError();
}
@@ -841,11 +831,11 @@ void DecimalFormat::setCurrencyPluralInfo(const CurrencyPluralInfo& info) {
if (fields == nullptr) {
return;
}
- if (fields->properties->currencyPluralInfo.fPtr.isNull()) {
+ if (fields->properties.currencyPluralInfo.fPtr.isNull()) {
// Note: clone() can fail with OOM error, but we have no way to report it. :(
- fields->properties->currencyPluralInfo.fPtr.adoptInstead(info.clone());
+ fields->properties.currencyPluralInfo.fPtr.adoptInstead(info.clone());
} else {
- *fields->properties->currencyPluralInfo.fPtr = info; // copy-assignment operator
+ *fields->properties.currencyPluralInfo.fPtr = info; // copy-assignment operator
}
touchNoError();
}
@@ -856,7 +846,7 @@ UnicodeString& DecimalFormat::getPositivePrefix(UnicodeString& result) const {
return result;
}
UErrorCode status = U_ZERO_ERROR;
- fields->formatter->getAffixImpl(true, false, result, status);
+ fields->formatter.getAffixImpl(true, false, result, status);
if (U_FAILURE(status)) { result.setToBogus(); }
return result;
}
@@ -865,8 +855,8 @@ void DecimalFormat::setPositivePrefix(const UnicodeString& newValue) {
if (fields == nullptr) {
return;
}
- if (newValue == fields->properties->positivePrefix) { return; }
- fields->properties->positivePrefix = newValue;
+ if (newValue == fields->properties.positivePrefix) { return; }
+ fields->properties.positivePrefix = newValue;
touchNoError();
}
@@ -876,7 +866,7 @@ UnicodeString& DecimalFormat::getNegativePrefix(UnicodeString& result) const {
return result;
}
UErrorCode status = U_ZERO_ERROR;
- fields->formatter->getAffixImpl(true, true, result, status);
+ fields->formatter.getAffixImpl(true, true, result, status);
if (U_FAILURE(status)) { result.setToBogus(); }
return result;
}
@@ -885,8 +875,8 @@ void DecimalFormat::setNegativePrefix(const UnicodeString& newValue) {
if (fields == nullptr) {
return;
}
- if (newValue == fields->properties->negativePrefix) { return; }
- fields->properties->negativePrefix = newValue;
+ if (newValue == fields->properties.negativePrefix) { return; }
+ fields->properties.negativePrefix = newValue;
touchNoError();
}
@@ -896,7 +886,7 @@ UnicodeString& DecimalFormat::getPositiveSuffix(UnicodeString& result) const {
return result;
}
UErrorCode status = U_ZERO_ERROR;
- fields->formatter->getAffixImpl(false, false, result, status);
+ fields->formatter.getAffixImpl(false, false, result, status);
if (U_FAILURE(status)) { result.setToBogus(); }
return result;
}
@@ -905,8 +895,8 @@ void DecimalFormat::setPositiveSuffix(const UnicodeString& newValue) {
if (fields == nullptr) {
return;
}
- if (newValue == fields->properties->positiveSuffix) { return; }
- fields->properties->positiveSuffix = newValue;
+ if (newValue == fields->properties.positiveSuffix) { return; }
+ fields->properties.positiveSuffix = newValue;
touchNoError();
}
@@ -916,7 +906,7 @@ UnicodeString& DecimalFormat::getNegativeSuffix(UnicodeString& result) const {
return result;
}
UErrorCode status = U_ZERO_ERROR;
- fields->formatter->getAffixImpl(false, true, result, status);
+ fields->formatter.getAffixImpl(false, true, result, status);
if (U_FAILURE(status)) { result.setToBogus(); }
return result;
}
@@ -925,8 +915,8 @@ void DecimalFormat::setNegativeSuffix(const UnicodeString& newValue) {
if (fields == nullptr) {
return;
}
- if (newValue == fields->properties->negativeSuffix) { return; }
- fields->properties->negativeSuffix = newValue;
+ if (newValue == fields->properties.negativeSuffix) { return; }
+ fields->properties.negativeSuffix = newValue;
touchNoError();
}
@@ -935,13 +925,13 @@ UBool DecimalFormat::isSignAlwaysShown() const {
if (fields == nullptr) {
return DecimalFormatProperties::getDefault().signAlwaysShown;
}
- return fields->properties->signAlwaysShown;
+ return fields->properties.signAlwaysShown;
}
void DecimalFormat::setSignAlwaysShown(UBool value) {
if (fields == nullptr) { return; }
- if (UBOOL_TO_BOOL(value) == fields->properties->signAlwaysShown) { return; }
- fields->properties->signAlwaysShown = value;
+ if (UBOOL_TO_BOOL(value) == fields->properties.signAlwaysShown) { return; }
+ fields->properties.signAlwaysShown = value;
touchNoError();
}
@@ -952,7 +942,7 @@ int32_t DecimalFormat::getMultiplier(void) const {
// Fallback to using the default instance of DecimalFormatProperties.
dfp = &(DecimalFormatProperties::getDefault());
} else {
- dfp = fields->properties.getAlias();
+ dfp = &fields->properties;
}
if (dfp->multiplier != 1) {
return dfp->multiplier;
@@ -984,11 +974,11 @@ void DecimalFormat::setMultiplier(int32_t multiplier) {
value = temp;
}
if (delta != -1) {
- fields->properties->magnitudeMultiplier = delta;
- fields->properties->multiplier = 1;
+ fields->properties.magnitudeMultiplier = delta;
+ fields->properties.multiplier = 1;
} else {
- fields->properties->magnitudeMultiplier = 0;
- fields->properties->multiplier = multiplier;
+ fields->properties.magnitudeMultiplier = 0;
+ fields->properties.multiplier = multiplier;
}
touchNoError();
}
@@ -999,13 +989,13 @@ int32_t DecimalFormat::getMultiplierScale() const {
// Fallback to using the default instance of DecimalFormatProperties.
return DecimalFormatProperties::getDefault().multiplierScale;
}
- return fields->properties->multiplierScale;
+ return fields->properties.multiplierScale;
}
void DecimalFormat::setMultiplierScale(int32_t newValue) {
if (fields == nullptr) { return; }
- if (newValue == fields->properties->multiplierScale) { return; }
- fields->properties->multiplierScale = newValue;
+ if (newValue == fields->properties.multiplierScale) { return; }
+ fields->properties.multiplierScale = newValue;
touchNoError();
}
@@ -1015,13 +1005,13 @@ double DecimalFormat::getRoundingIncrement(void) const {
// Fallback to using the default instance of DecimalFormatProperties.
return DecimalFormatProperties::getDefault().roundingIncrement;
}
- return fields->exportedProperties->roundingIncrement;
+ return fields->exportedProperties.roundingIncrement;
}
void DecimalFormat::setRoundingIncrement(double newValue) {
if (fields == nullptr) { return; }
- if (newValue == fields->properties->roundingIncrement) { return; }
- fields->properties->roundingIncrement = newValue;
+ if (newValue == fields->properties.roundingIncrement) { return; }
+ fields->properties.roundingIncrement = newValue;
touchNoError();
}
@@ -1032,17 +1022,17 @@ ERoundingMode DecimalFormat::getRoundingMode(void) const {
return static_cast<ERoundingMode>(DecimalFormatProperties::getDefault().roundingMode.getNoError());
}
// UNumberFormatRoundingMode and ERoundingMode have the same values.
- return static_cast<ERoundingMode>(fields->exportedProperties->roundingMode.getNoError());
+ return static_cast<ERoundingMode>(fields->exportedProperties.roundingMode.getNoError());
}
void DecimalFormat::setRoundingMode(ERoundingMode roundingMode) {
if (fields == nullptr) { return; }
auto uRoundingMode = static_cast<UNumberFormatRoundingMode>(roundingMode);
- if (!fields->properties->roundingMode.isNull() && uRoundingMode == fields->properties->roundingMode.getNoError()) {
+ if (!fields->properties.roundingMode.isNull() && uRoundingMode == fields->properties.roundingMode.getNoError()) {
return;
}
NumberFormat::setMaximumIntegerDigits(roundingMode); // to set field for compatibility
- fields->properties->roundingMode = uRoundingMode;
+ fields->properties.roundingMode = uRoundingMode;
touchNoError();
}
@@ -1052,52 +1042,52 @@ int32_t DecimalFormat::getFormatWidth(void) const {
// Fallback to using the default instance of DecimalFormatProperties.
return DecimalFormatProperties::getDefault().formatWidth;
}
- return fields->properties->formatWidth;
+ return fields->properties.formatWidth;
}
void DecimalFormat::setFormatWidth(int32_t width) {
if (fields == nullptr) { return; }
- if (width == fields->properties->formatWidth) { return; }
- fields->properties->formatWidth = width;
+ if (width == fields->properties.formatWidth) { return; }
+ fields->properties.formatWidth = width;
touchNoError();
}
UnicodeString DecimalFormat::getPadCharacterString() const {
- if (fields == nullptr || fields->properties->padString.isBogus()) {
+ if (fields == nullptr || fields->properties.padString.isBogus()) {
// Readonly-alias the static string kFallbackPaddingString
return {TRUE, kFallbackPaddingString, -1};
} else {
- return fields->properties->padString;
+ return fields->properties.padString;
}
}
void DecimalFormat::setPadCharacter(const UnicodeString& padChar) {
if (fields == nullptr) { return; }
- if (padChar == fields->properties->padString) { return; }
+ if (padChar == fields->properties.padString) { return; }
if (padChar.length() > 0) {
- fields->properties->padString = UnicodeString(padChar.char32At(0));
+ fields->properties.padString = UnicodeString(padChar.char32At(0));
} else {
- fields->properties->padString.setToBogus();
+ fields->properties.padString.setToBogus();
}
touchNoError();
}
EPadPosition DecimalFormat::getPadPosition(void) const {
- if (fields == nullptr || fields->properties->padPosition.isNull()) {
+ if (fields == nullptr || fields->properties.padPosition.isNull()) {
return EPadPosition::kPadBeforePrefix;
} else {
// UNumberFormatPadPosition and EPadPosition have the same values.
- return static_cast<EPadPosition>(fields->properties->padPosition.getNoError());
+ return static_cast<EPadPosition>(fields->properties.padPosition.getNoError());
}
}
void DecimalFormat::setPadPosition(EPadPosition padPos) {
if (fields == nullptr) { return; }
auto uPadPos = static_cast<UNumberFormatPadPosition>(padPos);
- if (!fields->properties->padPosition.isNull() && uPadPos == fields->properties->padPosition.getNoError()) {
+ if (!fields->properties.padPosition.isNull() && uPadPos == fields->properties.padPosition.getNoError()) {
return;
}
- fields->properties->padPosition = uPadPos;
+ fields->properties.padPosition = uPadPos;
touchNoError();
}
@@ -1107,17 +1097,17 @@ UBool DecimalFormat::isScientificNotation(void) const {
// Fallback to using the default instance of DecimalFormatProperties.
return (DecimalFormatProperties::getDefault().minimumExponentDigits != -1);
}
- return (fields->properties->minimumExponentDigits != -1);
+ return (fields->properties.minimumExponentDigits != -1);
}
void DecimalFormat::setScientificNotation(UBool useScientific) {
if (fields == nullptr) { return; }
int32_t minExp = useScientific ? 1 : -1;
- if (fields->properties->minimumExponentDigits == minExp) { return; }
+ if (fields->properties.minimumExponentDigits == minExp) { return; }
if (useScientific) {
- fields->properties->minimumExponentDigits = 1;
+ fields->properties.minimumExponentDigits = 1;
} else {
- fields->properties->minimumExponentDigits = -1;
+ fields->properties.minimumExponentDigits = -1;
}
touchNoError();
}
@@ -1128,13 +1118,13 @@ int8_t DecimalFormat::getMinimumExponentDigits(void) const {
// Fallback to using the default instance of DecimalFormatProperties.
return static_cast<int8_t>(DecimalFormatProperties::getDefault().minimumExponentDigits);
}
- return static_cast<int8_t>(fields->properties->minimumExponentDigits);
+ return static_cast<int8_t>(fields->properties.minimumExponentDigits);
}
void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig) {
if (fields == nullptr) { return; }
- if (minExpDig == fields->properties->minimumExponentDigits) { return; }
- fields->properties->minimumExponentDigits = minExpDig;
+ if (minExpDig == fields->properties.minimumExponentDigits) { return; }
+ fields->properties.minimumExponentDigits = minExpDig;
touchNoError();
}
@@ -1144,13 +1134,13 @@ UBool DecimalFormat::isExponentSignAlwaysShown(void) const {
// Fallback to using the default instance of DecimalFormatProperties.
return DecimalFormatProperties::getDefault().exponentSignAlwaysShown;
}
- return fields->properties->exponentSignAlwaysShown;
+ return fields->properties.exponentSignAlwaysShown;
}
void DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways) {
if (fields == nullptr) { return; }
- if (UBOOL_TO_BOOL(expSignAlways) == fields->properties->exponentSignAlwaysShown) { return; }
- fields->properties->exponentSignAlwaysShown = expSignAlways;
+ if (UBOOL_TO_BOOL(expSignAlways) == fields->properties.exponentSignAlwaysShown) { return; }
+ fields->properties.exponentSignAlwaysShown = expSignAlways;
touchNoError();
}
@@ -1161,7 +1151,7 @@ int32_t DecimalFormat::getGroupingSize(void) const {
// Fallback to using the default instance of DecimalFormatProperties.
groupingSize = DecimalFormatProperties::getDefault().groupingSize;
} else {
- groupingSize = fields->properties->groupingSize;
+ groupingSize = fields->properties.groupingSize;
}
if (groupingSize < 0) {
return 0;
@@ -1171,8 +1161,8 @@ int32_t DecimalFormat::getGroupingSize(void) const {
void DecimalFormat::setGroupingSize(int32_t newValue) {
if (fields == nullptr) { return; }
- if (newValue == fields->properties->groupingSize) { return; }
- fields->properties->groupingSize = newValue;
+ if (newValue == fields->properties.groupingSize) { return; }
+ fields->properties.groupingSize = newValue;
touchNoError();
}
@@ -1183,7 +1173,7 @@ int32_t DecimalFormat::getSecondaryGroupingSize(void) const {
// Fallback to using the default instance of DecimalFormatProperties.
grouping2 = DecimalFormatProperties::getDefault().secondaryGroupingSize;
} else {
- grouping2 = fields->properties->secondaryGroupingSize;
+ grouping2 = fields->properties.secondaryGroupingSize;
}
if (grouping2 < 0) {
return 0;
@@ -1193,8 +1183,8 @@ int32_t DecimalFormat::getSecondaryGroupingSize(void) const {
void DecimalFormat::setSecondaryGroupingSize(int32_t newValue) {
if (fields == nullptr) { return; }
- if (newValue == fields->properties->secondaryGroupingSize) { return; }
- fields->properties->secondaryGroupingSize = newValue;
+ if (newValue == fields->properties.secondaryGroupingSize) { return; }
+ fields->properties.secondaryGroupingSize = newValue;
touchNoError();
}
@@ -1204,13 +1194,13 @@ int32_t DecimalFormat::getMinimumGroupingDigits() const {
// Fallback to using the default instance of DecimalFormatProperties.
return DecimalFormatProperties::getDefault().minimumGroupingDigits;
}
- return fields->properties->minimumGroupingDigits;
+ return fields->properties.minimumGroupingDigits;
}
void DecimalFormat::setMinimumGroupingDigits(int32_t newValue) {
if (fields == nullptr) { return; }
- if (newValue == fields->properties->minimumGroupingDigits) { return; }
- fields->properties->minimumGroupingDigits = newValue;
+ if (newValue == fields->properties.minimumGroupingDigits) { return; }
+ fields->properties.minimumGroupingDigits = newValue;
touchNoError();
}
@@ -1220,13 +1210,13 @@ UBool DecimalFormat::isDecimalSeparatorAlwaysShown(void) const {
// Fallback to using the default instance of DecimalFormatProperties.
return DecimalFormatProperties::getDefault().decimalSeparatorAlwaysShown;
}
- return fields->properties->decimalSeparatorAlwaysShown;
+ return fields->properties.decimalSeparatorAlwaysShown;
}
void DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue) {
if (fields == nullptr) { return; }
- if (UBOOL_TO_BOOL(newValue) == fields->properties->decimalSeparatorAlwaysShown) { return; }
- fields->properties->decimalSeparatorAlwaysShown = newValue;
+ if (UBOOL_TO_BOOL(newValue) == fields->properties.decimalSeparatorAlwaysShown) { return; }
+ fields->properties.decimalSeparatorAlwaysShown = newValue;
touchNoError();
}
@@ -1236,13 +1226,13 @@ UBool DecimalFormat::isDecimalPatternMatchRequired(void) const {
// Fallback to using the default instance of DecimalFormatProperties.
return DecimalFormatProperties::getDefault().decimalPatternMatchRequired;
}
- return fields->properties->decimalPatternMatchRequired;
+ return fields->properties.decimalPatternMatchRequired;
}
void DecimalFormat::setDecimalPatternMatchRequired(UBool newValue) {
if (fields == nullptr) { return; }
- if (UBOOL_TO_BOOL(newValue) == fields->properties->decimalPatternMatchRequired) { return; }
- fields->properties->decimalPatternMatchRequired = newValue;
+ if (UBOOL_TO_BOOL(newValue) == fields->properties.decimalPatternMatchRequired) { return; }
+ fields->properties.decimalPatternMatchRequired = newValue;
touchNoError();
}
@@ -1252,13 +1242,13 @@ UBool DecimalFormat::isParseNoExponent() const {
// Fallback to using the default instance of DecimalFormatProperties.
return DecimalFormatProperties::getDefault().parseNoExponent;
}
- return fields->properties->parseNoExponent;
+ return fields->properties.parseNoExponent;
}
void DecimalFormat::setParseNoExponent(UBool value) {
if (fields == nullptr) { return; }
- if (UBOOL_TO_BOOL(value) == fields->properties->parseNoExponent) { return; }
- fields->properties->parseNoExponent = value;
+ if (UBOOL_TO_BOOL(value) == fields->properties.parseNoExponent) { return; }
+ fields->properties.parseNoExponent = value;
touchNoError();
}
@@ -1268,13 +1258,13 @@ UBool DecimalFormat::isParseCaseSensitive() const {
// Fallback to using the default instance of DecimalFormatProperties.
return DecimalFormatProperties::getDefault().parseCaseSensitive;
}
- return fields->properties->parseCaseSensitive;
+ return fields->properties.parseCaseSensitive;
}
void DecimalFormat::setParseCaseSensitive(UBool value) {
if (fields == nullptr) { return; }
- if (UBOOL_TO_BOOL(value) == fields->properties->parseCaseSensitive) { return; }
- fields->properties->parseCaseSensitive = value;
+ if (UBOOL_TO_BOOL(value) == fields->properties.parseCaseSensitive) { return; }
+ fields->properties.parseCaseSensitive = value;
touchNoError();
}
@@ -1284,13 +1274,13 @@ UBool DecimalFormat::isFormatFailIfMoreThanMaxDigits() const {
// Fallback to using the default instance of DecimalFormatProperties.
return DecimalFormatProperties::getDefault().formatFailIfMoreThanMaxDigits;
}
- return fields->properties->formatFailIfMoreThanMaxDigits;
+ return fields->properties.formatFailIfMoreThanMaxDigits;
}
void DecimalFormat::setFormatFailIfMoreThanMaxDigits(UBool value) {
if (fields == nullptr) { return; }
- if (UBOOL_TO_BOOL(value) == fields->properties->formatFailIfMoreThanMaxDigits) { return; }
- fields->properties->formatFailIfMoreThanMaxDigits = value;
+ if (UBOOL_TO_BOOL(value) == fields->properties.formatFailIfMoreThanMaxDigits) { return; }
+ fields->properties.formatFailIfMoreThanMaxDigits = value;
touchNoError();
}
@@ -1305,7 +1295,7 @@ UnicodeString& DecimalFormat::toPattern(UnicodeString& result) const {
// so that CurrencyUsage is reflected properly.
// TODO: Consider putting this logic in number_patternstring.cpp instead.
ErrorCode localStatus;
- DecimalFormatProperties tprops(*fields->properties);
+ DecimalFormatProperties tprops(fields->properties);
bool useCurrency = (
!tprops.currency.isNull() ||
!tprops.currencyPluralInfo.fPtr.isNull() ||
@@ -1315,9 +1305,9 @@ UnicodeString& DecimalFormat::toPattern(UnicodeString& result) const {
AffixUtils::hasCurrencySymbols(tprops.negativePrefixPattern, localStatus) ||
AffixUtils::hasCurrencySymbols(tprops.negativeSuffixPattern, localStatus));
if (useCurrency) {
- tprops.minimumFractionDigits = fields->exportedProperties->minimumFractionDigits;
- tprops.maximumFractionDigits = fields->exportedProperties->maximumFractionDigits;
- tprops.roundingIncrement = fields->exportedProperties->roundingIncrement;
+ tprops.minimumFractionDigits = fields->exportedProperties.minimumFractionDigits;
+ tprops.maximumFractionDigits = fields->exportedProperties.maximumFractionDigits;
+ tprops.roundingIncrement = fields->exportedProperties.roundingIncrement;
}
result = PatternStringUtils::propertiesToPatternString(tprops, localStatus);
return result;
@@ -1373,49 +1363,53 @@ void DecimalFormat::applyLocalizedPattern(const UnicodeString& localizedPattern,
void DecimalFormat::setMaximumIntegerDigits(int32_t newValue) {
if (fields == nullptr) { return; }
- if (newValue == fields->properties->maximumIntegerDigits) { return; }
+ if (newValue == fields->properties.maximumIntegerDigits) { return; }
// For backwards compatibility, conflicting min/max need to keep the most recent setting.
- int32_t min = fields->properties->minimumIntegerDigits;
+ int32_t min = fields->properties.minimumIntegerDigits;
if (min >= 0 && min > newValue) {
- fields->properties->minimumIntegerDigits = newValue;
+ fields->properties.minimumIntegerDigits = newValue;
}
- fields->properties->maximumIntegerDigits = newValue;
+ fields->properties.maximumIntegerDigits = newValue;
touchNoError();
}
void DecimalFormat::setMinimumIntegerDigits(int32_t newValue) {
if (fields == nullptr) { return; }
- if (newValue == fields->properties->minimumIntegerDigits) { return; }
+ if (newValue == fields->properties.minimumIntegerDigits) { return; }
// For backwards compatibility, conflicting min/max need to keep the most recent setting.
- int32_t max = fields->properties->maximumIntegerDigits;
+ int32_t max = fields->properties.maximumIntegerDigits;
if (max >= 0 && max < newValue) {
- fields->properties->maximumIntegerDigits = newValue;
+ fields->properties.maximumIntegerDigits = newValue;
}
- fields->properties->minimumIntegerDigits = newValue;
+ fields->properties.minimumIntegerDigits = newValue;
touchNoError();
}
void DecimalFormat::setMaximumFractionDigits(int32_t newValue) {
if (fields == nullptr) { return; }
- if (newValue == fields->properties->maximumFractionDigits) { return; }
+ if (newValue == fields->properties.maximumFractionDigits) { return; }
+ // cap for backward compatibility, formerly 340, now 999
+ if (newValue > kMaxIntFracSig) {
+ newValue = kMaxIntFracSig;
+ }
// For backwards compatibility, conflicting min/max need to keep the most recent setting.
- int32_t min = fields->properties->minimumFractionDigits;
+ int32_t min = fields->properties.minimumFractionDigits;
if (min >= 0 && min > newValue) {
- fields->properties->minimumFractionDigits = newValue;
+ fields->properties.minimumFractionDigits = newValue;
}
- fields->properties->maximumFractionDigits = newValue;
+ fields->properties.maximumFractionDigits = newValue;
touchNoError();
}
void DecimalFormat::setMinimumFractionDigits(int32_t newValue) {
if (fields == nullptr) { return; }
- if (newValue == fields->properties->minimumFractionDigits) { return; }
+ if (newValue == fields->properties.minimumFractionDigits) { return; }
// For backwards compatibility, conflicting min/max need to keep the most recent setting.
- int32_t max = fields->properties->maximumFractionDigits;
+ int32_t max = fields->properties.maximumFractionDigits;
if (max >= 0 && max < newValue) {
- fields->properties->maximumFractionDigits = newValue;
+ fields->properties.maximumFractionDigits = newValue;
}
- fields->properties->minimumFractionDigits = newValue;
+ fields->properties.minimumFractionDigits = newValue;
touchNoError();
}
@@ -1425,7 +1419,7 @@ int32_t DecimalFormat::getMinimumSignificantDigits() const {
// Fallback to using the default instance of DecimalFormatProperties.
return DecimalFormatProperties::getDefault().minimumSignificantDigits;
}
- return fields->exportedProperties->minimumSignificantDigits;
+ return fields->exportedProperties.minimumSignificantDigits;
}
int32_t DecimalFormat::getMaximumSignificantDigits() const {
@@ -1434,28 +1428,28 @@ int32_t DecimalFormat::getMaximumSignificantDigits() const {
// Fallback to using the default instance of DecimalFormatProperties.
return DecimalFormatProperties::getDefault().maximumSignificantDigits;
}
- return fields->exportedProperties->maximumSignificantDigits;
+ return fields->exportedProperties.maximumSignificantDigits;
}
void DecimalFormat::setMinimumSignificantDigits(int32_t value) {
if (fields == nullptr) { return; }
- if (value == fields->properties->minimumSignificantDigits) { return; }
- int32_t max = fields->properties->maximumSignificantDigits;
+ if (value == fields->properties.minimumSignificantDigits) { return; }
+ int32_t max = fields->properties.maximumSignificantDigits;
if (max >= 0 && max < value) {
- fields->properties->maximumSignificantDigits = value;
+ fields->properties.maximumSignificantDigits = value;
}
- fields->properties->minimumSignificantDigits = value;
+ fields->properties.minimumSignificantDigits = value;
touchNoError();
}
void DecimalFormat::setMaximumSignificantDigits(int32_t value) {
if (fields == nullptr) { return; }
- if (value == fields->properties->maximumSignificantDigits) { return; }
- int32_t min = fields->properties->minimumSignificantDigits;
+ if (value == fields->properties.maximumSignificantDigits) { return; }
+ int32_t min = fields->properties.minimumSignificantDigits;
if (min >= 0 && min > value) {
- fields->properties->minimumSignificantDigits = value;
+ fields->properties.minimumSignificantDigits = value;
}
- fields->properties->maximumSignificantDigits = value;
+ fields->properties.maximumSignificantDigits = value;
touchNoError();
}
@@ -1466,7 +1460,7 @@ UBool DecimalFormat::areSignificantDigitsUsed() const {
// Fallback to using the default instance of DecimalFormatProperties.
dfp = &(DecimalFormatProperties::getDefault());
} else {
- dfp = fields->properties.getAlias();
+ dfp = &fields->properties;
}
return dfp->minimumSignificantDigits != -1 || dfp->maximumSignificantDigits != -1;
}
@@ -1476,20 +1470,20 @@ void DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits) {
// These are the default values from the old implementation.
if (useSignificantDigits) {
- if (fields->properties->minimumSignificantDigits != -1 ||
- fields->properties->maximumSignificantDigits != -1) {
+ if (fields->properties.minimumSignificantDigits != -1 ||
+ fields->properties.maximumSignificantDigits != -1) {
return;
}
} else {
- if (fields->properties->minimumSignificantDigits == -1 &&
- fields->properties->maximumSignificantDigits == -1) {
+ if (fields->properties.minimumSignificantDigits == -1 &&
+ fields->properties.maximumSignificantDigits == -1) {
return;
}
}
int32_t minSig = useSignificantDigits ? 1 : -1;
int32_t maxSig = useSignificantDigits ? 6 : -1;
- fields->properties->minimumSignificantDigits = minSig;
- fields->properties->maximumSignificantDigits = maxSig;
+ fields->properties.minimumSignificantDigits = minSig;
+ fields->properties.maximumSignificantDigits = maxSig;
touchNoError();
}
@@ -1503,11 +1497,11 @@ void DecimalFormat::setCurrency(const char16_t* theCurrency, UErrorCode& ec) {
}
CurrencyUnit currencyUnit(theCurrency, ec);
if (U_FAILURE(ec)) { return; }
- if (!fields->properties->currency.isNull() && fields->properties->currency.getNoError() == currencyUnit) {
+ if (!fields->properties.currency.isNull() && fields->properties.currency.getNoError() == currencyUnit) {
return;
}
NumberFormat::setCurrency(theCurrency, ec); // to set field for compatibility
- fields->properties->currency = currencyUnit;
+ fields->properties.currency = currencyUnit;
// TODO: Set values in fields->symbols, too?
touchNoError();
}
@@ -1525,20 +1519,20 @@ void DecimalFormat::setCurrencyUsage(UCurrencyUsage newUsage, UErrorCode* ec) {
*ec = U_MEMORY_ALLOCATION_ERROR;
return;
}
- if (!fields->properties->currencyUsage.isNull() && newUsage == fields->properties->currencyUsage.getNoError()) {
+ if (!fields->properties.currencyUsage.isNull() && newUsage == fields->properties.currencyUsage.getNoError()) {
return;
}
- fields->properties->currencyUsage = newUsage;
+ fields->properties.currencyUsage = newUsage;
touch(*ec);
}
UCurrencyUsage DecimalFormat::getCurrencyUsage() const {
// CurrencyUsage is not exported, so we have to get it from the input property bag.
// TODO: Should we export CurrencyUsage instead?
- if (fields == nullptr || fields->properties->currencyUsage.isNull()) {
+ if (fields == nullptr || fields->properties.currencyUsage.isNull()) {
return UCURR_USAGE_STANDARD;
}
- return fields->properties->currencyUsage.getNoError();
+ return fields->properties.currencyUsage.getNoError();
}
void
@@ -1550,7 +1544,7 @@ DecimalFormat::formatToDecimalQuantity(double number, DecimalQuantity& output, U
status = U_MEMORY_ALLOCATION_ERROR;
return;
}
- fields->formatter->formatDouble(number, status).getDecimalQuantity(output, status);
+ fields->formatter.formatDouble(number, status).getDecimalQuantity(output, status);
}
void DecimalFormat::formatToDecimalQuantity(const Formattable& number, DecimalQuantity& output,
@@ -1564,7 +1558,7 @@ void DecimalFormat::formatToDecimalQuantity(const Formattable& number, DecimalQu
}
UFormattedNumberData obj;
number.populateDecimalQuantity(obj.quantity, status);
- fields->formatter->formatImpl(&obj, status);
+ fields->formatter.formatImpl(&obj, status);
output = std::move(obj.quantity);
}
@@ -1576,12 +1570,7 @@ const number::LocalizedNumberFormatter* DecimalFormat::toNumberFormatter(UErrorC
status = U_MEMORY_ALLOCATION_ERROR;
return nullptr;
}
- return &*fields->formatter;
-}
-
-const number::LocalizedNumberFormatter& DecimalFormat::toNumberFormatter() const {
- UErrorCode localStatus = U_ZERO_ERROR;
- return *toNumberFormatter(localStatus);
+ return &fields->formatter;
}
/** Rebuilds the formatter object from the property bag. */
@@ -1608,9 +1597,9 @@ void DecimalFormat::touch(UErrorCode& status) {
// Since memory has already been allocated for the formatter, we can move assign a stack-allocated object
// and don't need to call new. (Which is slower and could possibly fail).
- *fields->formatter = NumberPropertyMapper::create(
- *fields->properties, *fields->symbols, fields->warehouse, *fields->exportedProperties, status).locale(
- locale);
+ fields->formatter = NumberPropertyMapper::create(
+ fields->properties, *fields->symbols, fields->warehouse, fields->exportedProperties, status
+ ).locale(locale);
// Do this after fields->exportedProperties are set up
setupFastFormat();
@@ -1620,13 +1609,13 @@ void DecimalFormat::touch(UErrorCode& status) {
delete fields->atomicCurrencyParser.exchange(nullptr);
// In order for the getters to work, we need to populate some fields in NumberFormat.
- NumberFormat::setCurrency(fields->exportedProperties->currency.get(status).getISOCurrency(), status);
- NumberFormat::setMaximumIntegerDigits(fields->exportedProperties->maximumIntegerDigits);
- NumberFormat::setMinimumIntegerDigits(fields->exportedProperties->minimumIntegerDigits);
- NumberFormat::setMaximumFractionDigits(fields->exportedProperties->maximumFractionDigits);
- NumberFormat::setMinimumFractionDigits(fields->exportedProperties->minimumFractionDigits);
+ NumberFormat::setCurrency(fields->exportedProperties.currency.get(status).getISOCurrency(), status);
+ NumberFormat::setMaximumIntegerDigits(fields->exportedProperties.maximumIntegerDigits);
+ NumberFormat::setMinimumIntegerDigits(fields->exportedProperties.minimumIntegerDigits);
+ NumberFormat::setMaximumFractionDigits(fields->exportedProperties.maximumFractionDigits);
+ NumberFormat::setMinimumFractionDigits(fields->exportedProperties.minimumFractionDigits);
// fImpl->properties, not fields->exportedProperties, since this information comes from the pattern:
- NumberFormat::setGroupingUsed(fields->properties->groupingUsed);
+ NumberFormat::setGroupingUsed(fields->properties.groupingUsed);
}
void DecimalFormat::touchNoError() {
@@ -1639,7 +1628,7 @@ void DecimalFormat::setPropertiesFromPattern(const UnicodeString& pattern, int32
if (U_SUCCESS(status)) {
// Cast workaround to get around putting the enum in the public header file
auto actualIgnoreRounding = static_cast<IgnoreRounding>(ignoreRounding);
- PatternParser::parseToExistingProperties(pattern, *fields->properties, actualIgnoreRounding, status);
+ PatternParser::parseToExistingProperties(pattern, fields->properties, actualIgnoreRounding, status);
}
}
@@ -1658,7 +1647,7 @@ const numparse::impl::NumberParserImpl* DecimalFormat::getParser(UErrorCode& sta
}
// Try computing the parser on our own
- auto* temp = NumberParserImpl::createParserFromProperties(*fields->properties, *fields->symbols, false, status);
+ auto* temp = NumberParserImpl::createParserFromProperties(fields->properties, *fields->symbols, false, status);
if (U_FAILURE(status)) {
return nullptr;
}
@@ -1691,7 +1680,7 @@ const numparse::impl::NumberParserImpl* DecimalFormat::getCurrencyParser(UErrorC
}
// Try computing the parser on our own
- auto* temp = NumberParserImpl::createParserFromProperties(*fields->properties, *fields->symbols, true, status);
+ auto* temp = NumberParserImpl::createParserFromProperties(fields->properties, *fields->symbols, true, status);
if (temp == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR;
// although we may still dereference, call sites should be guarded
@@ -1739,7 +1728,7 @@ DecimalFormat::fieldPositionIteratorHelper(const number::FormattedNumber& format
void DecimalFormat::setupFastFormat() {
// Check the majority of properties:
- if (!fields->properties->equalsDefaultExceptFastFormat()) {
+ if (!fields->properties.equalsDefaultExceptFastFormat()) {
trace("no fast format: equality\n");
fields->canUseFastFormat = false;
return;
@@ -1747,12 +1736,12 @@ void DecimalFormat::setupFastFormat() {
// Now check the remaining properties.
// Nontrivial affixes:
- UBool trivialPP = fields->properties->positivePrefixPattern.isEmpty();
- UBool trivialPS = fields->properties->positiveSuffixPattern.isEmpty();
- UBool trivialNP = fields->properties->negativePrefixPattern.isBogus() || (
- fields->properties->negativePrefixPattern.length() == 1 &&
- fields->properties->negativePrefixPattern.charAt(0) == u'-');
- UBool trivialNS = fields->properties->negativeSuffixPattern.isEmpty();
+ UBool trivialPP = fields->properties.positivePrefixPattern.isEmpty();
+ UBool trivialPS = fields->properties.positiveSuffixPattern.isEmpty();
+ UBool trivialNP = fields->properties.negativePrefixPattern.isBogus() || (
+ fields->properties.negativePrefixPattern.length() == 1 &&
+ fields->properties.negativePrefixPattern.charAt(0) == u'-');
+ UBool trivialNS = fields->properties.negativeSuffixPattern.isEmpty();
if (!trivialPP || !trivialPS || !trivialNP || !trivialNS) {
trace("no fast format: affixes\n");
fields->canUseFastFormat = false;
@@ -1760,8 +1749,8 @@ void DecimalFormat::setupFastFormat() {
}
// Grouping (secondary grouping is forbidden in equalsDefaultExceptFastFormat):
- bool groupingUsed = fields->properties->groupingUsed;
- int32_t groupingSize = fields->properties->groupingSize;
+ bool groupingUsed = fields->properties.groupingUsed;
+ int32_t groupingSize = fields->properties.groupingSize;
bool unusualGroupingSize = groupingSize > 0 && groupingSize != 3;
const UnicodeString& groupingString = fields->symbols->getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
if (groupingUsed && (unusualGroupingSize || groupingString.length() != 1)) {
@@ -1771,8 +1760,8 @@ void DecimalFormat::setupFastFormat() {
}
// Integer length:
- int32_t minInt = fields->exportedProperties->minimumIntegerDigits;
- int32_t maxInt = fields->exportedProperties->maximumIntegerDigits;
+ int32_t minInt = fields->exportedProperties.minimumIntegerDigits;
+ int32_t maxInt = fields->exportedProperties.maximumIntegerDigits;
// Fastpath supports up to only 10 digits (length of INT32_MIN)
if (minInt > 10) {
trace("no fast format: integer\n");
@@ -1781,7 +1770,7 @@ void DecimalFormat::setupFastFormat() {
}
// Fraction length (no fraction part allowed in fast path):
- int32_t minFrac = fields->exportedProperties->minimumFractionDigits;
+ int32_t minFrac = fields->exportedProperties.minimumFractionDigits;
if (minFrac > 0) {
trace("no fast format: fraction\n");
fields->canUseFastFormat = false;
diff --git a/deps/icu-small/source/i18n/double-conversion-bignum-dtoa.cpp b/deps/icu-small/source/i18n/double-conversion-bignum-dtoa.cpp
index 2add399f87..a95910df04 100644
--- a/deps/icu-small/source/i18n/double-conversion-bignum-dtoa.cpp
+++ b/deps/icu-small/source/i18n/double-conversion-bignum-dtoa.cpp
@@ -49,7 +49,7 @@ U_NAMESPACE_BEGIN
namespace double_conversion {
static int NormalizedExponent(uint64_t significand, int exponent) {
- ASSERT(significand != 0);
+ DOUBLE_CONVERSION_ASSERT(significand != 0);
while ((significand & Double::kHiddenBit) == 0) {
significand = significand << 1;
exponent = exponent - 1;
@@ -90,26 +90,26 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
// Generates 'requested_digits' after the decimal point.
static void BignumToFixed(int requested_digits, int* decimal_point,
Bignum* numerator, Bignum* denominator,
- Vector<char>(buffer), int* length);
+ Vector<char> buffer, int* length);
// Generates 'count' digits of numerator/denominator.
// Once 'count' digits have been produced rounds the result depending on the
// remainder (remainders of exactly .5 round upwards). Might update the
// decimal_point when rounding up (for example for 0.9999).
static void GenerateCountedDigits(int count, int* decimal_point,
Bignum* numerator, Bignum* denominator,
- Vector<char>(buffer), int* length);
+ Vector<char> buffer, int* length);
void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits,
Vector<char> buffer, int* length, int* decimal_point) {
- ASSERT(v > 0);
- ASSERT(!Double(v).IsSpecial());
+ DOUBLE_CONVERSION_ASSERT(v > 0);
+ DOUBLE_CONVERSION_ASSERT(!Double(v).IsSpecial());
uint64_t significand;
int exponent;
bool lower_boundary_is_closer;
if (mode == BIGNUM_DTOA_SHORTEST_SINGLE) {
float f = static_cast<float>(v);
- ASSERT(f == v);
+ DOUBLE_CONVERSION_ASSERT(f == v);
significand = Single(f).Significand();
exponent = Single(f).Exponent();
lower_boundary_is_closer = Single(f).LowerBoundaryIsCloser();
@@ -148,7 +148,7 @@ void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits,
// 4e-324. In this case the denominator needs fewer than 324*4 binary digits.
// The maximum double is 1.7976931348623157e308 which needs fewer than
// 308*4 binary digits.
- ASSERT(Bignum::kMaxSignificantBits >= 324*4);
+ DOUBLE_CONVERSION_ASSERT(Bignum::kMaxSignificantBits >= 324*4);
InitialScaledStartValues(significand, exponent, lower_boundary_is_closer,
estimated_power, need_boundary_deltas,
&numerator, &denominator,
@@ -177,7 +177,7 @@ void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits,
buffer, length);
break;
default:
- UNREACHABLE();
+ DOUBLE_CONVERSION_UNREACHABLE();
}
buffer[*length] = '\0';
}
@@ -209,7 +209,7 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
for (;;) {
uint16_t digit;
digit = numerator->DivideModuloIntBignum(*denominator);
- ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
+ DOUBLE_CONVERSION_ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
// digit = numerator / denominator (integer division).
// numerator = numerator % denominator.
buffer[(*length)++] = static_cast<char>(digit + '0');
@@ -255,7 +255,7 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
// loop would have stopped earlier.
// We still have an assert here in case the preconditions were not
// satisfied.
- ASSERT(buffer[(*length) - 1] != '9');
+ DOUBLE_CONVERSION_ASSERT(buffer[(*length) - 1] != '9');
buffer[(*length) - 1]++;
} else {
// Halfway case.
@@ -266,7 +266,7 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
if ((buffer[(*length) - 1] - '0') % 2 == 0) {
// Round down => Do nothing.
} else {
- ASSERT(buffer[(*length) - 1] != '9');
+ DOUBLE_CONVERSION_ASSERT(buffer[(*length) - 1] != '9');
buffer[(*length) - 1]++;
}
}
@@ -278,9 +278,9 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
// Round up.
// Note again that the last digit could not be '9' since this would have
// stopped the loop earlier.
- // We still have an ASSERT here, in case the preconditions were not
+ // We still have an DOUBLE_CONVERSION_ASSERT here, in case the preconditions were not
// satisfied.
- ASSERT(buffer[(*length) -1] != '9');
+ DOUBLE_CONVERSION_ASSERT(buffer[(*length) -1] != '9');
buffer[(*length) - 1]++;
return;
}
@@ -297,11 +297,11 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
static void GenerateCountedDigits(int count, int* decimal_point,
Bignum* numerator, Bignum* denominator,
Vector<char> buffer, int* length) {
- ASSERT(count >= 0);
+ DOUBLE_CONVERSION_ASSERT(count >= 0);
for (int i = 0; i < count - 1; ++i) {
uint16_t digit;
digit = numerator->DivideModuloIntBignum(*denominator);
- ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
+ DOUBLE_CONVERSION_ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
// digit = numerator / denominator (integer division).
// numerator = numerator % denominator.
buffer[i] = static_cast<char>(digit + '0');
@@ -314,7 +314,7 @@ static void GenerateCountedDigits(int count, int* decimal_point,
if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
digit++;
}
- ASSERT(digit <= 10);
+ DOUBLE_CONVERSION_ASSERT(digit <= 10);
buffer[count - 1] = static_cast<char>(digit + '0');
// Correct bad digits (in case we had a sequence of '9's). Propagate the
// carry until we hat a non-'9' or til we reach the first digit.
@@ -339,7 +339,7 @@ static void GenerateCountedDigits(int count, int* decimal_point,
// Input verifies: 1 <= (numerator + delta) / denominator < 10.
static void BignumToFixed(int requested_digits, int* decimal_point,
Bignum* numerator, Bignum* denominator,
- Vector<char>(buffer), int* length) {
+ Vector<char> buffer, int* length) {
// Note that we have to look at more than just the requested_digits, since
// a number could be rounded up. Example: v=0.5 with requested_digits=0.
// Even though the power of v equals 0 we can't just stop here.
@@ -355,7 +355,7 @@ static void BignumToFixed(int requested_digits, int* decimal_point,
} else if (-(*decimal_point) == requested_digits) {
// We only need to verify if the number rounds down or up.
// Ex: 0.04 and 0.06 with requested_digits == 1.
- ASSERT(*decimal_point == -requested_digits);
+ DOUBLE_CONVERSION_ASSERT(*decimal_point == -requested_digits);
// Initially the fraction lies in range (1, 10]. Multiply the denominator
// by 10 so that we can compare more easily.
denominator->Times10();
@@ -434,7 +434,7 @@ static void InitialScaledStartValuesPositiveExponent(
Bignum* numerator, Bignum* denominator,
Bignum* delta_minus, Bignum* delta_plus) {
// A positive exponent implies a positive power.
- ASSERT(estimated_power >= 0);
+ DOUBLE_CONVERSION_ASSERT(estimated_power >= 0);
// Since the estimated_power is positive we simply multiply the denominator
// by 10^estimated_power.
@@ -520,7 +520,7 @@ static void InitialScaledStartValuesNegativeExponentNegativePower(
// numerator = v * 10^-estimated_power * 2 * 2^-exponent.
// Remember: numerator has been abused as power_ten. So no need to assign it
// to itself.
- ASSERT(numerator == power_ten);
+ DOUBLE_CONVERSION_ASSERT(numerator == power_ten);
numerator->MultiplyByUInt64(significand);
// denominator = 2 * 2^-exponent with exponent < 0.
diff --git a/deps/icu-small/source/i18n/double-conversion-bignum.cpp b/deps/icu-small/source/i18n/double-conversion-bignum.cpp
index 5356923921..996d75c9f6 100644
--- a/deps/icu-small/source/i18n/double-conversion-bignum.cpp
+++ b/deps/icu-small/source/i18n/double-conversion-bignum.cpp
@@ -34,6 +34,9 @@
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
+#include <algorithm>
+#include <cstring>
+
// ICU PATCH: Customize header file paths for ICU.
#include "double-conversion-bignum.h"
@@ -44,136 +47,129 @@ U_NAMESPACE_BEGIN
namespace double_conversion {
-Bignum::Bignum()
- : bigits_buffer_(), bigits_(bigits_buffer_, kBigitCapacity), used_digits_(0), exponent_(0) {
- for (int i = 0; i < kBigitCapacity; ++i) {
- bigits_[i] = 0;
- }
+Bignum::Chunk& Bignum::RawBigit(const int index) {
+ DOUBLE_CONVERSION_ASSERT(static_cast<unsigned>(index) < kBigitCapacity);
+ return bigits_buffer_[index];
+}
+
+
+const Bignum::Chunk& Bignum::RawBigit(const int index) const {
+ DOUBLE_CONVERSION_ASSERT(static_cast<unsigned>(index) < kBigitCapacity);
+ return bigits_buffer_[index];
}
template<typename S>
-static int BitSize(S value) {
+static int BitSize(const S value) {
(void) value; // Mark variable as used.
return 8 * sizeof(value);
}
// Guaranteed to lie in one Bigit.
-void Bignum::AssignUInt16(uint16_t value) {
- ASSERT(kBigitSize >= BitSize(value));
+void Bignum::AssignUInt16(const uint16_t value) {
+ DOUBLE_CONVERSION_ASSERT(kBigitSize >= BitSize(value));
Zero();
- if (value == 0) return;
-
- EnsureCapacity(1);
- bigits_[0] = value;
- used_digits_ = 1;
+ if (value > 0) {
+ RawBigit(0) = value;
+ used_bigits_ = 1;
+ }
}
void Bignum::AssignUInt64(uint64_t value) {
- const int kUInt64Size = 64;
-
Zero();
- if (value == 0) return;
-
- int needed_bigits = kUInt64Size / kBigitSize + 1;
- EnsureCapacity(needed_bigits);
- for (int i = 0; i < needed_bigits; ++i) {
- bigits_[i] = value & kBigitMask;
- value = value >> kBigitSize;
+ for(int i = 0; value > 0; ++i) {
+ RawBigit(i) = value & kBigitMask;
+ value >>= kBigitSize;
+ ++used_bigits_;
}
- used_digits_ = needed_bigits;
- Clamp();
}
void Bignum::AssignBignum(const Bignum& other) {
exponent_ = other.exponent_;
- for (int i = 0; i < other.used_digits_; ++i) {
- bigits_[i] = other.bigits_[i];
+ for (int i = 0; i < other.used_bigits_; ++i) {
+ RawBigit(i) = other.RawBigit(i);
}
- // Clear the excess digits (if there were any).
- for (int i = other.used_digits_; i < used_digits_; ++i) {
- bigits_[i] = 0;
- }
- used_digits_ = other.used_digits_;
+ used_bigits_ = other.used_bigits_;
}
-static uint64_t ReadUInt64(Vector<const char> buffer,
- int from,
- int digits_to_read) {
+static uint64_t ReadUInt64(const Vector<const char> buffer,
+ const int from,
+ const int digits_to_read) {
uint64_t result = 0;
for (int i = from; i < from + digits_to_read; ++i) {
- int digit = buffer[i] - '0';
- ASSERT(0 <= digit && digit <= 9);
+ const int digit = buffer[i] - '0';
+ DOUBLE_CONVERSION_ASSERT(0 <= digit && digit <= 9);
result = result * 10 + digit;
}
return result;
}
-void Bignum::AssignDecimalString(Vector<const char> value) {
+void Bignum::AssignDecimalString(const Vector<const char> value) {
// 2^64 = 18446744073709551616 > 10^19
- const int kMaxUint64DecimalDigits = 19;
+ static const int kMaxUint64DecimalDigits = 19;
Zero();
int length = value.length();
- unsigned int pos = 0;
+ unsigned pos = 0;
// Let's just say that each digit needs 4 bits.
while (length >= kMaxUint64DecimalDigits) {
- uint64_t digits = ReadUInt64(value, pos, kMaxUint64DecimalDigits);
+ const uint64_t digits = ReadUInt64(value, pos, kMaxUint64DecimalDigits);
pos += kMaxUint64DecimalDigits;
length -= kMaxUint64DecimalDigits;
MultiplyByPowerOfTen(kMaxUint64DecimalDigits);
AddUInt64(digits);
}
- uint64_t digits = ReadUInt64(value, pos, length);
+ const uint64_t digits = ReadUInt64(value, pos, length);
MultiplyByPowerOfTen(length);
AddUInt64(digits);
Clamp();
}
-static int HexCharValue(char c) {
- if ('0' <= c && c <= '9') return c - '0';
- if ('a' <= c && c <= 'f') return 10 + c - 'a';
- ASSERT('A' <= c && c <= 'F');
+static uint64_t HexCharValue(const int c) {
+ if ('0' <= c && c <= '9') {
+ return c - '0';
+ }
+ if ('a' <= c && c <= 'f') {
+ return 10 + c - 'a';
+ }
+ DOUBLE_CONVERSION_ASSERT('A' <= c && c <= 'F');
return 10 + c - 'A';
}
+// Unlike AssignDecimalString(), this function is "only" used
+// for unit-tests and therefore not performance critical.
void Bignum::AssignHexString(Vector<const char> value) {
Zero();
- int length = value.length();
-
- int needed_bigits = length * 4 / kBigitSize + 1;
- EnsureCapacity(needed_bigits);
- int string_index = length - 1;
- for (int i = 0; i < needed_bigits - 1; ++i) {
- // These bigits are guaranteed to be "full".
- Chunk current_bigit = 0;
- for (int j = 0; j < kBigitSize / 4; j++) {
- current_bigit += HexCharValue(value[string_index--]) << (j * 4);
+ // Required capacity could be reduced by ignoring leading zeros.
+ EnsureCapacity(((value.length() * 4) + kBigitSize - 1) / kBigitSize);
+ DOUBLE_CONVERSION_ASSERT(sizeof(uint64_t) * 8 >= kBigitSize + 4); // TODO: static_assert
+ // Accumulates converted hex digits until at least kBigitSize bits.
+ // Works with non-factor-of-four kBigitSizes.
+ uint64_t tmp = 0; // Accumulates converted hex digits until at least
+ for (int cnt = 0; !value.is_empty(); value.pop_back()) {
+ tmp |= (HexCharValue(value.last()) << cnt);
+ if ((cnt += 4) >= kBigitSize) {
+ RawBigit(used_bigits_++) = (tmp & kBigitMask);
+ cnt -= kBigitSize;
+ tmp >>= kBigitSize;
}
- bigits_[i] = current_bigit;
- }
- used_digits_ = needed_bigits - 1;
-
- Chunk most_significant_bigit = 0; // Could be = 0;
- for (int j = 0; j <= string_index; ++j) {
- most_significant_bigit <<= 4;
- most_significant_bigit += HexCharValue(value[j]);
}
- if (most_significant_bigit != 0) {
- bigits_[used_digits_] = most_significant_bigit;
- used_digits_++;
+ if (tmp > 0) {
+ RawBigit(used_bigits_++) = tmp;
}
Clamp();
}
-void Bignum::AddUInt64(uint64_t operand) {
- if (operand == 0) return;
+void Bignum::AddUInt64(const uint64_t operand) {
+ if (operand == 0) {
+ return;
+ }
Bignum other;
other.AssignUInt64(operand);
AddBignum(other);
@@ -181,8 +177,8 @@ void Bignum::AddUInt64(uint64_t operand) {
void Bignum::AddBignum(const Bignum& other) {
- ASSERT(IsClamped());
- ASSERT(other.IsClamped());
+ DOUBLE_CONVERSION_ASSERT(IsClamped());
+ DOUBLE_CONVERSION_ASSERT(other.IsClamped());
// If this has a greater exponent than other append zero-bigits to this.
// After this call exponent_ <= other.exponent_.
@@ -200,48 +196,52 @@ void Bignum::AddBignum(const Bignum& other) {
// cccccccccccc 0000
// In both cases we might need a carry bigit.
- EnsureCapacity(1 + Max(BigitLength(), other.BigitLength()) - exponent_);
+ EnsureCapacity(1 + (std::max)(BigitLength(), other.BigitLength()) - exponent_);
Chunk carry = 0;
int bigit_pos = other.exponent_ - exponent_;
- ASSERT(bigit_pos >= 0);
- for (int i = 0; i < other.used_digits_; ++i) {
- Chunk sum = bigits_[bigit_pos] + other.bigits_[i] + carry;
- bigits_[bigit_pos] = sum & kBigitMask;
+ DOUBLE_CONVERSION_ASSERT(bigit_pos >= 0);
+ for (int i = used_bigits_; i < bigit_pos; ++i) {
+ RawBigit(i) = 0;
+ }
+ for (int i = 0; i < other.used_bigits_; ++i) {
+ const Chunk my = (bigit_pos < used_bigits_) ? RawBigit(bigit_pos) : 0;
+ const Chunk sum = my + other.RawBigit(i) + carry;
+ RawBigit(bigit_pos) = sum & kBigitMask;
carry = sum >> kBigitSize;
- bigit_pos++;
+ ++bigit_pos;
}
-
while (carry != 0) {
- Chunk sum = bigits_[bigit_pos] + carry;
- bigits_[bigit_pos] = sum & kBigitMask;
+ const Chunk my = (bigit_pos < used_bigits_) ? RawBigit(bigit_pos) : 0;
+ const Chunk sum = my + carry;
+ RawBigit(bigit_pos) = sum & kBigitMask;
carry = sum >> kBigitSize;
- bigit_pos++;
+ ++bigit_pos;
}
- used_digits_ = Max(bigit_pos, used_digits_);
- ASSERT(IsClamped());
+ used_bigits_ = (std::max)(bigit_pos, static_cast<int>(used_bigits_));
+ DOUBLE_CONVERSION_ASSERT(IsClamped());
}
void Bignum::SubtractBignum(const Bignum& other) {
- ASSERT(IsClamped());
- ASSERT(other.IsClamped());
+ DOUBLE_CONVERSION_ASSERT(IsClamped());
+ DOUBLE_CONVERSION_ASSERT(other.IsClamped());
// We require this to be bigger than other.
- ASSERT(LessEqual(other, *this));
+ DOUBLE_CONVERSION_ASSERT(LessEqual(other, *this));
Align(other);
- int offset = other.exponent_ - exponent_;
+ const int offset = other.exponent_ - exponent_;
Chunk borrow = 0;
int i;
- for (i = 0; i < other.used_digits_; ++i) {
- ASSERT((borrow == 0) || (borrow == 1));
- Chunk difference = bigits_[i + offset] - other.bigits_[i] - borrow;
- bigits_[i + offset] = difference & kBigitMask;
+ for (i = 0; i < other.used_bigits_; ++i) {
+ DOUBLE_CONVERSION_ASSERT((borrow == 0) || (borrow == 1));
+ const Chunk difference = RawBigit(i + offset) - other.RawBigit(i) - borrow;
+ RawBigit(i + offset) = difference & kBigitMask;
borrow = difference >> (kChunkSize - 1);
}
while (borrow != 0) {
- Chunk difference = bigits_[i + offset] - borrow;
- bigits_[i + offset] = difference & kBigitMask;
+ const Chunk difference = RawBigit(i + offset) - borrow;
+ RawBigit(i + offset) = difference & kBigitMask;
borrow = difference >> (kChunkSize - 1);
++i;
}
@@ -249,91 +249,105 @@ void Bignum::SubtractBignum(const Bignum& other) {
}
-void Bignum::ShiftLeft(int shift_amount) {
- if (used_digits_ == 0) return;
- exponent_ += shift_amount / kBigitSize;
- int local_shift = shift_amount % kBigitSize;
- EnsureCapacity(used_digits_ + 1);
+void Bignum::ShiftLeft(const int shift_amount) {
+ if (used_bigits_ == 0) {
+ return;
+ }
+ exponent_ += (shift_amount / kBigitSize);
+ const int local_shift = shift_amount % kBigitSize;
+ EnsureCapacity(used_bigits_ + 1);
BigitsShiftLeft(local_shift);
}
-void Bignum::MultiplyByUInt32(uint32_t factor) {
- if (factor == 1) return;
+void Bignum::MultiplyByUInt32(const uint32_t factor) {
+ if (factor == 1) {
+ return;
+ }
if (factor == 0) {
Zero();
return;
}
- if (used_digits_ == 0) return;
-
+ if (used_bigits_ == 0) {
+ return;
+ }
// The product of a bigit with the factor is of size kBigitSize + 32.
// Assert that this number + 1 (for the carry) fits into double chunk.
- ASSERT(kDoubleChunkSize >= kBigitSize + 32 + 1);
+ DOUBLE_CONVERSION_ASSERT(kDoubleChunkSize >= kBigitSize + 32 + 1);
DoubleChunk carry = 0;
- for (int i = 0; i < used_digits_; ++i) {
- DoubleChunk product = static_cast<DoubleChunk>(factor) * bigits_[i] + carry;
- bigits_[i] = static_cast<Chunk>(product & kBigitMask);
+ for (int i = 0; i < used_bigits_; ++i) {
+ const DoubleChunk product = static_cast<DoubleChunk>(factor) * RawBigit(i) + carry;
+ RawBigit(i) = static_cast<Chunk>(product & kBigitMask);
carry = (product >> kBigitSize);
}
while (carry != 0) {
- EnsureCapacity(used_digits_ + 1);
- bigits_[used_digits_] = carry & kBigitMask;
- used_digits_++;
+ EnsureCapacity(used_bigits_ + 1);
+ RawBigit(used_bigits_) = carry & kBigitMask;
+ used_bigits_++;
carry >>= kBigitSize;
}
}
-void Bignum::MultiplyByUInt64(uint64_t factor) {
- if (factor == 1) return;
+void Bignum::MultiplyByUInt64(const uint64_t factor) {
+ if (factor == 1) {
+ return;
+ }
if (factor == 0) {
Zero();
return;
}
- ASSERT(kBigitSize < 32);
+ if (used_bigits_ == 0) {
+ return;
+ }
+ DOUBLE_CONVERSION_ASSERT(kBigitSize < 32);
uint64_t carry = 0;
- uint64_t low = factor & 0xFFFFFFFF;
- uint64_t high = factor >> 32;
- for (int i = 0; i < used_digits_; ++i) {
- uint64_t product_low = low * bigits_[i];
- uint64_t product_high = high * bigits_[i];
- uint64_t tmp = (carry & kBigitMask) + product_low;
- bigits_[i] = tmp & kBigitMask;
+ const uint64_t low = factor & 0xFFFFFFFF;
+ const uint64_t high = factor >> 32;
+ for (int i = 0; i < used_bigits_; ++i) {
+ const uint64_t product_low = low * RawBigit(i);
+ const uint64_t product_high = high * RawBigit(i);
+ const uint64_t tmp = (carry & kBigitMask) + product_low;
+ RawBigit(i) = tmp & kBigitMask;
carry = (carry >> kBigitSize) + (tmp >> kBigitSize) +
(product_high << (32 - kBigitSize));
}
while (carry != 0) {
- EnsureCapacity(used_digits_ + 1);
- bigits_[used_digits_] = carry & kBigitMask;
- used_digits_++;
+ EnsureCapacity(used_bigits_ + 1);
+ RawBigit(used_bigits_) = carry & kBigitMask;
+ used_bigits_++;
carry >>= kBigitSize;
}
}
-void Bignum::MultiplyByPowerOfTen(int exponent) {
- const uint64_t kFive27 = UINT64_2PART_C(0x6765c793, fa10079d);
- const uint16_t kFive1 = 5;
- const uint16_t kFive2 = kFive1 * 5;
- const uint16_t kFive3 = kFive2 * 5;
- const uint16_t kFive4 = kFive3 * 5;
- const uint16_t kFive5 = kFive4 * 5;
- const uint16_t kFive6 = kFive5 * 5;
- const uint32_t kFive7 = kFive6 * 5;
- const uint32_t kFive8 = kFive7 * 5;
- const uint32_t kFive9 = kFive8 * 5;
- const uint32_t kFive10 = kFive9 * 5;
- const uint32_t kFive11 = kFive10 * 5;
- const uint32_t kFive12 = kFive11 * 5;
- const uint32_t kFive13 = kFive12 * 5;
- const uint32_t kFive1_to_12[] =
+void Bignum::MultiplyByPowerOfTen(const int exponent) {
+ static const uint64_t kFive27 = DOUBLE_CONVERSION_UINT64_2PART_C(0x6765c793, fa10079d);
+ static const uint16_t kFive1 = 5;
+ static const uint16_t kFive2 = kFive1 * 5;
+ static const uint16_t kFive3 = kFive2 * 5;
+ static const uint16_t kFive4 = kFive3 * 5;
+ static const uint16_t kFive5 = kFive4 * 5;
+ static const uint16_t kFive6 = kFive5 * 5;
+ static const uint32_t kFive7 = kFive6 * 5;
+ static const uint32_t kFive8 = kFive7 * 5;
+ static const uint32_t kFive9 = kFive8 * 5;
+ static const uint32_t kFive10 = kFive9 * 5;
+ static const uint32_t kFive11 = kFive10 * 5;
+ static const uint32_t kFive12 = kFive11 * 5;
+ static const uint32_t kFive13 = kFive12 * 5;
+ static const uint32_t kFive1_to_12[] =
{ kFive1, kFive2, kFive3, kFive4, kFive5, kFive6,
kFive7, kFive8, kFive9, kFive10, kFive11, kFive12 };
- ASSERT(exponent >= 0);
- if (exponent == 0) return;
- if (used_digits_ == 0) return;
+ DOUBLE_CONVERSION_ASSERT(exponent >= 0);
+ if (exponent == 0) {
+ return;
+ }
+ if (used_bigits_ == 0) {
+ return;
+ }
// We shift by exponent at the end just before returning.
int remaining_exponent = exponent;
while (remaining_exponent >= 27) {
@@ -352,8 +366,8 @@ void Bignum::MultiplyByPowerOfTen(int exponent) {
void Bignum::Square() {
- ASSERT(IsClamped());
- int product_length = 2 * used_digits_;
+ DOUBLE_CONVERSION_ASSERT(IsClamped());
+ const int product_length = 2 * used_bigits_;
EnsureCapacity(product_length);
// Comba multiplication: compute each column separately.
@@ -368,64 +382,64 @@ void Bignum::Square() {
//
// Assert that the additional number of bits in a DoubleChunk are enough to
// sum up used_digits of Bigit*Bigit.
- if ((1 << (2 * (kChunkSize - kBigitSize))) <= used_digits_) {
- UNIMPLEMENTED();
+ if ((1 << (2 * (kChunkSize - kBigitSize))) <= used_bigits_) {
+ DOUBLE_CONVERSION_UNIMPLEMENTED();
}
DoubleChunk accumulator = 0;
// First shift the digits so we don't overwrite them.
- int copy_offset = used_digits_;
- for (int i = 0; i < used_digits_; ++i) {
- bigits_[copy_offset + i] = bigits_[i];
+ const int copy_offset = used_bigits_;
+ for (int i = 0; i < used_bigits_; ++i) {
+ RawBigit(copy_offset + i) = RawBigit(i);
}
// We have two loops to avoid some 'if's in the loop.
- for (int i = 0; i < used_digits_; ++i) {
+ for (int i = 0; i < used_bigits_; ++i) {
// Process temporary digit i with power i.
// The sum of the two indices must be equal to i.
int bigit_index1 = i;
int bigit_index2 = 0;
// Sum all of the sub-products.
while (bigit_index1 >= 0) {
- Chunk chunk1 = bigits_[copy_offset + bigit_index1];
- Chunk chunk2 = bigits_[copy_offset + bigit_index2];
+ const Chunk chunk1 = RawBigit(copy_offset + bigit_index1);
+ const Chunk chunk2 = RawBigit(copy_offset + bigit_index2);
accumulator += static_cast<DoubleChunk>(chunk1) * chunk2;
bigit_index1--;
bigit_index2++;
}
- bigits_[i] = static_cast<Chunk>(accumulator) & kBigitMask;
+ RawBigit(i) = static_cast<Chunk>(accumulator) & kBigitMask;
accumulator >>= kBigitSize;
}
- for (int i = used_digits_; i < product_length; ++i) {
- int bigit_index1 = used_digits_ - 1;
+ for (int i = used_bigits_; i < product_length; ++i) {
+ int bigit_index1 = used_bigits_ - 1;
int bigit_index2 = i - bigit_index1;
// Invariant: sum of both indices is again equal to i.
// Inner loop runs 0 times on last iteration, emptying accumulator.
- while (bigit_index2 < used_digits_) {
- Chunk chunk1 = bigits_[copy_offset + bigit_index1];
- Chunk chunk2 = bigits_[copy_offset + bigit_index2];
+ while (bigit_index2 < used_bigits_) {
+ const Chunk chunk1 = RawBigit(copy_offset + bigit_index1);
+ const Chunk chunk2 = RawBigit(copy_offset + bigit_index2);
accumulator += static_cast<DoubleChunk>(chunk1) * chunk2;
bigit_index1--;
bigit_index2++;
}
- // The overwritten bigits_[i] will never be read in further loop iterations,
+ // The overwritten RawBigit(i) will never be read in further loop iterations,
// because bigit_index1 and bigit_index2 are always greater
- // than i - used_digits_.
- bigits_[i] = static_cast<Chunk>(accumulator) & kBigitMask;
+ // than i - used_bigits_.
+ RawBigit(i) = static_cast<Chunk>(accumulator) & kBigitMask;
accumulator >>= kBigitSize;
}
// Since the result was guaranteed to lie inside the number the
// accumulator must be 0 now.
- ASSERT(accumulator == 0);
+ DOUBLE_CONVERSION_ASSERT(accumulator == 0);
// Don't forget to update the used_digits and the exponent.
- used_digits_ = product_length;
+ used_bigits_ = product_length;
exponent_ *= 2;
Clamp();
}
-void Bignum::AssignPowerUInt16(uint16_t base, int power_exponent) {
- ASSERT(base != 0);
- ASSERT(power_exponent >= 0);
+void Bignum::AssignPowerUInt16(uint16_t base, const int power_exponent) {
+ DOUBLE_CONVERSION_ASSERT(base != 0);
+ DOUBLE_CONVERSION_ASSERT(power_exponent >= 0);
if (power_exponent == 0) {
AssignUInt16(1);
return;
@@ -445,7 +459,7 @@ void Bignum::AssignPowerUInt16(uint16_t base, int power_exponent) {
tmp_base >>= 1;
bit_size++;
}
- int final_size = bit_size * power_exponent;
+ const int final_size = bit_size * power_exponent;
// 1 extra bigit for the shifting, and one for rounded final_size.
EnsureCapacity(final_size / kBigitSize + 2);
@@ -466,10 +480,10 @@ void Bignum::AssignPowerUInt16(uint16_t base, int power_exponent) {
// Verify that there is enough space in this_value to perform the
// multiplication. The first bit_size bits must be 0.
if ((power_exponent & mask) != 0) {
- ASSERT(bit_size > 0);
- uint64_t base_bits_mask =
- ~((static_cast<uint64_t>(1) << (64 - bit_size)) - 1);
- bool high_bits_zero = (this_value & base_bits_mask) == 0;
+ DOUBLE_CONVERSION_ASSERT(bit_size > 0);
+ const uint64_t base_bits_mask =
+ ~((static_cast<uint64_t>(1) << (64 - bit_size)) - 1);
+ const bool high_bits_zero = (this_value & base_bits_mask) == 0;
if (high_bits_zero) {
this_value *= base;
} else {
@@ -499,9 +513,9 @@ void Bignum::AssignPowerUInt16(uint16_t base, int power_exponent) {
// Precondition: this/other < 16bit.
uint16_t Bignum::DivideModuloIntBignum(const Bignum& other) {
- ASSERT(IsClamped());
- ASSERT(other.IsClamped());
- ASSERT(other.used_digits_ > 0);
+ DOUBLE_CONVERSION_ASSERT(IsClamped());
+ DOUBLE_CONVERSION_ASSERT(other.IsClamped());
+ DOUBLE_CONVERSION_ASSERT(other.used_bigits_ > 0);
// Easy case: if we have less digits than the divisor than the result is 0.
// Note: this handles the case where this == 0, too.
@@ -519,34 +533,34 @@ uint16_t Bignum::DivideModuloIntBignum(const Bignum& other) {
// This naive approach is extremely inefficient if `this` divided by other
// is big. This function is implemented for doubleToString where
// the result should be small (less than 10).
- ASSERT(other.bigits_[other.used_digits_ - 1] >= ((1 << kBigitSize) / 16));
- ASSERT(bigits_[used_digits_ - 1] < 0x10000);
+ DOUBLE_CONVERSION_ASSERT(other.RawBigit(other.used_bigits_ - 1) >= ((1 << kBigitSize) / 16));
+ DOUBLE_CONVERSION_ASSERT(RawBigit(used_bigits_ - 1) < 0x10000);
// Remove the multiples of the first digit.
// Example this = 23 and other equals 9. -> Remove 2 multiples.
- result += static_cast<uint16_t>(bigits_[used_digits_ - 1]);
- SubtractTimes(other, bigits_[used_digits_ - 1]);
+ result += static_cast<uint16_t>(RawBigit(used_bigits_ - 1));
+ SubtractTimes(other, RawBigit(used_bigits_ - 1));
}
- ASSERT(BigitLength() == other.BigitLength());
+ DOUBLE_CONVERSION_ASSERT(BigitLength() == other.BigitLength());
// Both bignums are at the same length now.
// Since other has more than 0 digits we know that the access to
- // bigits_[used_digits_ - 1] is safe.
- Chunk this_bigit = bigits_[used_digits_ - 1];
- Chunk other_bigit = other.bigits_[other.used_digits_ - 1];
+ // RawBigit(used_bigits_ - 1) is safe.
+ const Chunk this_bigit = RawBigit(used_bigits_ - 1);
+ const Chunk other_bigit = other.RawBigit(other.used_bigits_ - 1);
- if (other.used_digits_ == 1) {
+ if (other.used_bigits_ == 1) {
// Shortcut for easy (and common) case.
int quotient = this_bigit / other_bigit;
- bigits_[used_digits_ - 1] = this_bigit - other_bigit * quotient;
- ASSERT(quotient < 0x10000);
+ RawBigit(used_bigits_ - 1) = this_bigit - other_bigit * quotient;
+ DOUBLE_CONVERSION_ASSERT(quotient < 0x10000);
result += static_cast<uint16_t>(quotient);
Clamp();
return result;
}
- int division_estimate = this_bigit / (other_bigit + 1);
- ASSERT(division_estimate < 0x10000);
+ const int division_estimate = this_bigit / (other_bigit + 1);
+ DOUBLE_CONVERSION_ASSERT(division_estimate < 0x10000);
result += static_cast<uint16_t>(division_estimate);
SubtractTimes(other, division_estimate);
@@ -566,7 +580,7 @@ uint16_t Bignum::DivideModuloIntBignum(const Bignum& other) {
template<typename S>
static int SizeInHexChars(S number) {
- ASSERT(number > 0);
+ DOUBLE_CONVERSION_ASSERT(number > 0);
int result = 0;
while (number != 0) {
number >>= 4;
@@ -576,29 +590,35 @@ static int SizeInHexChars(S number) {
}
-static char HexCharOfValue(int value) {
- ASSERT(0 <= value && value <= 16);
- if (value < 10) return static_cast<char>(value + '0');
+static char HexCharOfValue(const int value) {
+ DOUBLE_CONVERSION_ASSERT(0 <= value && value <= 16);
+ if (value < 10) {
+ return static_cast<char>(value + '0');
+ }
return static_cast<char>(value - 10 + 'A');
}
-bool Bignum::ToHexString(char* buffer, int buffer_size) const {
- ASSERT(IsClamped());
+bool Bignum::ToHexString(char* buffer, const int buffer_size) const {
+ DOUBLE_CONVERSION_ASSERT(IsClamped());
// Each bigit must be printable as separate hex-character.
- ASSERT(kBigitSize % 4 == 0);
- const int kHexCharsPerBigit = kBigitSize / 4;
+ DOUBLE_CONVERSION_ASSERT(kBigitSize % 4 == 0);
+ static const int kHexCharsPerBigit = kBigitSize / 4;
- if (used_digits_ == 0) {
- if (buffer_size < 2) return false;
+ if (used_bigits_ == 0) {
+ if (buffer_size < 2) {
+ return false;
+ }
buffer[0] = '0';
buffer[1] = '\0';
return true;
}
// We add 1 for the terminating '\0' character.
- int needed_chars = (BigitLength() - 1) * kHexCharsPerBigit +
- SizeInHexChars(bigits_[used_digits_ - 1]) + 1;
- if (needed_chars > buffer_size) return false;
+ const int needed_chars = (BigitLength() - 1) * kHexCharsPerBigit +
+ SizeInHexChars(RawBigit(used_bigits_ - 1)) + 1;
+ if (needed_chars > buffer_size) {
+ return false;
+ }
int string_index = needed_chars - 1;
buffer[string_index--] = '\0';
for (int i = 0; i < exponent_; ++i) {
@@ -606,15 +626,15 @@ bool Bignum::ToHexString(char* buffer, int buffer_size) const {
buffer[string_index--] = '0';
}
}
- for (int i = 0; i < used_digits_ - 1; ++i) {
- Chunk current_bigit = bigits_[i];
+ for (int i = 0; i < used_bigits_ - 1; ++i) {
+ Chunk current_bigit = RawBigit(i);
for (int j = 0; j < kHexCharsPerBigit; ++j) {
buffer[string_index--] = HexCharOfValue(current_bigit & 0xF);
current_bigit >>= 4;
}
}
// And finally the last bigit.
- Chunk most_significant_bigit = bigits_[used_digits_ - 1];
+ Chunk most_significant_bigit = RawBigit(used_bigits_ - 1);
while (most_significant_bigit != 0) {
buffer[string_index--] = HexCharOfValue(most_significant_bigit & 0xF);
most_significant_bigit >>= 4;
@@ -623,25 +643,37 @@ bool Bignum::ToHexString(char* buffer, int buffer_size) const {
}
-Bignum::Chunk Bignum::BigitAt(int index) const {
- if (index >= BigitLength()) return 0;
- if (index < exponent_) return 0;
- return bigits_[index - exponent_];
+Bignum::Chunk Bignum::BigitOrZero(const int index) const {
+ if (index >= BigitLength()) {
+ return 0;
+ }
+ if (index < exponent_) {
+ return 0;
+ }
+ return RawBigit(index - exponent_);
}
int Bignum::Compare(const Bignum& a, const Bignum& b) {
- ASSERT(a.IsClamped());
- ASSERT(b.IsClamped());
- int bigit_length_a = a.BigitLength();
- int bigit_length_b = b.BigitLength();
- if (bigit_length_a < bigit_length_b) return -1;
- if (bigit_length_a > bigit_length_b) return +1;
- for (int i = bigit_length_a - 1; i >= Min(a.exponent_, b.exponent_); --i) {
- Chunk bigit_a = a.BigitAt(i);
- Chunk bigit_b = b.BigitAt(i);
- if (bigit_a < bigit_b) return -1;
- if (bigit_a > bigit_b) return +1;
+ DOUBLE_CONVERSION_ASSERT(a.IsClamped());
+ DOUBLE_CONVERSION_ASSERT(b.IsClamped());
+ const int bigit_length_a = a.BigitLength();
+ const int bigit_length_b = b.BigitLength();
+ if (bigit_length_a < bigit_length_b) {
+ return -1;
+ }
+ if (bigit_length_a > bigit_length_b) {
+ return +1;
+ }
+ for (int i = bigit_length_a - 1; i >= (std::min)(a.exponent_, b.exponent_); --i) {
+ const Chunk bigit_a = a.BigitOrZero(i);
+ const Chunk bigit_b = b.BigitOrZero(i);
+ if (bigit_a < bigit_b) {
+ return -1;
+ }
+ if (bigit_a > bigit_b) {
+ return +1;
+ }
// Otherwise they are equal up to this digit. Try the next digit.
}
return 0;
@@ -649,14 +681,18 @@ int Bignum::Compare(const Bignum& a, const Bignum& b) {
int Bignum::PlusCompare(const Bignum& a, const Bignum& b, const Bignum& c) {
- ASSERT(a.IsClamped());
- ASSERT(b.IsClamped());
- ASSERT(c.IsClamped());
+ DOUBLE_CONVERSION_ASSERT(a.IsClamped());
+ DOUBLE_CONVERSION_ASSERT(b.IsClamped());
+ DOUBLE_CONVERSION_ASSERT(c.IsClamped());
if (a.BigitLength() < b.BigitLength()) {
return PlusCompare(b, a, c);
}
- if (a.BigitLength() + 1 < c.BigitLength()) return -1;
- if (a.BigitLength() > c.BigitLength()) return +1;
+ if (a.BigitLength() + 1 < c.BigitLength()) {
+ return -1;
+ }
+ if (a.BigitLength() > c.BigitLength()) {
+ return +1;
+ }
// The exponent encodes 0-bigits. So if there are more 0-digits in 'a' than
// 'b' has digits, then the bigit-length of 'a'+'b' must be equal to the one
// of 'a'.
@@ -666,92 +702,83 @@ int Bignum::PlusCompare(const Bignum& a, const Bignum& b, const Bignum& c) {
Chunk borrow = 0;
// Starting at min_exponent all digits are == 0. So no need to compare them.
- int min_exponent = Min(Min(a.exponent_, b.exponent_), c.exponent_);
+ const int min_exponent = (std::min)((std::min)(a.exponent_, b.exponent_), c.exponent_);
for (int i = c.BigitLength() - 1; i >= min_exponent; --i) {
- Chunk chunk_a = a.BigitAt(i);
- Chunk chunk_b = b.BigitAt(i);
- Chunk chunk_c = c.BigitAt(i);
- Chunk sum = chunk_a + chunk_b;
+ const Chunk chunk_a = a.BigitOrZero(i);
+ const Chunk chunk_b = b.BigitOrZero(i);
+ const Chunk chunk_c = c.BigitOrZero(i);
+ const Chunk sum = chunk_a + chunk_b;
if (sum > chunk_c + borrow) {
return +1;
} else {
borrow = chunk_c + borrow - sum;
- if (borrow > 1) return -1;
+ if (borrow > 1) {
+ return -1;
+ }
borrow <<= kBigitSize;
}
}
- if (borrow == 0) return 0;
+ if (borrow == 0) {
+ return 0;
+ }
return -1;
}
void Bignum::Clamp() {
- while (used_digits_ > 0 && bigits_[used_digits_ - 1] == 0) {
- used_digits_--;
+ while (used_bigits_ > 0 && RawBigit(used_bigits_ - 1) == 0) {
+ used_bigits_--;
}
- if (used_digits_ == 0) {
+ if (used_bigits_ == 0) {
// Zero.
exponent_ = 0;
}
}
-bool Bignum::IsClamped() const {
- return used_digits_ == 0 || bigits_[used_digits_ - 1] != 0;
-}
-
-
-void Bignum::Zero() {
- for (int i = 0; i < used_digits_; ++i) {
- bigits_[i] = 0;
- }
- used_digits_ = 0;
- exponent_ = 0;
-}
-
-
void Bignum::Align(const Bignum& other) {
if (exponent_ > other.exponent_) {
- // If "X" represents a "hidden" digit (by the exponent) then we are in the
+ // If "X" represents a "hidden" bigit (by the exponent) then we are in the
// following case (a == this, b == other):
// a: aaaaaaXXXX or a: aaaaaXXX
// b: bbbbbbX b: bbbbbbbbXX
// We replace some of the hidden digits (X) of a with 0 digits.
// a: aaaaaa000X or a: aaaaa0XX
- int zero_digits = exponent_ - other.exponent_;
- EnsureCapacity(used_digits_ + zero_digits);
- for (int i = used_digits_ - 1; i >= 0; --i) {
- bigits_[i + zero_digits] = bigits_[i];
+ const int zero_bigits = exponent_ - other.exponent_;
+ EnsureCapacity(used_bigits_ + zero_bigits);
+ for (int i = used_bigits_ - 1; i >= 0; --i) {
+ RawBigit(i + zero_bigits) = RawBigit(i);
}
- for (int i = 0; i < zero_digits; ++i) {
- bigits_[i] = 0;
+ for (int i = 0; i < zero_bigits; ++i) {
+ RawBigit(i) = 0;
}
- used_digits_ += zero_digits;
- exponent_ -= zero_digits;
- ASSERT(used_digits_ >= 0);
- ASSERT(exponent_ >= 0);
+ used_bigits_ += zero_bigits;
+ exponent_ -= zero_bigits;
+
+ DOUBLE_CONVERSION_ASSERT(used_bigits_ >= 0);
+ DOUBLE_CONVERSION_ASSERT(exponent_ >= 0);
}
}
-void Bignum::BigitsShiftLeft(int shift_amount) {
- ASSERT(shift_amount < kBigitSize);
- ASSERT(shift_amount >= 0);
+void Bignum::BigitsShiftLeft(const int shift_amount) {
+ DOUBLE_CONVERSION_ASSERT(shift_amount < kBigitSize);
+ DOUBLE_CONVERSION_ASSERT(shift_amount >= 0);
Chunk carry = 0;
- for (int i = 0; i < used_digits_; ++i) {
- Chunk new_carry = bigits_[i] >> (kBigitSize - shift_amount);
- bigits_[i] = ((bigits_[i] << shift_amount) + carry) & kBigitMask;
+ for (int i = 0; i < used_bigits_; ++i) {
+ const Chunk new_carry = RawBigit(i) >> (kBigitSize - shift_amount);
+ RawBigit(i) = ((RawBigit(i) << shift_amount) + carry) & kBigitMask;
carry = new_carry;
}
if (carry != 0) {
- bigits_[used_digits_] = carry;
- used_digits_++;
+ RawBigit(used_bigits_) = carry;
+ used_bigits_++;
}
}
-void Bignum::SubtractTimes(const Bignum& other, int factor) {
- ASSERT(exponent_ <= other.exponent_);
+void Bignum::SubtractTimes(const Bignum& other, const int factor) {
+ DOUBLE_CONVERSION_ASSERT(exponent_ <= other.exponent_);
if (factor < 3) {
for (int i = 0; i < factor; ++i) {
SubtractBignum(other);
@@ -759,19 +786,21 @@ void Bignum::SubtractTimes(const Bignum& other, int factor) {
return;
}
Chunk borrow = 0;
- int exponent_diff = other.exponent_ - exponent_;
- for (int i = 0; i < other.used_digits_; ++i) {
- DoubleChunk product = static_cast<DoubleChunk>(factor) * other.bigits_[i];
- DoubleChunk remove = borrow + product;
- Chunk difference = bigits_[i + exponent_diff] - (remove & kBigitMask);
- bigits_[i + exponent_diff] = difference & kBigitMask;
+ const int exponent_diff = other.exponent_ - exponent_;
+ for (int i = 0; i < other.used_bigits_; ++i) {
+ const DoubleChunk product = static_cast<DoubleChunk>(factor) * other.RawBigit(i);
+ const DoubleChunk remove = borrow + product;
+ const Chunk difference = RawBigit(i + exponent_diff) - (remove & kBigitMask);
+ RawBigit(i + exponent_diff) = difference & kBigitMask;
borrow = static_cast<Chunk>((difference >> (kChunkSize - 1)) +
(remove >> kBigitSize));
}
- for (int i = other.used_digits_ + exponent_diff; i < used_digits_; ++i) {
- if (borrow == 0) return;
- Chunk difference = bigits_[i] - borrow;
- bigits_[i] = difference & kBigitMask;
+ for (int i = other.used_bigits_ + exponent_diff; i < used_bigits_; ++i) {
+ if (borrow == 0) {
+ return;
+ }
+ const Chunk difference = RawBigit(i) - borrow;
+ RawBigit(i) = difference & kBigitMask;
borrow = difference >> (kChunkSize - 1);
}
Clamp();
diff --git a/deps/icu-small/source/i18n/double-conversion-bignum.h b/deps/icu-small/source/i18n/double-conversion-bignum.h
index d39a3dee01..bae900a15a 100644
--- a/deps/icu-small/source/i18n/double-conversion-bignum.h
+++ b/deps/icu-small/source/i18n/double-conversion-bignum.h
@@ -53,26 +53,27 @@ class Bignum {
// exponent.
static const int kMaxSignificantBits = 3584;
- Bignum();
- void AssignUInt16(uint16_t value);
+ Bignum() : used_bigits_(0), exponent_(0) {}
+
+ void AssignUInt16(const uint16_t value);
void AssignUInt64(uint64_t value);
void AssignBignum(const Bignum& other);
- void AssignDecimalString(Vector<const char> value);
- void AssignHexString(Vector<const char> value);
+ void AssignDecimalString(const Vector<const char> value);
+ void AssignHexString(const Vector<const char> value);
- void AssignPowerUInt16(uint16_t base, int exponent);
+ void AssignPowerUInt16(uint16_t base, const int exponent);
- void AddUInt64(uint64_t operand);
+ void AddUInt64(const uint64_t operand);
void AddBignum(const Bignum& other);
// Precondition: this >= other.
void SubtractBignum(const Bignum& other);
void Square();
- void ShiftLeft(int shift_amount);
- void MultiplyByUInt32(uint32_t factor);
- void MultiplyByUInt64(uint64_t factor);
- void MultiplyByPowerOfTen(int exponent);
+ void ShiftLeft(const int shift_amount);
+ void MultiplyByUInt32(const uint32_t factor);
+ void MultiplyByUInt64(const uint64_t factor);
+ void MultiplyByPowerOfTen(const int exponent);
void Times10() { return MultiplyByUInt32(10); }
// Pseudocode:
// int result = this / other;
@@ -80,7 +81,7 @@ class Bignum {
// In the worst case this function is in O(this/other).
uint16_t DivideModuloIntBignum(const Bignum& other);
- bool ToHexString(char* buffer, int buffer_size) const;
+ bool ToHexString(char* buffer, const int buffer_size) const;
// Returns
// -1 if a < b,
@@ -124,33 +125,40 @@ class Bignum {
// grow. There are no checks if the stack-allocated space is sufficient.
static const int kBigitCapacity = kMaxSignificantBits / kBigitSize;
- void EnsureCapacity(int size) {
+ static void EnsureCapacity(const int size) {
if (size > kBigitCapacity) {
- UNREACHABLE();
+ DOUBLE_CONVERSION_UNREACHABLE();
}
}
void Align(const Bignum& other);
void Clamp();
- bool IsClamped() const;
- void Zero();
+ bool IsClamped() const {
+ return used_bigits_ == 0 || RawBigit(used_bigits_ - 1) != 0;
+ }
+ void Zero() {
+ used_bigits_ = 0;
+ exponent_ = 0;
+ }
// Requires this to have enough capacity (no tests done).
- // Updates used_digits_ if necessary.
+ // Updates used_bigits_ if necessary.
// shift_amount must be < kBigitSize.
- void BigitsShiftLeft(int shift_amount);
- // BigitLength includes the "hidden" digits encoded in the exponent.
- int BigitLength() const { return used_digits_ + exponent_; }
- Chunk BigitAt(int index) const;
- void SubtractTimes(const Bignum& other, int factor);
-
+ void BigitsShiftLeft(const int shift_amount);
+ // BigitLength includes the "hidden" bigits encoded in the exponent.
+ int BigitLength() const { return used_bigits_ + exponent_; }
+ Chunk& RawBigit(const int index);
+ const Chunk& RawBigit(const int index) const;
+ Chunk BigitOrZero(const int index) const;
+ void SubtractTimes(const Bignum& other, const int factor);
+
+ // The Bignum's value is value(bigits_buffer_) * 2^(exponent_ * kBigitSize),
+ // where the value of the buffer consists of the lower kBigitSize bits of
+ // the first used_bigits_ Chunks in bigits_buffer_, first chunk has lowest
+ // significant bits.
+ int16_t used_bigits_;
+ int16_t exponent_;
Chunk bigits_buffer_[kBigitCapacity];
- // A vector backed by bigits_buffer_. This way accesses to the array are
- // checked for out-of-bounds errors.
- Vector<Chunk> bigits_;
- int used_digits_;
- // The Bignum's value equals value(bigits_) * 2^(exponent_ * kBigitSize).
- int exponent_;
-
- DC_DISALLOW_COPY_AND_ASSIGN(Bignum);
+
+ DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(Bignum);
};
} // namespace double_conversion
diff --git a/deps/icu-small/source/i18n/double-conversion-cached-powers.cpp b/deps/icu-small/source/i18n/double-conversion-cached-powers.cpp
index e1b66d2c65..3bc35c8aaf 100644
--- a/deps/icu-small/source/i18n/double-conversion-cached-powers.cpp
+++ b/deps/icu-small/source/i18n/double-conversion-cached-powers.cpp
@@ -49,6 +49,8 @@ U_NAMESPACE_BEGIN
namespace double_conversion {
+namespace PowersOfTenCache {
+
struct CachedPower {
uint64_t significand;
int16_t binary_exponent;
@@ -56,103 +58,99 @@ struct CachedPower {
};
static const CachedPower kCachedPowers[] = {
- {UINT64_2PART_C(0xfa8fd5a0, 081c0288), -1220, -348},
- {UINT64_2PART_C(0xbaaee17f, a23ebf76), -1193, -340},
- {UINT64_2PART_C(0x8b16fb20, 3055ac76), -1166, -332},
- {UINT64_2PART_C(0xcf42894a, 5dce35ea), -1140, -324},
- {UINT64_2PART_C(0x9a6bb0aa, 55653b2d), -1113, -316},
- {UINT64_2PART_C(0xe61acf03, 3d1a45df), -1087, -308},
- {UINT64_2PART_C(0xab70fe17, c79ac6ca), -1060, -300},
- {UINT64_2PART_C(0xff77b1fc, bebcdc4f), -1034, -292},
- {UINT64_2PART_C(0xbe5691ef, 416bd60c), -1007, -284},
- {UINT64_2PART_C(0x8dd01fad, 907ffc3c), -980, -276},
- {UINT64_2PART_C(0xd3515c28, 31559a83), -954, -268},
- {UINT64_2PART_C(0x9d71ac8f, ada6c9b5), -927, -260},
- {UINT64_2PART_C(0xea9c2277, 23ee8bcb), -901, -252},
- {UINT64_2PART_C(0xaecc4991, 4078536d), -874, -244},
- {UINT64_2PART_C(0x823c1279, 5db6ce57), -847, -236},
- {UINT64_2PART_C(0xc2109436, 4dfb5637), -821, -228},
- {UINT64_2PART_C(0x9096ea6f, 3848984f), -794, -220},
- {UINT64_2PART_C(0xd77485cb, 25823ac7), -768, -212},
- {UINT64_2PART_C(0xa086cfcd, 97bf97f4), -741, -204},
- {UINT64_2PART_C(0xef340a98, 172aace5), -715, -196},
- {UINT64_2PART_C(0xb23867fb, 2a35b28e), -688, -188},
- {UINT64_2PART_C(0x84c8d4df, d2c63f3b), -661, -180},
- {UINT64_2PART_C(0xc5dd4427, 1ad3cdba), -635, -172},
- {UINT64_2PART_C(0x936b9fce, bb25c996), -608, -164},
- {UINT64_2PART_C(0xdbac6c24, 7d62a584), -582, -156},
- {UINT64_2PART_C(0xa3ab6658, 0d5fdaf6), -555, -148},
- {UINT64_2PART_C(0xf3e2f893, dec3f126), -529, -140},
- {UINT64_2PART_C(0xb5b5ada8, aaff80b8), -502, -132},
- {UINT64_2PART_C(0x87625f05, 6c7c4a8b), -475, -124},
- {UINT64_2PART_C(0xc9bcff60, 34c13053), -449, -116},
- {UINT64_2PART_C(0x964e858c, 91ba2655), -422, -108},
- {UINT64_2PART_C(0xdff97724, 70297ebd), -396, -100},
- {UINT64_2PART_C(0xa6dfbd9f, b8e5b88f), -369, -92},
- {UINT64_2PART_C(0xf8a95fcf, 88747d94), -343, -84},
- {UINT64_2PART_C(0xb9447093, 8fa89bcf), -316, -76},
- {UINT64_2PART_C(0x8a08f0f8, bf0f156b), -289, -68},
- {UINT64_2PART_C(0xcdb02555, 653131b6), -263, -60},
- {UINT64_2PART_C(0x993fe2c6, d07b7fac), -236, -52},
- {UINT64_2PART_C(0xe45c10c4, 2a2b3b06), -210, -44},
- {UINT64_2PART_C(0xaa242499, 697392d3), -183, -36},
- {UINT64_2PART_C(0xfd87b5f2, 8300ca0e), -157, -28},
- {UINT64_2PART_C(0xbce50864, 92111aeb), -130, -20},
- {UINT64_2PART_C(0x8cbccc09, 6f5088cc), -103, -12},
- {UINT64_2PART_C(0xd1b71758, e219652c), -77, -4},
- {UINT64_2PART_C(0x9c400000, 00000000), -50, 4},
- {UINT64_2PART_C(0xe8d4a510, 00000000), -24, 12},
- {UINT64_2PART_C(0xad78ebc5, ac620000), 3, 20},
- {UINT64_2PART_C(0x813f3978, f8940984), 30, 28},
- {UINT64_2PART_C(0xc097ce7b, c90715b3), 56, 36},
- {UINT64_2PART_C(0x8f7e32ce, 7bea5c70), 83, 44},
- {UINT64_2PART_C(0xd5d238a4, abe98068), 109, 52},
- {UINT64_2PART_C(0x9f4f2726, 179a2245), 136, 60},
- {UINT64_2PART_C(0xed63a231, d4c4fb27), 162, 68},
- {UINT64_2PART_C(0xb0de6538, 8cc8ada8), 189, 76},
- {UINT64_2PART_C(0x83c7088e, 1aab65db), 216, 84},
- {UINT64_2PART_C(0xc45d1df9, 42711d9a), 242, 92},
- {UINT64_2PART_C(0x924d692c, a61be758), 269, 100},
- {UINT64_2PART_C(0xda01ee64, 1a708dea), 295, 108},
- {UINT64_2PART_C(0xa26da399, 9aef774a), 322, 116},
- {UINT64_2PART_C(0xf209787b, b47d6b85), 348, 124},
- {UINT64_2PART_C(0xb454e4a1, 79dd1877), 375, 132},
- {UINT64_2PART_C(0x865b8692, 5b9bc5c2), 402, 140},
- {UINT64_2PART_C(0xc83553c5, c8965d3d), 428, 148},
- {UINT64_2PART_C(0x952ab45c, fa97a0b3), 455, 156},
- {UINT64_2PART_C(0xde469fbd, 99a05fe3), 481, 164},
- {UINT64_2PART_C(0xa59bc234, db398c25), 508, 172},
- {UINT64_2PART_C(0xf6c69a72, a3989f5c), 534, 180},
- {UINT64_2PART_C(0xb7dcbf53, 54e9bece), 561, 188},
- {UINT64_2PART_C(0x88fcf317, f22241e2), 588, 196},
- {UINT64_2PART_C(0xcc20ce9b, d35c78a5), 614, 204},
- {UINT64_2PART_C(0x98165af3, 7b2153df), 641, 212},
- {UINT64_2PART_C(0xe2a0b5dc, 971f303a), 667, 220},
- {UINT64_2PART_C(0xa8d9d153, 5ce3b396), 694, 228},
- {UINT64_2PART_C(0xfb9b7cd9, a4a7443c), 720, 236},
- {UINT64_2PART_C(0xbb764c4c, a7a44410), 747, 244},
- {UINT64_2PART_C(0x8bab8eef, b6409c1a), 774, 252},
- {UINT64_2PART_C(0xd01fef10, a657842c), 800, 260},
- {UINT64_2PART_C(0x9b10a4e5, e9913129), 827, 268},
- {UINT64_2PART_C(0xe7109bfb, a19c0c9d), 853, 276},
- {UINT64_2PART_C(0xac2820d9, 623bf429), 880, 284},
- {UINT64_2PART_C(0x80444b5e, 7aa7cf85), 907, 292},
- {UINT64_2PART_C(0xbf21e440, 03acdd2d), 933, 300},
- {UINT64_2PART_C(0x8e679c2f, 5e44ff8f), 960, 308},
- {UINT64_2PART_C(0xd433179d, 9c8cb841), 986, 316},
- {UINT64_2PART_C(0x9e19db92, b4e31ba9), 1013, 324},
- {UINT64_2PART_C(0xeb96bf6e, badf77d9), 1039, 332},
- {UINT64_2PART_C(0xaf87023b, 9bf0ee6b), 1066, 340},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xfa8fd5a0, 081c0288), -1220, -348},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xbaaee17f, a23ebf76), -1193, -340},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x8b16fb20, 3055ac76), -1166, -332},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xcf42894a, 5dce35ea), -1140, -324},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x9a6bb0aa, 55653b2d), -1113, -316},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xe61acf03, 3d1a45df), -1087, -308},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xab70fe17, c79ac6ca), -1060, -300},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xff77b1fc, bebcdc4f), -1034, -292},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xbe5691ef, 416bd60c), -1007, -284},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x8dd01fad, 907ffc3c), -980, -276},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xd3515c28, 31559a83), -954, -268},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x9d71ac8f, ada6c9b5), -927, -260},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xea9c2277, 23ee8bcb), -901, -252},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xaecc4991, 4078536d), -874, -244},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x823c1279, 5db6ce57), -847, -236},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xc2109436, 4dfb5637), -821, -228},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x9096ea6f, 3848984f), -794, -220},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xd77485cb, 25823ac7), -768, -212},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xa086cfcd, 97bf97f4), -741, -204},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xef340a98, 172aace5), -715, -196},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xb23867fb, 2a35b28e), -688, -188},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x84c8d4df, d2c63f3b), -661, -180},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xc5dd4427, 1ad3cdba), -635, -172},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x936b9fce, bb25c996), -608, -164},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xdbac6c24, 7d62a584), -582, -156},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xa3ab6658, 0d5fdaf6), -555, -148},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xf3e2f893, dec3f126), -529, -140},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xb5b5ada8, aaff80b8), -502, -132},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x87625f05, 6c7c4a8b), -475, -124},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xc9bcff60, 34c13053), -449, -116},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x964e858c, 91ba2655), -422, -108},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xdff97724, 70297ebd), -396, -100},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xa6dfbd9f, b8e5b88f), -369, -92},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xf8a95fcf, 88747d94), -343, -84},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xb9447093, 8fa89bcf), -316, -76},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x8a08f0f8, bf0f156b), -289, -68},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xcdb02555, 653131b6), -263, -60},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x993fe2c6, d07b7fac), -236, -52},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xe45c10c4, 2a2b3b06), -210, -44},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xaa242499, 697392d3), -183, -36},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xfd87b5f2, 8300ca0e), -157, -28},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xbce50864, 92111aeb), -130, -20},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x8cbccc09, 6f5088cc), -103, -12},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xd1b71758, e219652c), -77, -4},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x9c400000, 00000000), -50, 4},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xe8d4a510, 00000000), -24, 12},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xad78ebc5, ac620000), 3, 20},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x813f3978, f8940984), 30, 28},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xc097ce7b, c90715b3), 56, 36},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x8f7e32ce, 7bea5c70), 83, 44},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xd5d238a4, abe98068), 109, 52},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x9f4f2726, 179a2245), 136, 60},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xed63a231, d4c4fb27), 162, 68},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xb0de6538, 8cc8ada8), 189, 76},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x83c7088e, 1aab65db), 216, 84},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xc45d1df9, 42711d9a), 242, 92},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x924d692c, a61be758), 269, 100},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xda01ee64, 1a708dea), 295, 108},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xa26da399, 9aef774a), 322, 116},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xf209787b, b47d6b85), 348, 124},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xb454e4a1, 79dd1877), 375, 132},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x865b8692, 5b9bc5c2), 402, 140},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xc83553c5, c8965d3d), 428, 148},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x952ab45c, fa97a0b3), 455, 156},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xde469fbd, 99a05fe3), 481, 164},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xa59bc234, db398c25), 508, 172},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xf6c69a72, a3989f5c), 534, 180},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xb7dcbf53, 54e9bece), 561, 188},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x88fcf317, f22241e2), 588, 196},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xcc20ce9b, d35c78a5), 614, 204},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x98165af3, 7b2153df), 641, 212},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xe2a0b5dc, 971f303a), 667, 220},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xa8d9d153, 5ce3b396), 694, 228},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xfb9b7cd9, a4a7443c), 720, 236},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xbb764c4c, a7a44410), 747, 244},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x8bab8eef, b6409c1a), 774, 252},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xd01fef10, a657842c), 800, 260},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x9b10a4e5, e9913129), 827, 268},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xe7109bfb, a19c0c9d), 853, 276},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xac2820d9, 623bf429), 880, 284},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x80444b5e, 7aa7cf85), 907, 292},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xbf21e440, 03acdd2d), 933, 300},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x8e679c2f, 5e44ff8f), 960, 308},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xd433179d, 9c8cb841), 986, 316},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0x9e19db92, b4e31ba9), 1013, 324},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xeb96bf6e, badf77d9), 1039, 332},
+ {DOUBLE_CONVERSION_UINT64_2PART_C(0xaf87023b, 9bf0ee6b), 1066, 340},
};
static const int kCachedPowersOffset = 348; // -1 * the first decimal_exponent.
static const double kD_1_LOG2_10 = 0.30102999566398114; // 1 / lg(10)
-// Difference between the decimal exponents in the table above.
-const int PowersOfTenCache::kDecimalExponentDistance = 8;
-const int PowersOfTenCache::kMinDecimalExponent = -348;
-const int PowersOfTenCache::kMaxDecimalExponent = 340;
-void PowersOfTenCache::GetCachedPowerForBinaryExponentRange(
+void GetCachedPowerForBinaryExponentRange(
int min_exponent,
int max_exponent,
DiyFp* power,
@@ -162,30 +160,32 @@ void PowersOfTenCache::GetCachedPowerForBinaryExponentRange(
int foo = kCachedPowersOffset;
int index =
(foo + static_cast<int>(k) - 1) / kDecimalExponentDistance + 1;
- ASSERT(0 <= index && index < static_cast<int>(ARRAY_SIZE(kCachedPowers)));
+ DOUBLE_CONVERSION_ASSERT(0 <= index && index < static_cast<int>(DOUBLE_CONVERSION_ARRAY_SIZE(kCachedPowers)));
CachedPower cached_power = kCachedPowers[index];
- ASSERT(min_exponent <= cached_power.binary_exponent);
+ DOUBLE_CONVERSION_ASSERT(min_exponent <= cached_power.binary_exponent);
(void) max_exponent; // Mark variable as used.
- ASSERT(cached_power.binary_exponent <= max_exponent);
+ DOUBLE_CONVERSION_ASSERT(cached_power.binary_exponent <= max_exponent);
*decimal_exponent = cached_power.decimal_exponent;
*power = DiyFp(cached_power.significand, cached_power.binary_exponent);
}
-void PowersOfTenCache::GetCachedPowerForDecimalExponent(int requested_exponent,
- DiyFp* power,
- int* found_exponent) {
- ASSERT(kMinDecimalExponent <= requested_exponent);
- ASSERT(requested_exponent < kMaxDecimalExponent + kDecimalExponentDistance);
+void GetCachedPowerForDecimalExponent(int requested_exponent,
+ DiyFp* power,
+ int* found_exponent) {
+ DOUBLE_CONVERSION_ASSERT(kMinDecimalExponent <= requested_exponent);
+ DOUBLE_CONVERSION_ASSERT(requested_exponent < kMaxDecimalExponent + kDecimalExponentDistance);
int index =
(requested_exponent + kCachedPowersOffset) / kDecimalExponentDistance;
CachedPower cached_power = kCachedPowers[index];
*power = DiyFp(cached_power.significand, cached_power.binary_exponent);
*found_exponent = cached_power.decimal_exponent;
- ASSERT(*found_exponent <= requested_exponent);
- ASSERT(requested_exponent < *found_exponent + kDecimalExponentDistance);
+ DOUBLE_CONVERSION_ASSERT(*found_exponent <= requested_exponent);
+ DOUBLE_CONVERSION_ASSERT(requested_exponent < *found_exponent + kDecimalExponentDistance);
}
+} // namespace PowersOfTenCache
+
} // namespace double_conversion
// ICU PATCH: Close ICU namespace
diff --git a/deps/icu-small/source/i18n/double-conversion-cached-powers.h b/deps/icu-small/source/i18n/double-conversion-cached-powers.h
index 438746b143..ade27baef8 100644
--- a/deps/icu-small/source/i18n/double-conversion-cached-powers.h
+++ b/deps/icu-small/source/i18n/double-conversion-cached-powers.h
@@ -46,32 +46,32 @@ U_NAMESPACE_BEGIN
namespace double_conversion {
-class PowersOfTenCache {
- public:
+namespace PowersOfTenCache {
// Not all powers of ten are cached. The decimal exponent of two neighboring
// cached numbers will differ by kDecimalExponentDistance.
- static const int kDecimalExponentDistance;
+ static const int kDecimalExponentDistance = 8;
- static const int kMinDecimalExponent;
- static const int kMaxDecimalExponent;
+ static const int kMinDecimalExponent = -348;
+ static const int kMaxDecimalExponent = 340;
// Returns a cached power-of-ten with a binary exponent in the range
// [min_exponent; max_exponent] (boundaries included).
- static void GetCachedPowerForBinaryExponentRange(int min_exponent,
- int max_exponent,
- DiyFp* power,
- int* decimal_exponent);
+ void GetCachedPowerForBinaryExponentRange(int min_exponent,
+ int max_exponent,
+ DiyFp* power,
+ int* decimal_exponent);
// Returns a cached power of ten x ~= 10^k such that
// k <= decimal_exponent < k + kCachedPowersDecimalDistance.
// The given decimal_exponent must satisfy
// kMinDecimalExponent <= requested_exponent, and
// requested_exponent < kMaxDecimalExponent + kDecimalExponentDistance.
- static void GetCachedPowerForDecimalExponent(int requested_exponent,
- DiyFp* power,
- int* found_exponent);
-};
+ void GetCachedPowerForDecimalExponent(int requested_exponent,
+ DiyFp* power,
+ int* found_exponent);
+
+} // namespace PowersOfTenCache
} // namespace double_conversion
diff --git a/deps/icu-small/source/i18n/double-conversion-diy-fp.cpp b/deps/icu-small/source/i18n/double-conversion-diy-fp.cpp
deleted file mode 100644
index f38430c6c3..0000000000
--- a/deps/icu-small/source/i18n/double-conversion-diy-fp.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-// © 2018 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-//
-// From the double-conversion library. Original license:
-//
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ICU PATCH: ifdef around UCONFIG_NO_FORMATTING
-#include "unicode/utypes.h"
-#if !UCONFIG_NO_FORMATTING
-
-// ICU PATCH: Customize header file paths for ICU.
-
-#include "double-conversion-diy-fp.h"
-#include "double-conversion-utils.h"
-
-// ICU PATCH: Wrap in ICU namespace
-U_NAMESPACE_BEGIN
-
-namespace double_conversion {
-
-void DiyFp::Multiply(const DiyFp& other) {
- // Simply "emulates" a 128 bit multiplication.
- // However: the resulting number only contains 64 bits. The least
- // significant 64 bits are only used for rounding the most significant 64
- // bits.
- const uint64_t kM32 = 0xFFFFFFFFU;
- uint64_t a = f_ >> 32;
- uint64_t b = f_ & kM32;
- uint64_t c = other.f_ >> 32;
- uint64_t d = other.f_ & kM32;
- uint64_t ac = a * c;
- uint64_t bc = b * c;
- uint64_t ad = a * d;
- uint64_t bd = b * d;
- uint64_t tmp = (bd >> 32) + (ad & kM32) + (bc & kM32);
- // By adding 1U << 31 to tmp we round the final result.
- // Halfway cases will be round up.
- tmp += 1U << 31;
- uint64_t result_f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32);
- e_ += other.e_ + 64;
- f_ = result_f;
-}
-
-} // namespace double_conversion
-
-// ICU PATCH: Close ICU namespace
-U_NAMESPACE_END
-#endif // ICU PATCH: close #if !UCONFIG_NO_FORMATTING
diff --git a/deps/icu-small/source/i18n/double-conversion-diy-fp.h b/deps/icu-small/source/i18n/double-conversion-diy-fp.h
index 21896851d2..5820abedf3 100644
--- a/deps/icu-small/source/i18n/double-conversion-diy-fp.h
+++ b/deps/icu-small/source/i18n/double-conversion-diy-fp.h
@@ -50,36 +50,55 @@ namespace double_conversion {
// with a uint64 significand and an int exponent. Normalized DiyFp numbers will
// have the most significant bit of the significand set.
// Multiplication and Subtraction do not normalize their results.
-// DiyFp are not designed to contain special doubles (NaN and Infinity).
+// DiyFp store only non-negative numbers and are not designed to contain special
+// doubles (NaN and Infinity).
class DiyFp {
public:
static const int kSignificandSize = 64;
DiyFp() : f_(0), e_(0) {}
- DiyFp(uint64_t significand, int exponent) : f_(significand), e_(exponent) {}
+ DiyFp(const uint64_t significand, const int32_t exponent) : f_(significand), e_(exponent) {}
- // this = this - other.
+ // this -= other.
// The exponents of both numbers must be the same and the significand of this
- // must be bigger than the significand of other.
+ // must be greater or equal than the significand of other.
// The result will not be normalized.
void Subtract(const DiyFp& other) {
- ASSERT(e_ == other.e_);
- ASSERT(f_ >= other.f_);
+ DOUBLE_CONVERSION_ASSERT(e_ == other.e_);
+ DOUBLE_CONVERSION_ASSERT(f_ >= other.f_);
f_ -= other.f_;
}
// Returns a - b.
- // The exponents of both numbers must be the same and this must be bigger
- // than other. The result will not be normalized.
+ // The exponents of both numbers must be the same and a must be greater
+ // or equal than b. The result will not be normalized.
static DiyFp Minus(const DiyFp& a, const DiyFp& b) {
DiyFp result = a;
result.Subtract(b);
return result;
}
-
- // this = this * other.
- void Multiply(const DiyFp& other);
+ // this *= other.
+ void Multiply(const DiyFp& other) {
+ // Simply "emulates" a 128 bit multiplication.
+ // However: the resulting number only contains 64 bits. The least
+ // significant 64 bits are only used for rounding the most significant 64
+ // bits.
+ const uint64_t kM32 = 0xFFFFFFFFU;
+ const uint64_t a = f_ >> 32;
+ const uint64_t b = f_ & kM32;
+ const uint64_t c = other.f_ >> 32;
+ const uint64_t d = other.f_ & kM32;
+ const uint64_t ac = a * c;
+ const uint64_t bc = b * c;
+ const uint64_t ad = a * d;
+ const uint64_t bd = b * d;
+ // By adding 1U << 31 to tmp we round the final result.
+ // Halfway cases will be rounded up.
+ const uint64_t tmp = (bd >> 32) + (ad & kM32) + (bc & kM32) + (1U << 31);
+ e_ += other.e_ + 64;
+ f_ = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32);
+ }
// returns a * b;
static DiyFp Times(const DiyFp& a, const DiyFp& b) {
@@ -89,13 +108,13 @@ class DiyFp {
}
void Normalize() {
- ASSERT(f_ != 0);
+ DOUBLE_CONVERSION_ASSERT(f_ != 0);
uint64_t significand = f_;
- int exponent = e_;
+ int32_t exponent = e_;
- // This method is mainly called for normalizing boundaries. In general
- // boundaries need to be shifted by 10 bits. We thus optimize for this case.
- const uint64_t k10MSBits = UINT64_2PART_C(0xFFC00000, 00000000);
+ // This method is mainly called for normalizing boundaries. In general,
+ // boundaries need to be shifted by 10 bits, and we optimize for this case.
+ const uint64_t k10MSBits = DOUBLE_CONVERSION_UINT64_2PART_C(0xFFC00000, 00000000);
while ((significand & k10MSBits) == 0) {
significand <<= 10;
exponent -= 10;
@@ -115,16 +134,16 @@ class DiyFp {
}
uint64_t f() const { return f_; }
- int e() const { return e_; }
+ int32_t e() const { return e_; }
void set_f(uint64_t new_value) { f_ = new_value; }
- void set_e(int new_value) { e_ = new_value; }
+ void set_e(int32_t new_value) { e_ = new_value; }
private:
- static const uint64_t kUint64MSB = UINT64_2PART_C(0x80000000, 00000000);
+ static const uint64_t kUint64MSB = DOUBLE_CONVERSION_UINT64_2PART_C(0x80000000, 00000000);
uint64_t f_;
- int e_;
+ int32_t e_;
};
} // namespace double_conversion
diff --git a/deps/icu-small/source/i18n/double-conversion-double-to-string.cpp b/deps/icu-small/source/i18n/double-conversion-double-to-string.cpp
new file mode 100644
index 0000000000..44c176f4f9
--- /dev/null
+++ b/deps/icu-small/source/i18n/double-conversion-double-to-string.cpp
@@ -0,0 +1,450 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+//
+// From the double-conversion library. Original license:
+//
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ICU PATCH: ifdef around UCONFIG_NO_FORMATTING
+#include "unicode/utypes.h"
+#if !UCONFIG_NO_FORMATTING
+
+#include <algorithm>
+#include <climits>
+#include <cmath>
+
+// ICU PATCH: Customize header file paths for ICU.
+// The file fixed-dtoa.h is not needed.
+
+#include "double-conversion-double-to-string.h"
+
+#include "double-conversion-bignum-dtoa.h"
+#include "double-conversion-fast-dtoa.h"
+#include "double-conversion-ieee.h"
+#include "double-conversion-utils.h"
+
+// ICU PATCH: Wrap in ICU namespace
+U_NAMESPACE_BEGIN
+
+namespace double_conversion {
+
+#if 0 // not needed for ICU
+const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() {
+ int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN;
+ static DoubleToStringConverter converter(flags,
+ "Infinity",
+ "NaN",
+ 'e',
+ -6, 21,
+ 6, 0);
+ return converter;
+}
+
+
+bool DoubleToStringConverter::HandleSpecialValues(
+ double value,
+ StringBuilder* result_builder) const {
+ Double double_inspect(value);
+ if (double_inspect.IsInfinite()) {
+ if (infinity_symbol_ == NULL) return false;
+ if (value < 0) {
+ result_builder->AddCharacter('-');
+ }
+ result_builder->AddString(infinity_symbol_);
+ return true;
+ }
+ if (double_inspect.IsNan()) {
+ if (nan_symbol_ == NULL) return false;
+ result_builder->AddString(nan_symbol_);
+ return true;
+ }
+ return false;
+}
+
+
+void DoubleToStringConverter::CreateExponentialRepresentation(
+ const char* decimal_digits,
+ int length,
+ int exponent,
+ StringBuilder* result_builder) const {
+ DOUBLE_CONVERSION_ASSERT(length != 0);
+ result_builder->AddCharacter(decimal_digits[0]);
+ if (length != 1) {
+ result_builder->AddCharacter('.');
+ result_builder->AddSubstring(&decimal_digits[1], length-1);
+ }
+ result_builder->AddCharacter(exponent_character_);
+ if (exponent < 0) {
+ result_builder->AddCharacter('-');
+ exponent = -exponent;
+ } else {
+ if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) {
+ result_builder->AddCharacter('+');
+ }
+ }
+ if (exponent == 0) {
+ result_builder->AddCharacter('0');
+ return;
+ }
+ DOUBLE_CONVERSION_ASSERT(exponent < 1e4);
+ // Changing this constant requires updating the comment of DoubleToStringConverter constructor
+ const int kMaxExponentLength = 5;
+ char buffer[kMaxExponentLength + 1];
+ buffer[kMaxExponentLength] = '\0';
+ int first_char_pos = kMaxExponentLength;
+ while (exponent > 0) {
+ buffer[--first_char_pos] = '0' + (exponent % 10);
+ exponent /= 10;
+ }
+ // Add prefix '0' to make exponent width >= min(min_exponent_with_, kMaxExponentLength)
+ // For example: convert 1e+9 -> 1e+09, if min_exponent_with_ is set to 2
+ while(kMaxExponentLength - first_char_pos < std::min(min_exponent_width_, kMaxExponentLength)) {
+ buffer[--first_char_pos] = '0';
+ }
+ result_builder->AddSubstring(&buffer[first_char_pos],
+ kMaxExponentLength - first_char_pos);
+}
+
+
+void DoubleToStringConverter::CreateDecimalRepresentation(
+ const char* decimal_digits,
+ int length,
+ int decimal_point,
+ int digits_after_point,
+ StringBuilder* result_builder) const {
+ // Create a representation that is padded with zeros if needed.
+ if (decimal_point <= 0) {
+ // "0.00000decimal_rep" or "0.000decimal_rep00".
+ result_builder->AddCharacter('0');
+ if (digits_after_point > 0) {
+ result_builder->AddCharacter('.');
+ result_builder->AddPadding('0', -decimal_point);
+ DOUBLE_CONVERSION_ASSERT(length <= digits_after_point - (-decimal_point));
+ result_builder->AddSubstring(decimal_digits, length);
+ int remaining_digits = digits_after_point - (-decimal_point) - length;
+ result_builder->AddPadding('0', remaining_digits);
+ }
+ } else if (decimal_point >= length) {
+ // "decimal_rep0000.00000" or "decimal_rep.0000".
+ result_builder->AddSubstring(decimal_digits, length);
+ result_builder->AddPadding('0', decimal_point - length);
+ if (digits_after_point > 0) {
+ result_builder->AddCharacter('.');
+ result_builder->AddPadding('0', digits_after_point);
+ }
+ } else {
+ // "decima.l_rep000".
+ DOUBLE_CONVERSION_ASSERT(digits_after_point > 0);
+ result_builder->AddSubstring(decimal_digits, decimal_point);
+ result_builder->AddCharacter('.');
+ DOUBLE_CONVERSION_ASSERT(length - decimal_point <= digits_after_point);
+ result_builder->AddSubstring(&decimal_digits[decimal_point],
+ length - decimal_point);
+ int remaining_digits = digits_after_point - (length - decimal_point);
+ result_builder->AddPadding('0', remaining_digits);
+ }
+ if (digits_after_point == 0) {
+ if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) {
+ result_builder->AddCharacter('.');
+ }
+ if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) {
+ result_builder->AddCharacter('0');
+ }
+ }
+}
+
+
+bool DoubleToStringConverter::ToShortestIeeeNumber(
+ double value,
+ StringBuilder* result_builder,
+ DoubleToStringConverter::DtoaMode mode) const {
+ DOUBLE_CONVERSION_ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE);
+ if (Double(value).IsSpecial()) {
+ return HandleSpecialValues(value, result_builder);
+ }
+
+ int decimal_point;
+ bool sign;
+ const int kDecimalRepCapacity = kBase10MaximalLength + 1;
+ char decimal_rep[kDecimalRepCapacity];
+ int decimal_rep_length;
+
+ DoubleToAscii(value, mode, 0, decimal_rep, kDecimalRepCapacity,
+ &sign, &decimal_rep_length, &decimal_point);
+
+ bool unique_zero = (flags_ & UNIQUE_ZERO) != 0;
+ if (sign && (value != 0.0 || !unique_zero)) {
+ result_builder->AddCharacter('-');
+ }
+
+ int exponent = decimal_point - 1;
+ if ((decimal_in_shortest_low_ <= exponent) &&
+ (exponent < decimal_in_shortest_high_)) {
+ CreateDecimalRepresentation(decimal_rep, decimal_rep_length,
+ decimal_point,
+ (std::max)(0, decimal_rep_length - decimal_point),
+ result_builder);
+ } else {
+ CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent,
+ result_builder);
+ }
+ return true;
+}
+
+
+bool DoubleToStringConverter::ToFixed(double value,
+ int requested_digits,
+ StringBuilder* result_builder) const {
+ DOUBLE_CONVERSION_ASSERT(kMaxFixedDigitsBeforePoint == 60);
+ const double kFirstNonFixed = 1e60;
+
+ if (Double(value).IsSpecial()) {
+ return HandleSpecialValues(value, result_builder);
+ }
+
+ if (requested_digits > kMaxFixedDigitsAfterPoint) return false;
+ if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false;
+
+ // Find a sufficiently precise decimal representation of n.
+ int decimal_point;
+ bool sign;
+ // Add space for the '\0' byte.
+ const int kDecimalRepCapacity =
+ kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1;
+ char decimal_rep[kDecimalRepCapacity];
+ int decimal_rep_length;
+ DoubleToAscii(value, FIXED, requested_digits,
+ decimal_rep, kDecimalRepCapacity,
+ &sign, &decimal_rep_length, &decimal_point);
+
+ bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
+ if (sign && (value != 0.0 || !unique_zero)) {
+ result_builder->AddCharacter('-');
+ }
+
+ CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
+ requested_digits, result_builder);
+ return true;
+}
+
+
+bool DoubleToStringConverter::ToExponential(
+ double value,
+ int requested_digits,
+ StringBuilder* result_builder) const {
+ if (Double(value).IsSpecial()) {
+ return HandleSpecialValues(value, result_builder);
+ }
+
+ if (requested_digits < -1) return false;
+ if (requested_digits > kMaxExponentialDigits) return false;
+
+ int decimal_point;
+ bool sign;
+ // Add space for digit before the decimal point and the '\0' character.
+ const int kDecimalRepCapacity = kMaxExponentialDigits + 2;
+ DOUBLE_CONVERSION_ASSERT(kDecimalRepCapacity > kBase10MaximalLength);
+ char decimal_rep[kDecimalRepCapacity];
+#ifndef NDEBUG
+ // Problem: there is an assert in StringBuilder::AddSubstring() that
+ // will pass this buffer to strlen(), and this buffer is not generally
+ // null-terminated.
+ memset(decimal_rep, 0, sizeof(decimal_rep));
+#endif
+ int decimal_rep_length;
+
+ if (requested_digits == -1) {
+ DoubleToAscii(value, SHORTEST, 0,
+ decimal_rep, kDecimalRepCapacity,
+ &sign, &decimal_rep_length, &decimal_point);
+ } else {
+ DoubleToAscii(value, PRECISION, requested_digits + 1,
+ decimal_rep, kDecimalRepCapacity,
+ &sign, &decimal_rep_length, &decimal_point);
+ DOUBLE_CONVERSION_ASSERT(decimal_rep_length <= requested_digits + 1);
+
+ for (int i = decimal_rep_length; i < requested_digits + 1; ++i) {
+ decimal_rep[i] = '0';
+ }
+ decimal_rep_length = requested_digits + 1;
+ }
+
+ bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
+ if (sign && (value != 0.0 || !unique_zero)) {
+ result_builder->AddCharacter('-');
+ }
+
+ int exponent = decimal_point - 1;
+ CreateExponentialRepresentation(decimal_rep,
+ decimal_rep_length,
+ exponent,
+ result_builder);
+ return true;
+}
+
+
+bool DoubleToStringConverter::ToPrecision(double value,
+ int precision,
+ StringBuilder* result_builder) const {
+ if (Double(value).IsSpecial()) {
+ return HandleSpecialValues(value, result_builder);
+ }
+
+ if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) {
+ return false;
+ }
+
+ // Find a sufficiently precise decimal representation of n.
+ int decimal_point;
+ bool sign;
+ // Add one for the terminating null character.
+ const int kDecimalRepCapacity = kMaxPrecisionDigits + 1;
+ char decimal_rep[kDecimalRepCapacity];
+ int decimal_rep_length;
+
+ DoubleToAscii(value, PRECISION, precision,
+ decimal_rep, kDecimalRepCapacity,
+ &sign, &decimal_rep_length, &decimal_point);
+ DOUBLE_CONVERSION_ASSERT(decimal_rep_length <= precision);
+
+ bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
+ if (sign && (value != 0.0 || !unique_zero)) {
+ result_builder->AddCharacter('-');
+ }
+
+ // The exponent if we print the number as x.xxeyyy. That is with the
+ // decimal point after the first digit.
+ int exponent = decimal_point - 1;
+
+ int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0;
+ if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) ||
+ (decimal_point - precision + extra_zero >
+ max_trailing_padding_zeroes_in_precision_mode_)) {
+ // Fill buffer to contain 'precision' digits.
+ // Usually the buffer is already at the correct length, but 'DoubleToAscii'
+ // is allowed to return less characters.
+ for (int i = decimal_rep_length; i < precision; ++i) {
+ decimal_rep[i] = '0';
+ }
+
+ CreateExponentialRepresentation(decimal_rep,
+ precision,
+ exponent,
+ result_builder);
+ } else {
+ CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
+ (std::max)(0, precision - decimal_point),
+ result_builder);
+ }
+ return true;
+}
+#endif // not needed for ICU
+
+
+static BignumDtoaMode DtoaToBignumDtoaMode(
+ DoubleToStringConverter::DtoaMode dtoa_mode) {
+ switch (dtoa_mode) {
+ case DoubleToStringConverter::SHORTEST: return BIGNUM_DTOA_SHORTEST;
+ case DoubleToStringConverter::SHORTEST_SINGLE:
+ return BIGNUM_DTOA_SHORTEST_SINGLE;
+ case DoubleToStringConverter::FIXED: return BIGNUM_DTOA_FIXED;
+ case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
+ default:
+ DOUBLE_CONVERSION_UNREACHABLE();
+ }
+}
+
+
+void DoubleToStringConverter::DoubleToAscii(double v,
+ DtoaMode mode,
+ int requested_digits,
+ char* buffer,
+ int buffer_length,
+ bool* sign,
+ int* length,
+ int* point) {
+ Vector<char> vector(buffer, buffer_length);
+ DOUBLE_CONVERSION_ASSERT(!Double(v).IsSpecial());
+ DOUBLE_CONVERSION_ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE || requested_digits >= 0);
+
+ if (Double(v).Sign() < 0) {
+ *sign = true;
+ v = -v;
+ } else {
+ *sign = false;
+ }
+
+ if (mode == PRECISION && requested_digits == 0) {
+ vector[0] = '\0';
+ *length = 0;
+ return;
+ }
+
+ if (v == 0) {
+ vector[0] = '0';
+ vector[1] = '\0';
+ *length = 1;
+ *point = 1;
+ return;
+ }
+
+ bool fast_worked;
+ switch (mode) {
+ case SHORTEST:
+ fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point);
+ break;
+#if 0 // not needed for ICU
+ case SHORTEST_SINGLE:
+ fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0,
+ vector, length, point);
+ break;
+ case FIXED:
+ fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point);
+ break;
+ case PRECISION:
+ fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits,
+ vector, length, point);
+ break;
+#endif // not needed for ICU
+ default:
+ fast_worked = false;
+ DOUBLE_CONVERSION_UNREACHABLE();
+ }
+ if (fast_worked) return;
+
+ // If the fast dtoa didn't succeed use the slower bignum version.
+ BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode);
+ BignumDtoa(v, bignum_mode, requested_digits, vector, length, point);
+ vector[*length] = '\0';
+}
+
+} // namespace double_conversion
+
+// ICU PATCH: Close ICU namespace
+U_NAMESPACE_END
+#endif // ICU PATCH: close #if !UCONFIG_NO_FORMATTING
diff --git a/deps/icu-small/source/i18n/double-conversion-double-to-string.h b/deps/icu-small/source/i18n/double-conversion-double-to-string.h
new file mode 100644
index 0000000000..27bd867848
--- /dev/null
+++ b/deps/icu-small/source/i18n/double-conversion-double-to-string.h
@@ -0,0 +1,419 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+//
+// From the double-conversion library. Original license:
+//
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ICU PATCH: ifdef around UCONFIG_NO_FORMATTING
+#include "unicode/utypes.h"
+#if !UCONFIG_NO_FORMATTING
+
+#ifndef DOUBLE_CONVERSION_DOUBLE_TO_STRING_H_
+#define DOUBLE_CONVERSION_DOUBLE_TO_STRING_H_
+
+// ICU PATCH: Customize header file paths for ICU.
+
+#include "double-conversion-utils.h"
+
+// ICU PATCH: Wrap in ICU namespace
+U_NAMESPACE_BEGIN
+
+namespace double_conversion {
+
+class DoubleToStringConverter {
+ public:
+#if 0 // not needed for ICU
+ // When calling ToFixed with a double > 10^kMaxFixedDigitsBeforePoint
+ // or a requested_digits parameter > kMaxFixedDigitsAfterPoint then the
+ // function returns false.
+ static const int kMaxFixedDigitsBeforePoint = 60;
+ static const int kMaxFixedDigitsAfterPoint = 60;
+
+ // When calling ToExponential with a requested_digits
+ // parameter > kMaxExponentialDigits then the function returns false.
+ static const int kMaxExponentialDigits = 120;
+
+ // When calling ToPrecision with a requested_digits
+ // parameter < kMinPrecisionDigits or requested_digits > kMaxPrecisionDigits
+ // then the function returns false.
+ static const int kMinPrecisionDigits = 1;
+ static const int kMaxPrecisionDigits = 120;
+
+ enum Flags {
+ NO_FLAGS = 0,
+ EMIT_POSITIVE_EXPONENT_SIGN = 1,
+ EMIT_TRAILING_DECIMAL_POINT = 2,
+ EMIT_TRAILING_ZERO_AFTER_POINT = 4,
+ UNIQUE_ZERO = 8
+ };
+
+ // Flags should be a bit-or combination of the possible Flags-enum.
+ // - NO_FLAGS: no special flags.
+ // - EMIT_POSITIVE_EXPONENT_SIGN: when the number is converted into exponent
+ // form, emits a '+' for positive exponents. Example: 1.2e+2.
+ // - EMIT_TRAILING_DECIMAL_POINT: when the input number is an integer and is
+ // converted into decimal format then a trailing decimal point is appended.
+ // Example: 2345.0 is converted to "2345.".
+ // - EMIT_TRAILING_ZERO_AFTER_POINT: in addition to a trailing decimal point
+ // emits a trailing '0'-character. This flag requires the
+ // EXMIT_TRAILING_DECIMAL_POINT flag.
+ // Example: 2345.0 is converted to "2345.0".
+ // - UNIQUE_ZERO: "-0.0" is converted to "0.0".
+ //
+ // Infinity symbol and nan_symbol provide the string representation for these
+ // special values. If the string is NULL and the special value is encountered
+ // then the conversion functions return false.
+ //
+ // The exponent_character is used in exponential representations. It is
+ // usually 'e' or 'E'.
+ //
+ // When converting to the shortest representation the converter will
+ // represent input numbers in decimal format if they are in the interval
+ // [10^decimal_in_shortest_low; 10^decimal_in_shortest_high[
+ // (lower boundary included, greater boundary excluded).
+ // Example: with decimal_in_shortest_low = -6 and
+ // decimal_in_shortest_high = 21:
+ // ToShortest(0.000001) -> "0.000001"
+ // ToShortest(0.0000001) -> "1e-7"
+ // ToShortest(111111111111111111111.0) -> "111111111111111110000"
+ // ToShortest(100000000000000000000.0) -> "100000000000000000000"
+ // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21"
+ //
+ // When converting to precision mode the converter may add
+ // max_leading_padding_zeroes before returning the number in exponential
+ // format.
+ // Example with max_leading_padding_zeroes_in_precision_mode = 6.
+ // ToPrecision(0.0000012345, 2) -> "0.0000012"
+ // ToPrecision(0.00000012345, 2) -> "1.2e-7"
+ // Similarily the converter may add up to
+ // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid
+ // returning an exponential representation. A zero added by the
+ // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit.
+ // Examples for max_trailing_padding_zeroes_in_precision_mode = 1:
+ // ToPrecision(230.0, 2) -> "230"
+ // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT.
+ // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT.
+ //
+ // The min_exponent_width is used for exponential representations.
+ // The converter adds leading '0's to the exponent until the exponent
+ // is at least min_exponent_width digits long.
+ // The min_exponent_width is clamped to 5.
+ // As such, the exponent may never have more than 5 digits in total.
+ DoubleToStringConverter(int flags,
+ const char* infinity_symbol,
+ const char* nan_symbol,
+ char exponent_character,
+ int decimal_in_shortest_low,
+ int decimal_in_shortest_high,
+ int max_leading_padding_zeroes_in_precision_mode,
+ int max_trailing_padding_zeroes_in_precision_mode,
+ int min_exponent_width = 0)
+ : flags_(flags),
+ infinity_symbol_(infinity_symbol),
+ nan_symbol_(nan_symbol),
+ exponent_character_(exponent_character),
+ decimal_in_shortest_low_(decimal_in_shortest_low),
+ decimal_in_shortest_high_(decimal_in_shortest_high),
+ max_leading_padding_zeroes_in_precision_mode_(
+ max_leading_padding_zeroes_in_precision_mode),
+ max_trailing_padding_zeroes_in_precision_mode_(
+ max_trailing_padding_zeroes_in_precision_mode),
+ min_exponent_width_(min_exponent_width) {
+ // When 'trailing zero after the point' is set, then 'trailing point'
+ // must be set too.
+ DOUBLE_CONVERSION_ASSERT(((flags & EMIT_TRAILING_DECIMAL_POINT) != 0) ||
+ !((flags & EMIT_TRAILING_ZERO_AFTER_POINT) != 0));
+ }
+
+ // Returns a converter following the EcmaScript specification.
+ static const DoubleToStringConverter& EcmaScriptConverter();
+
+ // Computes the shortest string of digits that correctly represent the input
+ // number. Depending on decimal_in_shortest_low and decimal_in_shortest_high
+ // (see constructor) it then either returns a decimal representation, or an
+ // exponential representation.
+ // Example with decimal_in_shortest_low = -6,
+ // decimal_in_shortest_high = 21,
+ // EMIT_POSITIVE_EXPONENT_SIGN activated, and
+ // EMIT_TRAILING_DECIMAL_POINT deactived:
+ // ToShortest(0.000001) -> "0.000001"
+ // ToShortest(0.0000001) -> "1e-7"
+ // ToShortest(111111111111111111111.0) -> "111111111111111110000"
+ // ToShortest(100000000000000000000.0) -> "100000000000000000000"
+ // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21"
+ //
+ // Note: the conversion may round the output if the returned string
+ // is accurate enough to uniquely identify the input-number.
+ // For example the most precise representation of the double 9e59 equals
+ // "899999999999999918767229449717619953810131273674690656206848", but
+ // the converter will return the shorter (but still correct) "9e59".
+ //
+ // Returns true if the conversion succeeds. The conversion always succeeds
+ // except when the input value is special and no infinity_symbol or
+ // nan_symbol has been given to the constructor.
+ bool ToShortest(double value, StringBuilder* result_builder) const {
+ return ToShortestIeeeNumber(value, result_builder, SHORTEST);
+ }
+
+ // Same as ToShortest, but for single-precision floats.
+ bool ToShortestSingle(float value, StringBuilder* result_builder) const {
+ return ToShortestIeeeNumber(value, result_builder, SHORTEST_SINGLE);
+ }
+
+
+ // Computes a decimal representation with a fixed number of digits after the
+ // decimal point. The last emitted digit is rounded.
+ //
+ // Examples:
+ // ToFixed(3.12, 1) -> "3.1"
+ // ToFixed(3.1415, 3) -> "3.142"
+ // ToFixed(1234.56789, 4) -> "1234.5679"
+ // ToFixed(1.23, 5) -> "1.23000"
+ // ToFixed(0.1, 4) -> "0.1000"
+ // ToFixed(1e30, 2) -> "1000000000000000019884624838656.00"
+ // ToFixed(0.1, 30) -> "0.100000000000000005551115123126"
+ // ToFixed(0.1, 17) -> "0.10000000000000001"
+ //
+ // If requested_digits equals 0, then the tail of the result depends on
+ // the EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT.
+ // Examples, for requested_digits == 0,
+ // let EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT be
+ // - false and false: then 123.45 -> 123
+ // 0.678 -> 1
+ // - true and false: then 123.45 -> 123.
+ // 0.678 -> 1.
+ // - true and true: then 123.45 -> 123.0
+ // 0.678 -> 1.0
+ //
+ // Returns true if the conversion succeeds. The conversion always succeeds
+ // except for the following cases:
+ // - the input value is special and no infinity_symbol or nan_symbol has
+ // been provided to the constructor,
+ // - 'value' > 10^kMaxFixedDigitsBeforePoint, or
+ // - 'requested_digits' > kMaxFixedDigitsAfterPoint.
+ // The last two conditions imply that the result will never contain more than
+ // 1 + kMaxFixedDigitsBeforePoint + 1 + kMaxFixedDigitsAfterPoint characters
+ // (one additional character for the sign, and one for the decimal point).
+ bool ToFixed(double value,
+ int requested_digits,
+ StringBuilder* result_builder) const;
+
+ // Computes a representation in exponential format with requested_digits
+ // after the decimal point. The last emitted digit is rounded.
+ // If requested_digits equals -1, then the shortest exponential representation
+ // is computed.
+ //
+ // Examples with EMIT_POSITIVE_EXPONENT_SIGN deactivated, and
+ // exponent_character set to 'e'.
+ // ToExponential(3.12, 1) -> "3.1e0"
+ // ToExponential(5.0, 3) -> "5.000e0"
+ // ToExponential(0.001, 2) -> "1.00e-3"
+ // ToExponential(3.1415, -1) -> "3.1415e0"
+ // ToExponential(3.1415, 4) -> "3.1415e0"
+ // ToExponential(3.1415, 3) -> "3.142e0"
+ // ToExponential(123456789000000, 3) -> "1.235e14"
+ // ToExponential(1000000000000000019884624838656.0, -1) -> "1e30"
+ // ToExponential(1000000000000000019884624838656.0, 32) ->
+ // "1.00000000000000001988462483865600e30"
+ // ToExponential(1234, 0) -> "1e3"
+ //
+ // Returns true if the conversion succeeds. The conversion always succeeds
+ // except for the following cases:
+ // - the input value is special and no infinity_symbol or nan_symbol has
+ // been provided to the constructor,
+ // - 'requested_digits' > kMaxExponentialDigits.
+ // The last condition implies that the result will never contain more than
+ // kMaxExponentialDigits + 8 characters (the sign, the digit before the
+ // decimal point, the decimal point, the exponent character, the
+ // exponent's sign, and at most 3 exponent digits).
+ bool ToExponential(double value,
+ int requested_digits,
+ StringBuilder* result_builder) const;
+
+ // Computes 'precision' leading digits of the given 'value' and returns them
+ // either in exponential or decimal format, depending on
+ // max_{leading|trailing}_padding_zeroes_in_precision_mode (given to the
+ // constructor).
+ // The last computed digit is rounded.
+ //
+ // Example with max_leading_padding_zeroes_in_precision_mode = 6.
+ // ToPrecision(0.0000012345, 2) -> "0.0000012"
+ // ToPrecision(0.00000012345, 2) -> "1.2e-7"
+ // Similarily the converter may add up to
+ // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid
+ // returning an exponential representation. A zero added by the
+ // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit.
+ // Examples for max_trailing_padding_zeroes_in_precision_mode = 1:
+ // ToPrecision(230.0, 2) -> "230"
+ // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT.
+ // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT.
+ // Examples for max_trailing_padding_zeroes_in_precision_mode = 3, and no
+ // EMIT_TRAILING_ZERO_AFTER_POINT:
+ // ToPrecision(123450.0, 6) -> "123450"
+ // ToPrecision(123450.0, 5) -> "123450"
+ // ToPrecision(123450.0, 4) -> "123500"
+ // ToPrecision(123450.0, 3) -> "123000"
+ // ToPrecision(123450.0, 2) -> "1.2e5"
+ //
+ // Returns true if the conversion succeeds. The conversion always succeeds
+ // except for the following cases:
+ // - the input value is special and no infinity_symbol or nan_symbol has
+ // been provided to the constructor,
+ // - precision < kMinPericisionDigits
+ // - precision > kMaxPrecisionDigits
+ // The last condition implies that the result will never contain more than
+ // kMaxPrecisionDigits + 7 characters (the sign, the decimal point, the
+ // exponent character, the exponent's sign, and at most 3 exponent digits).
+ bool ToPrecision(double value,
+ int precision,
+ StringBuilder* result_builder) const;
+#endif // not needed for ICU
+
+ enum DtoaMode {
+ // Produce the shortest correct representation.
+ // For example the output of 0.299999999999999988897 is (the less accurate
+ // but correct) 0.3.
+ SHORTEST,
+ // Same as SHORTEST, but for single-precision floats.
+ SHORTEST_SINGLE,
+ // Produce a fixed number of digits after the decimal point.
+ // For instance fixed(0.1, 4) becomes 0.1000
+ // If the input number is big, the output will be big.
+ FIXED,
+ // Fixed number of digits (independent of the decimal point).
+ PRECISION
+ };
+
+ // The maximal number of digits that are needed to emit a double in base 10.
+ // A higher precision can be achieved by using more digits, but the shortest
+ // accurate representation of any double will never use more digits than
+ // kBase10MaximalLength.
+ // Note that DoubleToAscii null-terminates its input. So the given buffer
+ // should be at least kBase10MaximalLength + 1 characters long.
+ static const int kBase10MaximalLength = 17;
+
+ // Converts the given double 'v' to digit characters. 'v' must not be NaN,
+ // +Infinity, or -Infinity. In SHORTEST_SINGLE-mode this restriction also
+ // applies to 'v' after it has been casted to a single-precision float. That
+ // is, in this mode static_cast<float>(v) must not be NaN, +Infinity or
+ // -Infinity.
+ //
+ // The result should be interpreted as buffer * 10^(point-length).
+ //
+ // The digits are written to the buffer in the platform's charset, which is
+ // often UTF-8 (with ASCII-range digits) but may be another charset, such
+ // as EBCDIC.
+ //
+ // The output depends on the given mode:
+ // - SHORTEST: produce the least amount of digits for which the internal
+ // identity requirement is still satisfied. If the digits are printed
+ // (together with the correct exponent) then reading this number will give
+ // 'v' again. The buffer will choose the representation that is closest to
+ // 'v'. If there are two at the same distance, than the one farther away
+ // from 0 is chosen (halfway cases - ending with 5 - are rounded up).
+ // In this mode the 'requested_digits' parameter is ignored.
+ // - SHORTEST_SINGLE: same as SHORTEST but with single-precision.
+ // - FIXED: produces digits necessary to print a given number with
+ // 'requested_digits' digits after the decimal point. The produced digits
+ // might be too short in which case the caller has to fill the remainder
+ // with '0's.
+ // Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2.
+ // Halfway cases are rounded towards +/-Infinity (away from 0). The call
+ // toFixed(0.15, 2) thus returns buffer="2", point=0.
+ // The returned buffer may contain digits that would be truncated from the
+ // shortest representation of the input.
+ // - PRECISION: produces 'requested_digits' where the first digit is not '0'.
+ // Even though the length of produced digits usually equals
+ // 'requested_digits', the function is allowed to return fewer digits, in
+ // which case the caller has to fill the missing digits with '0's.
+ // Halfway cases are again rounded away from 0.
+ // DoubleToAscii expects the given buffer to be big enough to hold all
+ // digits and a terminating null-character. In SHORTEST-mode it expects a
+ // buffer of at least kBase10MaximalLength + 1. In all other modes the
+ // requested_digits parameter and the padding-zeroes limit the size of the
+ // output. Don't forget the decimal point, the exponent character and the
+ // terminating null-character when computing the maximal output size.
+ // The given length is only used in debug mode to ensure the buffer is big
+ // enough.
+ // ICU PATCH: Export this as U_I18N_API for unit tests.
+ static void U_I18N_API DoubleToAscii(double v,
+ DtoaMode mode,
+ int requested_digits,
+ char* buffer,
+ int buffer_length,
+ bool* sign,
+ int* length,
+ int* point);
+
+#if 0 // not needed for ICU
+ private:
+ // Implementation for ToShortest and ToShortestSingle.
+ bool ToShortestIeeeNumber(double value,
+ StringBuilder* result_builder,
+ DtoaMode mode) const;
+
+ // If the value is a special value (NaN or Infinity) constructs the
+ // corresponding string using the configured infinity/nan-symbol.
+ // If either of them is NULL or the value is not special then the
+ // function returns false.
+ bool HandleSpecialValues(double value, StringBuilder* result_builder) const;
+ // Constructs an exponential representation (i.e. 1.234e56).
+ // The given exponent assumes a decimal point after the first decimal digit.
+ void CreateExponentialRepresentation(const char* decimal_digits,
+ int length,
+ int exponent,
+ StringBuilder* result_builder) const;
+ // Creates a decimal representation (i.e 1234.5678).
+ void CreateDecimalRepresentation(const char* decimal_digits,
+ int length,
+ int decimal_point,
+ int digits_after_point,
+ StringBuilder* result_builder) const;
+
+ const int flags_;
+ const char* const infinity_symbol_;
+ const char* const nan_symbol_;
+ const char exponent_character_;
+ const int decimal_in_shortest_low_;
+ const int decimal_in_shortest_high_;
+ const int max_leading_padding_zeroes_in_precision_mode_;
+ const int max_trailing_padding_zeroes_in_precision_mode_;
+ const int min_exponent_width_;
+#endif // not needed for ICU
+
+ DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS(DoubleToStringConverter);
+};
+
+} // namespace double_conversion
+
+// ICU PATCH: Close ICU namespace
+U_NAMESPACE_END
+
+#endif // DOUBLE_CONVERSION_DOUBLE_TO_STRING_H_
+#endif // ICU PATCH: close #if !UCONFIG_NO_FORMATTING
diff --git a/deps/icu-small/source/i18n/double-conversion-fast-dtoa.cpp b/deps/icu-small/source/i18n/double-conversion-fast-dtoa.cpp
index 8d1499a79b..87a3d536bf 100644
--- a/deps/icu-small/source/i18n/double-conversion-fast-dtoa.cpp
+++ b/deps/icu-small/source/i18n/double-conversion-fast-dtoa.cpp
@@ -152,7 +152,7 @@ static bool RoundWeed(Vector<char> buffer,
// Conceptually rest ~= too_high - buffer
// We need to do the following tests in this order to avoid over- and
// underflows.
- ASSERT(rest <= unsafe_interval);
+ DOUBLE_CONVERSION_ASSERT(rest <= unsafe_interval);
while (rest < small_distance && // Negated condition 1
unsafe_interval - rest >= ten_kappa && // Negated condition 2
(rest + ten_kappa < small_distance || // buffer{-1} > w_high
@@ -198,7 +198,7 @@ static bool RoundWeedCounted(Vector<char> buffer,
uint64_t ten_kappa,
uint64_t unit,
int* kappa) {
- ASSERT(rest < ten_kappa);
+ DOUBLE_CONVERSION_ASSERT(rest < ten_kappa);
// The following tests are done in a specific order to avoid overflows. They
// will work correctly with any uint64 values of rest < ten_kappa and unit.
//
@@ -255,7 +255,7 @@ static void BiggestPowerTen(uint32_t number,
int number_bits,
uint32_t* power,
int* exponent_plus_one) {
- ASSERT(number < (1u << (number_bits + 1)));
+ DOUBLE_CONVERSION_ASSERT(number < (1u << (number_bits + 1)));
// 1233/4096 is approximately 1/lg(10).
int exponent_plus_one_guess = ((number_bits + 1) * 1233 >> 12);
// We increment to skip over the first entry in the kPowersOf10 table.
@@ -317,9 +317,9 @@ static bool DigitGen(DiyFp low,
Vector<char> buffer,
int* length,
int* kappa) {
- ASSERT(low.e() == w.e() && w.e() == high.e());
- ASSERT(low.f() + 1 <= high.f() - 1);
- ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent);
+ DOUBLE_CONVERSION_ASSERT(low.e() == w.e() && w.e() == high.e());
+ DOUBLE_CONVERSION_ASSERT(low.f() + 1 <= high.f() - 1);
+ DOUBLE_CONVERSION_ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent);
// low, w and high are imprecise, but by less than one ulp (unit in the last
// place).
// If we remove (resp. add) 1 ulp from low (resp. high) we are certain that
@@ -361,7 +361,7 @@ static bool DigitGen(DiyFp low,
// that is smaller than integrals.
while (*kappa > 0) {
int digit = integrals / divisor;
- ASSERT(digit <= 9);
+ DOUBLE_CONVERSION_ASSERT(digit <= 9);
buffer[*length] = static_cast<char>('0' + digit);
(*length)++;
integrals %= divisor;
@@ -388,16 +388,16 @@ static bool DigitGen(DiyFp low,
// data (like the interval or 'unit'), too.
// Note that the multiplication by 10 does not overflow, because w.e >= -60
// and thus one.e >= -60.
- ASSERT(one.e() >= -60);
- ASSERT(fractionals < one.f());
- ASSERT(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
+ DOUBLE_CONVERSION_ASSERT(one.e() >= -60);
+ DOUBLE_CONVERSION_ASSERT(fractionals < one.f());
+ DOUBLE_CONVERSION_ASSERT(DOUBLE_CONVERSION_UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
for (;;) {
fractionals *= 10;
unit *= 10;
unsafe_interval.set_f(unsafe_interval.f() * 10);
// Integer division by one.
int digit = static_cast<int>(fractionals >> -one.e());
- ASSERT(digit <= 9);
+ DOUBLE_CONVERSION_ASSERT(digit <= 9);
buffer[*length] = static_cast<char>('0' + digit);
(*length)++;
fractionals &= one.f() - 1; // Modulo by one.
@@ -444,9 +444,9 @@ static bool DigitGenCounted(DiyFp w,
Vector<char> buffer,
int* length,
int* kappa) {
- ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent);
- ASSERT(kMinimalTargetExponent >= -60);
- ASSERT(kMaximalTargetExponent <= -32);
+ DOUBLE_CONVERSION_ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent);
+ DOUBLE_CONVERSION_ASSERT(kMinimalTargetExponent >= -60);
+ DOUBLE_CONVERSION_ASSERT(kMaximalTargetExponent <= -32);
// w is assumed to have an error less than 1 unit. Whenever w is scaled we
// also scale its error.
uint64_t w_error = 1;
@@ -472,7 +472,7 @@ static bool DigitGenCounted(DiyFp w,
// that is smaller than 'integrals'.
while (*kappa > 0) {
int digit = integrals / divisor;
- ASSERT(digit <= 9);
+ DOUBLE_CONVERSION_ASSERT(digit <= 9);
buffer[*length] = static_cast<char>('0' + digit);
(*length)++;
requested_digits--;
@@ -498,15 +498,15 @@ static bool DigitGenCounted(DiyFp w,
// data (the 'unit'), too.
// Note that the multiplication by 10 does not overflow, because w.e >= -60
// and thus one.e >= -60.
- ASSERT(one.e() >= -60);
- ASSERT(fractionals < one.f());
- ASSERT(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
+ DOUBLE_CONVERSION_ASSERT(one.e() >= -60);
+ DOUBLE_CONVERSION_ASSERT(fractionals < one.f());
+ DOUBLE_CONVERSION_ASSERT(DOUBLE_CONVERSION_UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
while (requested_digits > 0 && fractionals > w_error) {
fractionals *= 10;
w_error *= 10;
// Integer division by one.
int digit = static_cast<int>(fractionals >> -one.e());
- ASSERT(digit <= 9);
+ DOUBLE_CONVERSION_ASSERT(digit <= 9);
buffer[*length] = static_cast<char>('0' + digit);
(*length)++;
requested_digits--;
@@ -544,11 +544,11 @@ static bool Grisu3(double v,
if (mode == FAST_DTOA_SHORTEST) {
Double(v).NormalizedBoundaries(&boundary_minus, &boundary_plus);
} else {
- ASSERT(mode == FAST_DTOA_SHORTEST_SINGLE);
+ DOUBLE_CONVERSION_ASSERT(mode == FAST_DTOA_SHORTEST_SINGLE);
float single_v = static_cast<float>(v);
Single(single_v).NormalizedBoundaries(&boundary_minus, &boundary_plus);
}
- ASSERT(boundary_plus.e() == w.e());
+ DOUBLE_CONVERSION_ASSERT(boundary_plus.e() == w.e());
DiyFp ten_mk; // Cached power of ten: 10^-k
int mk; // -k
int ten_mk_minimal_binary_exponent =
@@ -559,7 +559,7 @@ static bool Grisu3(double v,
ten_mk_minimal_binary_exponent,
ten_mk_maximal_binary_exponent,
&ten_mk, &mk);
- ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() +
+ DOUBLE_CONVERSION_ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() +
DiyFp::kSignificandSize) &&
(kMaximalTargetExponent >= w.e() + ten_mk.e() +
DiyFp::kSignificandSize));
@@ -573,7 +573,7 @@ static bool Grisu3(double v,
// In other words: let f = scaled_w.f() and e = scaled_w.e(), then
// (f-1) * 2^e < w*10^k < (f+1) * 2^e
DiyFp scaled_w = DiyFp::Times(w, ten_mk);
- ASSERT(scaled_w.e() ==
+ DOUBLE_CONVERSION_ASSERT(scaled_w.e() ==
boundary_plus.e() + ten_mk.e() + DiyFp::kSignificandSize);
// In theory it would be possible to avoid some recomputations by computing
// the difference between w and boundary_minus/plus (a power of 2) and to
@@ -618,7 +618,7 @@ static bool Grisu3Counted(double v,
ten_mk_minimal_binary_exponent,
ten_mk_maximal_binary_exponent,
&ten_mk, &mk);
- ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() +
+ DOUBLE_CONVERSION_ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() +
DiyFp::kSignificandSize) &&
(kMaximalTargetExponent >= w.e() + ten_mk.e() +
DiyFp::kSignificandSize));
@@ -652,8 +652,8 @@ bool FastDtoa(double v,
Vector<char> buffer,
int* length,
int* decimal_point) {
- ASSERT(v > 0);
- ASSERT(!Double(v).IsSpecial());
+ DOUBLE_CONVERSION_ASSERT(v > 0);
+ DOUBLE_CONVERSION_ASSERT(!Double(v).IsSpecial());
bool result = false;
int decimal_exponent = 0;
@@ -667,7 +667,7 @@ bool FastDtoa(double v,
buffer, length, &decimal_exponent);
break;
default:
- UNREACHABLE();
+ DOUBLE_CONVERSION_UNREACHABLE();
}
if (result) {
*decimal_point = *length + decimal_exponent;
diff --git a/deps/icu-small/source/i18n/double-conversion-ieee.h b/deps/icu-small/source/i18n/double-conversion-ieee.h
index c83c8d9abb..f4c62a9a9f 100644
--- a/deps/icu-small/source/i18n/double-conversion-ieee.h
+++ b/deps/icu-small/source/i18n/double-conversion-ieee.h
@@ -55,12 +55,14 @@ static float uint32_to_float(uint32_t d32) { return BitCast<float>(d32); }
// Helper functions for doubles.
class Double {
public:
- static const uint64_t kSignMask = UINT64_2PART_C(0x80000000, 00000000);
- static const uint64_t kExponentMask = UINT64_2PART_C(0x7FF00000, 00000000);
- static const uint64_t kSignificandMask = UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
- static const uint64_t kHiddenBit = UINT64_2PART_C(0x00100000, 00000000);
+ static const uint64_t kSignMask = DOUBLE_CONVERSION_UINT64_2PART_C(0x80000000, 00000000);
+ static const uint64_t kExponentMask = DOUBLE_CONVERSION_UINT64_2PART_C(0x7FF00000, 00000000);
+ static const uint64_t kSignificandMask = DOUBLE_CONVERSION_UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
+ static const uint64_t kHiddenBit = DOUBLE_CONVERSION_UINT64_2PART_C(0x00100000, 00000000);
static const int kPhysicalSignificandSize = 52; // Excludes the hidden bit.
static const int kSignificandSize = 53;
+ static const int kExponentBias = 0x3FF + kPhysicalSignificandSize;
+ static const int kMaxExponent = 0x7FF - kExponentBias;
Double() : d64_(0) {}
explicit Double(double d) : d64_(double_to_uint64(d)) {}
@@ -71,14 +73,14 @@ class Double {
// The value encoded by this Double must be greater or equal to +0.0.
// It must not be special (infinity, or NaN).
DiyFp AsDiyFp() const {
- ASSERT(Sign() > 0);
- ASSERT(!IsSpecial());
+ DOUBLE_CONVERSION_ASSERT(Sign() > 0);
+ DOUBLE_CONVERSION_ASSERT(!IsSpecial());
return DiyFp(Significand(), Exponent());
}
// The value encoded by this Double must be strictly greater than 0.
DiyFp AsNormalizedDiyFp() const {
- ASSERT(value() > 0.0);
+ DOUBLE_CONVERSION_ASSERT(value() > 0.0);
uint64_t f = Significand();
int e = Exponent();
@@ -174,7 +176,7 @@ class Double {
// Precondition: the value encoded by this Double must be greater or equal
// than +0.0.
DiyFp UpperBoundary() const {
- ASSERT(Sign() > 0);
+ DOUBLE_CONVERSION_ASSERT(Sign() > 0);
return DiyFp(Significand() * 2 + 1, Exponent() - 1);
}
@@ -183,7 +185,7 @@ class Double {
// exponent as m_plus.
// Precondition: the value encoded by this Double must be greater than 0.
void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const {
- ASSERT(value() > 0.0);
+ DOUBLE_CONVERSION_ASSERT(value() > 0.0);
DiyFp v = this->AsDiyFp();
DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1));
DiyFp m_minus;
@@ -236,11 +238,9 @@ class Double {
}
private:
- static const int kExponentBias = 0x3FF + kPhysicalSignificandSize;
static const int kDenormalExponent = -kExponentBias + 1;
- static const int kMaxExponent = 0x7FF - kExponentBias;
- static const uint64_t kInfinity = UINT64_2PART_C(0x7FF00000, 00000000);
- static const uint64_t kNaN = UINT64_2PART_C(0x7FF80000, 00000000);
+ static const uint64_t kInfinity = DOUBLE_CONVERSION_UINT64_2PART_C(0x7FF00000, 00000000);
+ static const uint64_t kNaN = DOUBLE_CONVERSION_UINT64_2PART_C(0x7FF80000, 00000000);
const uint64_t d64_;
@@ -271,7 +271,7 @@ class Double {
(biased_exponent << kPhysicalSignificandSize);
}
- DC_DISALLOW_COPY_AND_ASSIGN(Double);
+ DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(Double);
};
class Single {
@@ -290,8 +290,8 @@ class Single {
// The value encoded by this Single must be greater or equal to +0.0.
// It must not be special (infinity, or NaN).
DiyFp AsDiyFp() const {
- ASSERT(Sign() > 0);
- ASSERT(!IsSpecial());
+ DOUBLE_CONVERSION_ASSERT(Sign() > 0);
+ DOUBLE_CONVERSION_ASSERT(!IsSpecial());
return DiyFp(Significand(), Exponent());
}
@@ -354,7 +354,7 @@ class Single {
// exponent as m_plus.
// Precondition: the value encoded by this Single must be greater than 0.
void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const {
- ASSERT(value() > 0.0);
+ DOUBLE_CONVERSION_ASSERT(value() > 0.0);
DiyFp v = this->AsDiyFp();
DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1));
DiyFp m_minus;
@@ -372,7 +372,7 @@ class Single {
// Precondition: the value encoded by this Single must be greater or equal
// than +0.0.
DiyFp UpperBoundary() const {
- ASSERT(Sign() > 0);
+ DOUBLE_CONVERSION_ASSERT(Sign() > 0);
return DiyFp(Significand() * 2 + 1, Exponent() - 1);
}
@@ -408,7 +408,7 @@ class Single {
const uint32_t d32_;
- DC_DISALLOW_COPY_AND_ASSIGN(Single);
+ DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(Single);
};
} // namespace double_conversion
diff --git a/deps/icu-small/source/i18n/double-conversion.cpp b/deps/icu-small/source/i18n/double-conversion-string-to-double.cpp
index 1a60afbd64..946b2b26e7 100644
--- a/deps/icu-small/source/i18n/double-conversion.cpp
+++ b/deps/icu-small/source/i18n/double-conversion-string-to-double.cpp
@@ -37,16 +37,13 @@
// ICU PATCH: Do not include std::locale.
#include <climits>
-//#include <locale>
+// #include <locale>
#include <cmath>
// ICU PATCH: Customize header file paths for ICU.
-// The file fixed-dtoa.h is not needed.
-#include "double-conversion.h"
+#include "double-conversion-string-to-double.h"
-#include "double-conversion-bignum-dtoa.h"
-#include "double-conversion-fast-dtoa.h"
#include "double-conversion-ieee.h"
#include "double-conversion-strtod.h"
#include "double-conversion-utils.h"
@@ -56,385 +53,6 @@ U_NAMESPACE_BEGIN
namespace double_conversion {
-#if 0 // not needed for ICU
-const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() {
- int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN;
- static DoubleToStringConverter converter(flags,
- "Infinity",
- "NaN",
- 'e',
- -6, 21,
- 6, 0);
- return converter;
-}
-
-
-bool DoubleToStringConverter::HandleSpecialValues(
- double value,
- StringBuilder* result_builder) const {
- Double double_inspect(value);
- if (double_inspect.IsInfinite()) {
- if (infinity_symbol_ == NULL) return false;
- if (value < 0) {
- result_builder->AddCharacter('-');
- }
- result_builder->AddString(infinity_symbol_);
- return true;
- }
- if (double_inspect.IsNan()) {
- if (nan_symbol_ == NULL) return false;
- result_builder->AddString(nan_symbol_);
- return true;
- }
- return false;
-}
-
-
-void DoubleToStringConverter::CreateExponentialRepresentation(
- const char* decimal_digits,
- int length,
- int exponent,
- StringBuilder* result_builder) const {
- ASSERT(length != 0);
- result_builder->AddCharacter(decimal_digits[0]);
- if (length != 1) {
- result_builder->AddCharacter('.');
- result_builder->AddSubstring(&decimal_digits[1], length-1);
- }
- result_builder->AddCharacter(exponent_character_);
- if (exponent < 0) {
- result_builder->AddCharacter('-');
- exponent = -exponent;
- } else {
- if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) {
- result_builder->AddCharacter('+');
- }
- }
- if (exponent == 0) {
- result_builder->AddCharacter('0');
- return;
- }
- ASSERT(exponent < 1e4);
- const int kMaxExponentLength = 5;
- char buffer[kMaxExponentLength + 1];
- buffer[kMaxExponentLength] = '\0';
- int first_char_pos = kMaxExponentLength;
- while (exponent > 0) {
- buffer[--first_char_pos] = '0' + (exponent % 10);
- exponent /= 10;
- }
- result_builder->AddSubstring(&buffer[first_char_pos],
- kMaxExponentLength - first_char_pos);
-}
-
-
-void DoubleToStringConverter::CreateDecimalRepresentation(
- const char* decimal_digits,
- int length,
- int decimal_point,
- int digits_after_point,
- StringBuilder* result_builder) const {
- // Create a representation that is padded with zeros if needed.
- if (decimal_point <= 0) {
- // "0.00000decimal_rep" or "0.000decimal_rep00".
- result_builder->AddCharacter('0');
- if (digits_after_point > 0) {
- result_builder->AddCharacter('.');
- result_builder->AddPadding('0', -decimal_point);
- ASSERT(length <= digits_after_point - (-decimal_point));
- result_builder->AddSubstring(decimal_digits, length);
- int remaining_digits = digits_after_point - (-decimal_point) - length;
- result_builder->AddPadding('0', remaining_digits);
- }
- } else if (decimal_point >= length) {
- // "decimal_rep0000.00000" or "decimal_rep.0000".
- result_builder->AddSubstring(decimal_digits, length);
- result_builder->AddPadding('0', decimal_point - length);
- if (digits_after_point > 0) {
- result_builder->AddCharacter('.');
- result_builder->AddPadding('0', digits_after_point);
- }
- } else {
- // "decima.l_rep000".
- ASSERT(digits_after_point > 0);
- result_builder->AddSubstring(decimal_digits, decimal_point);
- result_builder->AddCharacter('.');
- ASSERT(length - decimal_point <= digits_after_point);
- result_builder->AddSubstring(&decimal_digits[decimal_point],
- length - decimal_point);
- int remaining_digits = digits_after_point - (length - decimal_point);
- result_builder->AddPadding('0', remaining_digits);
- }
- if (digits_after_point == 0) {
- if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) {
- result_builder->AddCharacter('.');
- }
- if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) {
- result_builder->AddCharacter('0');
- }
- }
-}
-
-
-bool DoubleToStringConverter::ToShortestIeeeNumber(
- double value,
- StringBuilder* result_builder,
- DoubleToStringConverter::DtoaMode mode) const {
- ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE);
- if (Double(value).IsSpecial()) {
- return HandleSpecialValues(value, result_builder);
- }
-
- int decimal_point;
- bool sign;
- const int kDecimalRepCapacity = kBase10MaximalLength + 1;
- char decimal_rep[kDecimalRepCapacity];
- int decimal_rep_length;
-
- DoubleToAscii(value, mode, 0, decimal_rep, kDecimalRepCapacity,
- &sign, &decimal_rep_length, &decimal_point);
-
- bool unique_zero = (flags_ & UNIQUE_ZERO) != 0;
- if (sign && (value != 0.0 || !unique_zero)) {
- result_builder->AddCharacter('-');
- }
-
- int exponent = decimal_point - 1;
- if ((decimal_in_shortest_low_ <= exponent) &&
- (exponent < decimal_in_shortest_high_)) {
- CreateDecimalRepresentation(decimal_rep, decimal_rep_length,
- decimal_point,
- Max(0, decimal_rep_length - decimal_point),
- result_builder);
- } else {
- CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent,
- result_builder);
- }
- return true;
-}
-
-
-bool DoubleToStringConverter::ToFixed(double value,
- int requested_digits,
- StringBuilder* result_builder) const {
- ASSERT(kMaxFixedDigitsBeforePoint == 60);
- const double kFirstNonFixed = 1e60;
-
- if (Double(value).IsSpecial()) {
- return HandleSpecialValues(value, result_builder);
- }
-
- if (requested_digits > kMaxFixedDigitsAfterPoint) return false;
- if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false;
-
- // Find a sufficiently precise decimal representation of n.
- int decimal_point;
- bool sign;
- // Add space for the '\0' byte.
- const int kDecimalRepCapacity =
- kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1;
- char decimal_rep[kDecimalRepCapacity];
- int decimal_rep_length;
- DoubleToAscii(value, FIXED, requested_digits,
- decimal_rep, kDecimalRepCapacity,
- &sign, &decimal_rep_length, &decimal_point);
-
- bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
- if (sign && (value != 0.0 || !unique_zero)) {
- result_builder->AddCharacter('-');
- }
-
- CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
- requested_digits, result_builder);
- return true;
-}
-
-
-bool DoubleToStringConverter::ToExponential(
- double value,
- int requested_digits,
- StringBuilder* result_builder) const {
- if (Double(value).IsSpecial()) {
- return HandleSpecialValues(value, result_builder);
- }
-
- if (requested_digits < -1) return false;
- if (requested_digits > kMaxExponentialDigits) return false;
-
- int decimal_point;
- bool sign;
- // Add space for digit before the decimal point and the '\0' character.
- const int kDecimalRepCapacity = kMaxExponentialDigits + 2;
- ASSERT(kDecimalRepCapacity > kBase10MaximalLength);
- char decimal_rep[kDecimalRepCapacity];
- int decimal_rep_length;
-
- if (requested_digits == -1) {
- DoubleToAscii(value, SHORTEST, 0,
- decimal_rep, kDecimalRepCapacity,
- &sign, &decimal_rep_length, &decimal_point);
- } else {
- DoubleToAscii(value, PRECISION, requested_digits + 1,
- decimal_rep, kDecimalRepCapacity,
- &sign, &decimal_rep_length, &decimal_point);
- ASSERT(decimal_rep_length <= requested_digits + 1);
-
- for (int i = decimal_rep_length; i < requested_digits + 1; ++i) {
- decimal_rep[i] = '0';
- }
- decimal_rep_length = requested_digits + 1;
- }
-
- bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
- if (sign && (value != 0.0 || !unique_zero)) {
- result_builder->AddCharacter('-');
- }
-
- int exponent = decimal_point - 1;
- CreateExponentialRepresentation(decimal_rep,
- decimal_rep_length,
- exponent,
- result_builder);
- return true;
-}
-
-
-bool DoubleToStringConverter::ToPrecision(double value,
- int precision,
- StringBuilder* result_builder) const {
- if (Double(value).IsSpecial()) {
- return HandleSpecialValues(value, result_builder);
- }
-
- if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) {
- return false;
- }
-
- // Find a sufficiently precise decimal representation of n.
- int decimal_point;
- bool sign;
- // Add one for the terminating null character.
- const int kDecimalRepCapacity = kMaxPrecisionDigits + 1;
- char decimal_rep[kDecimalRepCapacity];
- int decimal_rep_length;
-
- DoubleToAscii(value, PRECISION, precision,
- decimal_rep, kDecimalRepCapacity,
- &sign, &decimal_rep_length, &decimal_point);
- ASSERT(decimal_rep_length <= precision);
-
- bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
- if (sign && (value != 0.0 || !unique_zero)) {
- result_builder->AddCharacter('-');
- }
-
- // The exponent if we print the number as x.xxeyyy. That is with the
- // decimal point after the first digit.
- int exponent = decimal_point - 1;
-
- int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0;
- if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) ||
- (decimal_point - precision + extra_zero >
- max_trailing_padding_zeroes_in_precision_mode_)) {
- // Fill buffer to contain 'precision' digits.
- // Usually the buffer is already at the correct length, but 'DoubleToAscii'
- // is allowed to return less characters.
- for (int i = decimal_rep_length; i < precision; ++i) {
- decimal_rep[i] = '0';
- }
-
- CreateExponentialRepresentation(decimal_rep,
- precision,
- exponent,
- result_builder);
- } else {
- CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
- Max(0, precision - decimal_point),
- result_builder);
- }
- return true;
-}
-#endif // not needed for ICU
-
-
-static BignumDtoaMode DtoaToBignumDtoaMode(
- DoubleToStringConverter::DtoaMode dtoa_mode) {
- switch (dtoa_mode) {
- case DoubleToStringConverter::SHORTEST: return BIGNUM_DTOA_SHORTEST;
- case DoubleToStringConverter::SHORTEST_SINGLE:
- return BIGNUM_DTOA_SHORTEST_SINGLE;
- case DoubleToStringConverter::FIXED: return BIGNUM_DTOA_FIXED;
- case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
- default:
- UNREACHABLE();
- }
-}
-
-
-void DoubleToStringConverter::DoubleToAscii(double v,
- DtoaMode mode,
- int requested_digits,
- char* buffer,
- int buffer_length,
- bool* sign,
- int* length,
- int* point) {
- Vector<char> vector(buffer, buffer_length);
- ASSERT(!Double(v).IsSpecial());
- ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE || requested_digits >= 0);
-
- if (Double(v).Sign() < 0) {
- *sign = true;
- v = -v;
- } else {
- *sign = false;
- }
-
- if (mode == PRECISION && requested_digits == 0) {
- vector[0] = '\0';
- *length = 0;
- return;
- }
-
- if (v == 0) {
- vector[0] = '0';
- vector[1] = '\0';
- *length = 1;
- *point = 1;
- return;
- }
-
- bool fast_worked;
- switch (mode) {
- case SHORTEST:
- fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point);
- break;
-#if 0 // not needed for ICU
- case SHORTEST_SINGLE:
- fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0,
- vector, length, point);
- break;
- case FIXED:
- fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point);
- break;
- case PRECISION:
- fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits,
- vector, length, point);
- break;
-#endif // not needed for ICU
- default:
- fast_worked = false;
- UNREACHABLE();
- }
- if (fast_worked) return;
-
- // If the fast dtoa didn't succeed use the slower bignum version.
- BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode);
- BignumDtoa(v, bignum_mode, requested_digits, vector, length, point);
- vector[*length] = '\0';
-}
-
-
namespace {
inline char ToLower(char ch) {
@@ -444,7 +62,7 @@ inline char ToLower(char ch) {
return cType.tolower(ch);
#else
(void)ch;
- UNREACHABLE();
+ DOUBLE_CONVERSION_UNREACHABLE();
#endif
}
@@ -457,7 +75,7 @@ static inline bool ConsumeSubStringImpl(Iterator* current,
Iterator end,
const char* substring,
Converter converter) {
- ASSERT(converter(**current) == *substring);
+ DOUBLE_CONVERSION_ASSERT(converter(**current) == *substring);
for (substring++; *substring != '\0'; substring++) {
++*current;
if (*current == end || converter(**current) != *substring) {
@@ -474,8 +92,8 @@ template <class Iterator>
static bool ConsumeSubString(Iterator* current,
Iterator end,
const char* substring,
- bool allow_case_insensibility) {
- if (allow_case_insensibility) {
+ bool allow_case_insensitivity) {
+ if (allow_case_insensitivity) {
return ConsumeSubStringImpl(current, end, substring, ToLower);
} else {
return ConsumeSubStringImpl(current, end, substring, Pass);
@@ -485,8 +103,8 @@ static bool ConsumeSubString(Iterator* current,
// Consumes first character of the str is equal to ch
inline bool ConsumeFirstCharacter(char ch,
const char* str,
- bool case_insensibility) {
- return case_insensibility ? ToLower(ch) == str[0] : ch == str[0];
+ bool case_insensitivity) {
+ return case_insensitivity ? ToLower(ch) == str[0] : ch == str[0];
}
} // namespace
@@ -501,15 +119,14 @@ const int kMaxSignificantDigits = 772;
static const char kWhitespaceTable7[] = { 32, 13, 10, 9, 11, 12 };
-static const int kWhitespaceTable7Length = ARRAY_SIZE(kWhitespaceTable7);
+static const int kWhitespaceTable7Length = DOUBLE_CONVERSION_ARRAY_SIZE(kWhitespaceTable7);
static const uc16 kWhitespaceTable16[] = {
160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195,
8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279
};
-static const int kWhitespaceTable16Length = ARRAY_SIZE(kWhitespaceTable16);
-
+static const int kWhitespaceTable16Length = DOUBLE_CONVERSION_ARRAY_SIZE(kWhitespaceTable16);
static bool isWhitespace(int x) {
@@ -609,7 +226,7 @@ static bool IsHexFloatString(Iterator start,
Iterator end,
uc16 separator,
bool allow_trailing_junk) {
- ASSERT(start != end);
+ DOUBLE_CONVERSION_ASSERT(start != end);
Iterator current = start;
@@ -624,8 +241,8 @@ static bool IsHexFloatString(Iterator start,
saw_digit = true;
if (Advance(&current, separator, 16, end)) return false;
}
- if (!saw_digit) return false; // Only the '.', but no digits.
}
+ if (!saw_digit) return false;
if (*current != 'p' && *current != 'P') return false;
if (Advance(&current, separator, 16, end)) return false;
if (*current == '+' || *current == '-') {
@@ -654,8 +271,8 @@ static double RadixStringToIeee(Iterator* current,
double junk_string_value,
bool read_as_double,
bool* result_is_junk) {
- ASSERT(*current != end);
- ASSERT(!parse_as_hex_float ||
+ DOUBLE_CONVERSION_ASSERT(*current != end);
+ DOUBLE_CONVERSION_ASSERT(!parse_as_hex_float ||
IsHexFloatString(*current, end, separator, allow_trailing_junk));
const int kDoubleSize = Double::kSignificandSize;
@@ -693,7 +310,7 @@ static double RadixStringToIeee(Iterator* current,
} else if (parse_as_hex_float && **current == '.') {
post_decimal = true;
Advance(current, separator, radix, end);
- ASSERT(*current != end);
+ DOUBLE_CONVERSION_ASSERT(*current != end);
continue;
} else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) {
break;
@@ -728,7 +345,7 @@ static double RadixStringToIeee(Iterator* current,
// Just run over the '.'. We are just trying to see whether there is
// a non-zero digit somewhere.
Advance(current, separator, radix, end);
- ASSERT(*current != end);
+ DOUBLE_CONVERSION_ASSERT(*current != end);
post_decimal = true;
}
if (!isDigit(**current, radix)) break;
@@ -763,27 +380,31 @@ static double RadixStringToIeee(Iterator* current,
if (Advance(current, separator, radix, end)) break;
}
- ASSERT(number < ((int64_t)1 << kSignificandSize));
- ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
+ DOUBLE_CONVERSION_ASSERT(number < ((int64_t)1 << kSignificandSize));
+ DOUBLE_CONVERSION_ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
*result_is_junk = false;
if (parse_as_hex_float) {
- ASSERT(**current == 'p' || **current == 'P');
+ DOUBLE_CONVERSION_ASSERT(**current == 'p' || **current == 'P');
Advance(current, separator, radix, end);
- ASSERT(*current != end);
+ DOUBLE_CONVERSION_ASSERT(*current != end);
bool is_negative = false;
if (**current == '+') {
Advance(current, separator, radix, end);
- ASSERT(*current != end);
+ DOUBLE_CONVERSION_ASSERT(*current != end);
} else if (**current == '-') {
is_negative = true;
Advance(current, separator, radix, end);
- ASSERT(*current != end);
+ DOUBLE_CONVERSION_ASSERT(*current != end);
}
int written_exponent = 0;
while (IsDecimalDigitForRadix(**current, 10)) {
- written_exponent = 10 * written_exponent + **current - '0';
+ // No need to read exponents if they are too big. That could potentially overflow
+ // the `written_exponent` variable.
+ if (abs(written_exponent) <= 100 * Double::kMaxExponent) {
+ written_exponent = 10 * written_exponent + **current - '0';
+ }
if (Advance(current, separator, radix, end)) break;
}
if (is_negative) written_exponent = -written_exponent;
@@ -798,7 +419,7 @@ static double RadixStringToIeee(Iterator* current,
return static_cast<double>(number);
}
- ASSERT(number != 0);
+ DOUBLE_CONVERSION_ASSERT(number != 0);
double result = Double(DiyFp(number, exponent)).value();
return sign ? -result : result;
}
@@ -818,7 +439,7 @@ double StringToDoubleConverter::StringToIeee(
const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0;
const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0;
const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
- const bool allow_case_insensibility = (flags_ & ALLOW_CASE_INSENSIBILITY) != 0;
+ const bool allow_case_insensitivity = (flags_ & ALLOW_CASE_INSENSITIVITY) != 0;
// To make sure that iterator dereferencing is valid the following
// convention is used:
@@ -868,8 +489,8 @@ double StringToDoubleConverter::StringToIeee(
}
if (infinity_symbol_ != NULL) {
- if (ConsumeFirstCharacter(*current, infinity_symbol_, allow_case_insensibility)) {
- if (!ConsumeSubString(&current, end, infinity_symbol_, allow_case_insensibility)) {
+ if (ConsumeFirstCharacter(*current, infinity_symbol_, allow_case_insensitivity)) {
+ if (!ConsumeSubString(&current, end, infinity_symbol_, allow_case_insensitivity)) {
return junk_string_value_;
}
@@ -880,15 +501,15 @@ double StringToDoubleConverter::StringToIeee(
return junk_string_value_;
}
- ASSERT(buffer_pos == 0);
+ DOUBLE_CONVERSION_ASSERT(buffer_pos == 0);
*processed_characters_count = static_cast<int>(current - input);
return sign ? -Double::Infinity() : Double::Infinity();
}
}
if (nan_symbol_ != NULL) {
- if (ConsumeFirstCharacter(*current, nan_symbol_, allow_case_insensibility)) {
- if (!ConsumeSubString(&current, end, nan_symbol_, allow_case_insensibility)) {
+ if (ConsumeFirstCharacter(*current, nan_symbol_, allow_case_insensitivity)) {
+ if (!ConsumeSubString(&current, end, nan_symbol_, allow_case_insensitivity)) {
return junk_string_value_;
}
@@ -899,7 +520,7 @@ double StringToDoubleConverter::StringToIeee(
return junk_string_value_;
}
- ASSERT(buffer_pos == 0);
+ DOUBLE_CONVERSION_ASSERT(buffer_pos == 0);
*processed_characters_count = static_cast<int>(current - input);
return sign ? -Double::NaN() : Double::NaN();
}
@@ -919,10 +540,11 @@ double StringToDoubleConverter::StringToIeee(
(*current == 'x' || *current == 'X')) {
++current;
+ if (current == end) return junk_string_value_; // "0x"
+
bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) &&
IsHexFloatString(current, end, separator_, allow_trailing_junk);
- if (current == end) return junk_string_value_; // "0x"
if (!parse_as_hex_float && !isDigit(*current, 16)) {
return junk_string_value_;
}
@@ -958,7 +580,7 @@ double StringToDoubleConverter::StringToIeee(
// Copy significant digits of the integer part (if any) to the buffer.
while (*current >= '0' && *current <= '9') {
if (significant_digits < kMaxSignificantDigits) {
- ASSERT(buffer_pos < kBufferSize);
+ DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize);
buffer[buffer_pos++] = static_cast<char>(*current);
significant_digits++;
// Will later check if it's an octal in the buffer.
@@ -1003,7 +625,7 @@ double StringToDoubleConverter::StringToIeee(
// We don't emit a '.', but adjust the exponent instead.
while (*current >= '0' && *current <= '9') {
if (significant_digits < kMaxSignificantDigits) {
- ASSERT(buffer_pos < kBufferSize);
+ DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize);
buffer[buffer_pos++] = static_cast<char>(*current);
significant_digits++;
exponent--;
@@ -1061,7 +683,7 @@ double StringToDoubleConverter::StringToIeee(
}
const int max_exponent = INT_MAX / 2;
- ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
+ DOUBLE_CONVERSION_ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
int num = 0;
do {
// Check overflow.
@@ -1104,7 +726,7 @@ double StringToDoubleConverter::StringToIeee(
junk_string_value_,
read_as_double,
&result_is_junk);
- ASSERT(!result_is_junk);
+ DOUBLE_CONVERSION_ASSERT(!result_is_junk);
*processed_characters_count = static_cast<int>(current - input);
return result;
}
@@ -1114,7 +736,7 @@ double StringToDoubleConverter::StringToIeee(
exponent--;
}
- ASSERT(buffer_pos < kBufferSize);
+ DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize);
buffer[buffer_pos] = '\0';
double converted;
diff --git a/deps/icu-small/source/i18n/double-conversion-string-to-double.h b/deps/icu-small/source/i18n/double-conversion-string-to-double.h
new file mode 100644
index 0000000000..2eb0c1f897
--- /dev/null
+++ b/deps/icu-small/source/i18n/double-conversion-string-to-double.h
@@ -0,0 +1,244 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+//
+// From the double-conversion library. Original license:
+//
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ICU PATCH: ifdef around UCONFIG_NO_FORMATTING
+#include "unicode/utypes.h"
+#if !UCONFIG_NO_FORMATTING
+
+#ifndef DOUBLE_CONVERSION_STRING_TO_DOUBLE_H_
+#define DOUBLE_CONVERSION_STRING_TO_DOUBLE_H_
+
+// ICU PATCH: Customize header file paths for ICU.
+
+#include "double-conversion-utils.h"
+
+// ICU PATCH: Wrap in ICU namespace
+U_NAMESPACE_BEGIN
+
+namespace double_conversion {
+
+class StringToDoubleConverter {
+ public:
+ // Enumeration for allowing octals and ignoring junk when converting
+ // strings to numbers.
+ enum Flags {
+ NO_FLAGS = 0,
+ ALLOW_HEX = 1,
+ ALLOW_OCTALS = 2,
+ ALLOW_TRAILING_JUNK = 4,
+ ALLOW_LEADING_SPACES = 8,
+ ALLOW_TRAILING_SPACES = 16,
+ ALLOW_SPACES_AFTER_SIGN = 32,
+ ALLOW_CASE_INSENSITIVITY = 64,
+ ALLOW_CASE_INSENSIBILITY = 64, // Deprecated
+ ALLOW_HEX_FLOATS = 128,
+ };
+
+ static const uc16 kNoSeparator = '\0';
+
+ // Flags should be a bit-or combination of the possible Flags-enum.
+ // - NO_FLAGS: no special flags.
+ // - ALLOW_HEX: recognizes the prefix "0x". Hex numbers may only be integers.
+ // Ex: StringToDouble("0x1234") -> 4660.0
+ // In StringToDouble("0x1234.56") the characters ".56" are trailing
+ // junk. The result of the call is hence dependent on
+ // the ALLOW_TRAILING_JUNK flag and/or the junk value.
+ // With this flag "0x" is a junk-string. Even with ALLOW_TRAILING_JUNK,
+ // the string will not be parsed as "0" followed by junk.
+ //
+ // - ALLOW_OCTALS: recognizes the prefix "0" for octals:
+ // If a sequence of octal digits starts with '0', then the number is
+ // read as octal integer. Octal numbers may only be integers.
+ // Ex: StringToDouble("01234") -> 668.0
+ // StringToDouble("012349") -> 12349.0 // Not a sequence of octal
+ // // digits.
+ // In StringToDouble("01234.56") the characters ".56" are trailing
+ // junk. The result of the call is hence dependent on
+ // the ALLOW_TRAILING_JUNK flag and/or the junk value.
+ // In StringToDouble("01234e56") the characters "e56" are trailing
+ // junk, too.
+ // - ALLOW_TRAILING_JUNK: ignore trailing characters that are not part of
+ // a double literal.
+ // - ALLOW_LEADING_SPACES: skip over leading whitespace, including spaces,
+ // new-lines, and tabs.
+ // - ALLOW_TRAILING_SPACES: ignore trailing whitespace.
+ // - ALLOW_SPACES_AFTER_SIGN: ignore whitespace after the sign.
+ // Ex: StringToDouble("- 123.2") -> -123.2.
+ // StringToDouble("+ 123.2") -> 123.2
+ // - ALLOW_CASE_INSENSITIVITY: ignore case of characters for special values:
+ // infinity and nan.
+ // - ALLOW_HEX_FLOATS: allows hexadecimal float literals.
+ // This *must* start with "0x" and separate the exponent with "p".
+ // Examples: 0x1.2p3 == 9.0
+ // 0x10.1p0 == 16.0625
+ // ALLOW_HEX and ALLOW_HEX_FLOATS are indendent.
+ //
+ // empty_string_value is returned when an empty string is given as input.
+ // If ALLOW_LEADING_SPACES or ALLOW_TRAILING_SPACES are set, then a string
+ // containing only spaces is converted to the 'empty_string_value', too.
+ //
+ // junk_string_value is returned when
+ // a) ALLOW_TRAILING_JUNK is not set, and a junk character (a character not
+ // part of a double-literal) is found.
+ // b) ALLOW_TRAILING_JUNK is set, but the string does not start with a
+ // double literal.
+ //
+ // infinity_symbol and nan_symbol are strings that are used to detect
+ // inputs that represent infinity and NaN. They can be null, in which case
+ // they are ignored.
+ // The conversion routine first reads any possible signs. Then it compares the
+ // following character of the input-string with the first character of
+ // the infinity, and nan-symbol. If either matches, the function assumes, that
+ // a match has been found, and expects the following input characters to match
+ // the remaining characters of the special-value symbol.
+ // This means that the following restrictions apply to special-value symbols:
+ // - they must not start with signs ('+', or '-'),
+ // - they must not have the same first character.
+ // - they must not start with digits.
+ //
+ // If the separator character is not kNoSeparator, then that specific
+ // character is ignored when in between two valid digits of the significant.
+ // It is not allowed to appear in the exponent.
+ // It is not allowed to lead or trail the number.
+ // It is not allowed to appear twice next to each other.
+ //
+ // Examples:
+ // flags = ALLOW_HEX | ALLOW_TRAILING_JUNK,
+ // empty_string_value = 0.0,
+ // junk_string_value = NaN,
+ // infinity_symbol = "infinity",
+ // nan_symbol = "nan":
+ // StringToDouble("0x1234") -> 4660.0.
+ // StringToDouble("0x1234K") -> 4660.0.
+ // StringToDouble("") -> 0.0 // empty_string_value.
+ // StringToDouble(" ") -> NaN // junk_string_value.
+ // StringToDouble(" 1") -> NaN // junk_string_value.
+ // StringToDouble("0x") -> NaN // junk_string_value.
+ // StringToDouble("-123.45") -> -123.45.
+ // StringToDouble("--123.45") -> NaN // junk_string_value.
+ // StringToDouble("123e45") -> 123e45.
+ // StringToDouble("123E45") -> 123e45.
+ // StringToDouble("123e+45") -> 123e45.
+ // StringToDouble("123E-45") -> 123e-45.
+ // StringToDouble("123e") -> 123.0 // trailing junk ignored.
+ // StringToDouble("123e-") -> 123.0 // trailing junk ignored.
+ // StringToDouble("+NaN") -> NaN // NaN string literal.
+ // StringToDouble("-infinity") -> -inf. // infinity literal.
+ // StringToDouble("Infinity") -> NaN // junk_string_value.
+ //
+ // flags = ALLOW_OCTAL | ALLOW_LEADING_SPACES,
+ // empty_string_value = 0.0,
+ // junk_string_value = NaN,
+ // infinity_symbol = NULL,
+ // nan_symbol = NULL:
+ // StringToDouble("0x1234") -> NaN // junk_string_value.
+ // StringToDouble("01234") -> 668.0.
+ // StringToDouble("") -> 0.0 // empty_string_value.
+ // StringToDouble(" ") -> 0.0 // empty_string_value.
+ // StringToDouble(" 1") -> 1.0
+ // StringToDouble("0x") -> NaN // junk_string_value.
+ // StringToDouble("0123e45") -> NaN // junk_string_value.
+ // StringToDouble("01239E45") -> 1239e45.
+ // StringToDouble("-infinity") -> NaN // junk_string_value.
+ // StringToDouble("NaN") -> NaN // junk_string_value.
+ //
+ // flags = NO_FLAGS,
+ // separator = ' ':
+ // StringToDouble("1 2 3 4") -> 1234.0
+ // StringToDouble("1 2") -> NaN // junk_string_value
+ // StringToDouble("1 000 000.0") -> 1000000.0
+ // StringToDouble("1.000 000") -> 1.0
+ // StringToDouble("1.0e1 000") -> NaN // junk_string_value
+ StringToDoubleConverter(int flags,
+ double empty_string_value,
+ double junk_string_value,
+ const char* infinity_symbol,
+ const char* nan_symbol,
+ uc16 separator = kNoSeparator)
+ : flags_(flags),
+ empty_string_value_(empty_string_value),
+ junk_string_value_(junk_string_value),
+ infinity_symbol_(infinity_symbol),
+ nan_symbol_(nan_symbol),
+ separator_(separator) {
+ }
+
+ // Performs the conversion.
+ // The output parameter 'processed_characters_count' is set to the number
+ // of characters that have been processed to read the number.
+ // Spaces than are processed with ALLOW_{LEADING|TRAILING}_SPACES are included
+ // in the 'processed_characters_count'. Trailing junk is never included.
+ double StringToDouble(const char* buffer,
+ int length,
+ int* processed_characters_count) const;
+
+ // Same as StringToDouble above but for 16 bit characters.
+ double StringToDouble(const uc16* buffer,
+ int length,
+ int* processed_characters_count) const;
+
+ // Same as StringToDouble but reads a float.
+ // Note that this is not equivalent to static_cast<float>(StringToDouble(...))
+ // due to potential double-rounding.
+ float StringToFloat(const char* buffer,
+ int length,
+ int* processed_characters_count) const;
+
+ // Same as StringToFloat above but for 16 bit characters.
+ float StringToFloat(const uc16* buffer,
+ int length,
+ int* processed_characters_count) const;
+
+ private:
+ const int flags_;
+ const double empty_string_value_;
+ const double junk_string_value_;
+ const char* const infinity_symbol_;
+ const char* const nan_symbol_;
+ const uc16 separator_;
+
+ template <class Iterator>
+ double StringToIeee(Iterator start_pointer,
+ int length,
+ bool read_as_double,
+ int* processed_characters_count) const;
+
+ DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter);
+};
+
+} // namespace double_conversion
+
+// ICU PATCH: Close ICU namespace
+U_NAMESPACE_END
+
+#endif // DOUBLE_CONVERSION_STRING_TO_DOUBLE_H_
+#endif // ICU PATCH: close #if !UCONFIG_NO_FORMATTING
diff --git a/deps/icu-small/source/i18n/double-conversion-strtod.cpp b/deps/icu-small/source/i18n/double-conversion-strtod.cpp
index be9b0b3bce..9cf4854426 100644
--- a/deps/icu-small/source/i18n/double-conversion-strtod.cpp
+++ b/deps/icu-small/source/i18n/double-conversion-strtod.cpp
@@ -34,16 +34,15 @@
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
-#include <stdarg.h>
-#include <limits.h>
+#include <climits>
+#include <cstdarg>
// ICU PATCH: Customize header file paths for ICU.
-// The file fixed-dtoa.h is not needed.
-#include "double-conversion-strtod.h"
#include "double-conversion-bignum.h"
#include "double-conversion-cached-powers.h"
#include "double-conversion-ieee.h"
+#include "double-conversion-strtod.h"
// ICU PATCH: Wrap in ICU namespace
U_NAMESPACE_BEGIN
@@ -67,7 +66,7 @@ static const int kMaxDecimalPower = 309;
static const int kMinDecimalPower = -324;
// 2^64 = 18446744073709551616
-static const uint64_t kMaxUint64 = UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF);
+static const uint64_t kMaxUint64 = DOUBLE_CONVERSION_UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF);
static const double exact_powers_of_ten[] = {
@@ -96,7 +95,7 @@ static const double exact_powers_of_ten[] = {
// 10^22 = 0x21e19e0c9bab2400000 = 0x878678326eac9 * 2^22
10000000000000000000000.0
};
-static const int kExactPowersOfTenSize = ARRAY_SIZE(exact_powers_of_ten);
+static const int kExactPowersOfTenSize = DOUBLE_CONVERSION_ARRAY_SIZE(exact_powers_of_ten);
// Maximum number of significant digits in the decimal representation.
// In fact the value is 772 (see conversions.cc), but to give us some margin
@@ -132,7 +131,7 @@ static void CutToMaxSignificantDigits(Vector<const char> buffer,
}
// The input buffer has been trimmed. Therefore the last digit must be
// different from '0'.
- ASSERT(buffer[buffer.length() - 1] != '0');
+ DOUBLE_CONVERSION_ASSERT(buffer[buffer.length() - 1] != '0');
// Set the last digit to be non-zero. This is sufficient to guarantee
// correct rounding.
significant_buffer[kMaxSignificantDecimalDigits - 1] = '1';
@@ -153,7 +152,7 @@ static void TrimAndCut(Vector<const char> buffer, int exponent,
exponent += left_trimmed.length() - right_trimmed.length();
if (right_trimmed.length() > kMaxSignificantDecimalDigits) {
(void) space_size; // Mark variable as used.
- ASSERT(space_size >= kMaxSignificantDecimalDigits);
+ DOUBLE_CONVERSION_ASSERT(space_size >= kMaxSignificantDecimalDigits);
CutToMaxSignificantDigits(right_trimmed, exponent,
buffer_copy_space, updated_exponent);
*trimmed = Vector<const char>(buffer_copy_space,
@@ -176,7 +175,7 @@ static uint64_t ReadUint64(Vector<const char> buffer,
int i = 0;
while (i < buffer.length() && result <= (kMaxUint64 / 10 - 1)) {
int digit = buffer[i++] - '0';
- ASSERT(0 <= digit && digit <= 9);
+ DOUBLE_CONVERSION_ASSERT(0 <= digit && digit <= 9);
result = 10 * result + digit;
}
*number_of_read_digits = i;
@@ -220,7 +219,7 @@ static bool DoubleStrtod(Vector<const char> trimmed,
// Note that the ARM simulator is compiled for 32bits. It therefore exhibits
// the same problem.
return false;
-#endif
+#else
if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) {
int read_digits;
// The trimmed input fits into a double.
@@ -232,14 +231,14 @@ static bool DoubleStrtod(Vector<const char> trimmed,
if (exponent < 0 && -exponent < kExactPowersOfTenSize) {
// 10^-exponent fits into a double.
*result = static_cast<double>(ReadUint64(trimmed, &read_digits));
- ASSERT(read_digits == trimmed.length());
+ DOUBLE_CONVERSION_ASSERT(read_digits == trimmed.length());
*result /= exact_powers_of_ten[-exponent];
return true;
}
if (0 <= exponent && exponent < kExactPowersOfTenSize) {
// 10^exponent fits into a double.
*result = static_cast<double>(ReadUint64(trimmed, &read_digits));
- ASSERT(read_digits == trimmed.length());
+ DOUBLE_CONVERSION_ASSERT(read_digits == trimmed.length());
*result *= exact_powers_of_ten[exponent];
return true;
}
@@ -251,34 +250,35 @@ static bool DoubleStrtod(Vector<const char> trimmed,
// 10^remaining_digits. As a result the remaining exponent now fits
// into a double too.
*result = static_cast<double>(ReadUint64(trimmed, &read_digits));
- ASSERT(read_digits == trimmed.length());
+ DOUBLE_CONVERSION_ASSERT(read_digits == trimmed.length());
*result *= exact_powers_of_ten[remaining_digits];
*result *= exact_powers_of_ten[exponent - remaining_digits];
return true;
}
}
return false;
+#endif
}
// Returns 10^exponent as an exact DiyFp.
// The given exponent must be in the range [1; kDecimalExponentDistance[.
static DiyFp AdjustmentPowerOfTen(int exponent) {
- ASSERT(0 < exponent);
- ASSERT(exponent < PowersOfTenCache::kDecimalExponentDistance);
+ DOUBLE_CONVERSION_ASSERT(0 < exponent);
+ DOUBLE_CONVERSION_ASSERT(exponent < PowersOfTenCache::kDecimalExponentDistance);
// Simply hardcode the remaining powers for the given decimal exponent
// distance.
- ASSERT(PowersOfTenCache::kDecimalExponentDistance == 8);
+ DOUBLE_CONVERSION_ASSERT(PowersOfTenCache::kDecimalExponentDistance == 8);
switch (exponent) {
- case 1: return DiyFp(UINT64_2PART_C(0xa0000000, 00000000), -60);
- case 2: return DiyFp(UINT64_2PART_C(0xc8000000, 00000000), -57);
- case 3: return DiyFp(UINT64_2PART_C(0xfa000000, 00000000), -54);
- case 4: return DiyFp(UINT64_2PART_C(0x9c400000, 00000000), -50);
- case 5: return DiyFp(UINT64_2PART_C(0xc3500000, 00000000), -47);
- case 6: return DiyFp(UINT64_2PART_C(0xf4240000, 00000000), -44);
- case 7: return DiyFp(UINT64_2PART_C(0x98968000, 00000000), -40);
+ case 1: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0xa0000000, 00000000), -60);
+ case 2: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0xc8000000, 00000000), -57);
+ case 3: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0xfa000000, 00000000), -54);
+ case 4: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0x9c400000, 00000000), -50);
+ case 5: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0xc3500000, 00000000), -47);
+ case 6: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0xf4240000, 00000000), -44);
+ case 7: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0x98968000, 00000000), -40);
default:
- UNREACHABLE();
+ DOUBLE_CONVERSION_UNREACHABLE();
}
}
@@ -307,7 +307,7 @@ static bool DiyFpStrtod(Vector<const char> buffer,
input.Normalize();
error <<= old_e - input.e();
- ASSERT(exponent <= PowersOfTenCache::kMaxDecimalExponent);
+ DOUBLE_CONVERSION_ASSERT(exponent <= PowersOfTenCache::kMaxDecimalExponent);
if (exponent < PowersOfTenCache::kMinDecimalExponent) {
*result = 0.0;
return true;
@@ -325,7 +325,7 @@ static bool DiyFpStrtod(Vector<const char> buffer,
if (kMaxUint64DecimalDigits - buffer.length() >= adjustment_exponent) {
// The product of input with the adjustment power fits into a 64 bit
// integer.
- ASSERT(DiyFp::kSignificandSize == 64);
+ DOUBLE_CONVERSION_ASSERT(DiyFp::kSignificandSize == 64);
} else {
// The adjustment power is exact. There is hence only an error of 0.5.
error += kDenominator / 2;
@@ -367,8 +367,8 @@ static bool DiyFpStrtod(Vector<const char> buffer,
precision_digits_count -= shift_amount;
}
// We use uint64_ts now. This only works if the DiyFp uses uint64_ts too.
- ASSERT(DiyFp::kSignificandSize == 64);
- ASSERT(precision_digits_count < 64);
+ DOUBLE_CONVERSION_ASSERT(DiyFp::kSignificandSize == 64);
+ DOUBLE_CONVERSION_ASSERT(precision_digits_count < 64);
uint64_t one64 = 1;
uint64_t precision_bits_mask = (one64 << precision_digits_count) - 1;
uint64_t precision_bits = input.f() & precision_bits_mask;
@@ -407,14 +407,14 @@ static bool DiyFpStrtod(Vector<const char> buffer,
static int CompareBufferWithDiyFp(Vector<const char> buffer,
int exponent,
DiyFp diy_fp) {
- ASSERT(buffer.length() + exponent <= kMaxDecimalPower + 1);
- ASSERT(buffer.length() + exponent > kMinDecimalPower);
- ASSERT(buffer.length() <= kMaxSignificantDecimalDigits);
+ DOUBLE_CONVERSION_ASSERT(buffer.length() + exponent <= kMaxDecimalPower + 1);
+ DOUBLE_CONVERSION_ASSERT(buffer.length() + exponent > kMinDecimalPower);
+ DOUBLE_CONVERSION_ASSERT(buffer.length() <= kMaxSignificantDecimalDigits);
// Make sure that the Bignum will be able to hold all our numbers.
// Our Bignum implementation has a separate field for exponents. Shifts will
// consume at most one bigit (< 64 bits).
// ln(10) == 3.3219...
- ASSERT(((kMaxDecimalPower + 1) * 333 / 100) < Bignum::kMaxSignificantBits);
+ DOUBLE_CONVERSION_ASSERT(((kMaxDecimalPower + 1) * 333 / 100) < Bignum::kMaxSignificantBits);
Bignum buffer_bignum;
Bignum diy_fp_bignum;
buffer_bignum.AssignDecimalString(buffer);
@@ -460,18 +460,33 @@ static bool ComputeGuess(Vector<const char> trimmed, int exponent,
return false;
}
-double Strtod(Vector<const char> buffer, int exponent) {
- char copy_buffer[kMaxSignificantDecimalDigits];
- Vector<const char> trimmed;
- int updated_exponent;
- TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits,
- &trimmed, &updated_exponent);
- exponent = updated_exponent;
+#if U_DEBUG // needed for ICU only in debug mode
+static bool IsDigit(const char d) {
+ return ('0' <= d) && (d <= '9');
+}
- double guess;
- bool is_correct = ComputeGuess(trimmed, exponent, &guess);
- if (is_correct) return guess;
+static bool IsNonZeroDigit(const char d) {
+ return ('1' <= d) && (d <= '9');
+}
+
+static bool AssertTrimmedDigits(const Vector<const char>& buffer) {
+ for(int i = 0; i < buffer.length(); ++i) {
+ if(!IsDigit(buffer[i])) {
+ return false;
+ }
+ }
+ return (buffer.length() == 0) || (IsNonZeroDigit(buffer[0]) && IsNonZeroDigit(buffer[buffer.length()-1]));
+}
+#endif // needed for ICU only in debug mode
+double StrtodTrimmed(Vector<const char> trimmed, int exponent) {
+ DOUBLE_CONVERSION_ASSERT(trimmed.length() <= kMaxSignificantDecimalDigits);
+ DOUBLE_CONVERSION_ASSERT(AssertTrimmedDigits(trimmed));
+ double guess;
+ const bool is_correct = ComputeGuess(trimmed, exponent, &guess);
+ if (is_correct) {
+ return guess;
+ }
DiyFp upper_boundary = Double(guess).UpperBoundary();
int comparison = CompareBufferWithDiyFp(trimmed, exponent, upper_boundary);
if (comparison < 0) {
@@ -486,6 +501,39 @@ double Strtod(Vector<const char> buffer, int exponent) {
}
}
+double Strtod(Vector<const char> buffer, int exponent) {
+ char copy_buffer[kMaxSignificantDecimalDigits];
+ Vector<const char> trimmed;
+ int updated_exponent;
+ TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits,
+ &trimmed, &updated_exponent);
+ return StrtodTrimmed(trimmed, updated_exponent);
+}
+
+static float SanitizedDoubletof(double d) {
+ DOUBLE_CONVERSION_ASSERT(d >= 0.0);
+ // ASAN has a sanitize check that disallows casting doubles to floats if
+ // they are too big.
+ // https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#available-checks
+ // The behavior should be covered by IEEE 754, but some projects use this
+ // flag, so work around it.
+ float max_finite = 3.4028234663852885981170418348451692544e+38;
+ // The half-way point between the max-finite and infinity value.
+ // Since infinity has an even significand everything equal or greater than
+ // this value should become infinity.
+ double half_max_finite_infinity =
+ 3.40282356779733661637539395458142568448e+38;
+ if (d >= max_finite) {
+ if (d >= half_max_finite_infinity) {
+ return Single::Infinity();
+ } else {
+ return max_finite;
+ }
+ } else {
+ return static_cast<float>(d);
+ }
+}
+
float Strtof(Vector<const char> buffer, int exponent) {
char copy_buffer[kMaxSignificantDecimalDigits];
Vector<const char> trimmed;
@@ -497,7 +545,7 @@ float Strtof(Vector<const char> buffer, int exponent) {
double double_guess;
bool is_correct = ComputeGuess(trimmed, exponent, &double_guess);
- float float_guess = static_cast<float>(double_guess);
+ float float_guess = SanitizedDoubletof(double_guess);
if (float_guess == double_guess) {
// This shortcut triggers for integer values.
return float_guess;
@@ -520,18 +568,18 @@ float Strtof(Vector<const char> buffer, int exponent) {
double double_next = Double(double_guess).NextDouble();
double double_previous = Double(double_guess).PreviousDouble();
- float f1 = static_cast<float>(double_previous);
+ float f1 = SanitizedDoubletof(double_previous);
float f2 = float_guess;
- float f3 = static_cast<float>(double_next);
+ float f3 = SanitizedDoubletof(double_next);
float f4;
if (is_correct) {
f4 = f3;
} else {
double double_next2 = Double(double_next).NextDouble();
- f4 = static_cast<float>(double_next2);
+ f4 = SanitizedDoubletof(double_next2);
}
(void) f2; // Mark variable as used.
- ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4);
+ DOUBLE_CONVERSION_ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4);
// If the guess doesn't lie near a single-precision boundary we can simply
// return its float-value.
@@ -539,11 +587,11 @@ float Strtof(Vector<const char> buffer, int exponent) {
return float_guess;
}
- ASSERT((f1 != f2 && f2 == f3 && f3 == f4) ||
+ DOUBLE_CONVERSION_ASSERT((f1 != f2 && f2 == f3 && f3 == f4) ||
(f1 == f2 && f2 != f3 && f3 == f4) ||
(f1 == f2 && f2 == f3 && f3 != f4));
- // guess and next are the two possible canditates (in the same way that
+ // guess and next are the two possible candidates (in the same way that
// double_guess was the lower candidate for a double-precision guess).
float guess = f1;
float next = f4;
diff --git a/deps/icu-small/source/i18n/double-conversion-strtod.h b/deps/icu-small/source/i18n/double-conversion-strtod.h
index e2d6d3c2fe..50ef746401 100644
--- a/deps/icu-small/source/i18n/double-conversion-strtod.h
+++ b/deps/icu-small/source/i18n/double-conversion-strtod.h
@@ -54,6 +54,11 @@ double Strtod(Vector<const char> buffer, int exponent);
// contain a dot or a sign. It must not start with '0', and must not be empty.
float Strtof(Vector<const char> buffer, int exponent);
+// For special use cases, the heart of the Strtod() function is also available
+// separately, it assumes that 'trimmed' is as produced by TrimAndCut(), i.e.
+// no leading or trailing zeros, also no lone zero, and not 'too many' digits.
+double StrtodTrimmed(Vector<const char> trimmed, int exponent);
+
} // namespace double_conversion
// ICU PATCH: Close ICU namespace
diff --git a/deps/icu-small/source/i18n/double-conversion-utils.h b/deps/icu-small/source/i18n/double-conversion-utils.h
index 1e44fcaa0e..099298460c 100644
--- a/deps/icu-small/source/i18n/double-conversion-utils.h
+++ b/deps/icu-small/source/i18n/double-conversion-utils.h
@@ -42,10 +42,12 @@
// ICU PATCH: Use U_ASSERT instead of <assert.h>
#include "uassert.h"
-#define ASSERT U_ASSERT
-
-#ifndef UNIMPLEMENTED
-#define UNIMPLEMENTED() (abort())
+#ifndef DOUBLE_CONVERSION_ASSERT
+#define DOUBLE_CONVERSION_ASSERT(condition) \
+ U_ASSERT(condition);
+#endif
+#ifndef DOUBLE_CONVERSION_UNIMPLEMENTED
+#define DOUBLE_CONVERSION_UNIMPLEMENTED() (abort())
#endif
#ifndef DOUBLE_CONVERSION_NO_RETURN
#ifdef _MSC_VER
@@ -54,16 +56,23 @@
#define DOUBLE_CONVERSION_NO_RETURN __attribute__((noreturn))
#endif
#endif
-#ifndef UNREACHABLE
+#ifndef DOUBLE_CONVERSION_UNREACHABLE
#ifdef _MSC_VER
void DOUBLE_CONVERSION_NO_RETURN abort_noreturn();
inline void abort_noreturn() { abort(); }
-#define UNREACHABLE() (abort_noreturn())
+#define DOUBLE_CONVERSION_UNREACHABLE() (abort_noreturn())
#else
-#define UNREACHABLE() (abort())
+#define DOUBLE_CONVERSION_UNREACHABLE() (abort())
#endif
#endif
+#ifndef DOUBLE_CONVERSION_UNUSED
+#ifdef __GNUC__
+#define DOUBLE_CONVERSION_UNUSED __attribute__((unused))
+#else
+#define DOUBLE_CONVERSION_UNUSED
+#endif
+#endif
// Double operations detection based on target architecture.
// Linux uses a 80bit wide floating point stack on x86. This induces double
@@ -99,9 +108,9 @@ int main(int argc, char** argv) {
defined(_POWER) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
defined(__SH4__) || defined(__alpha__) || \
- defined(_MIPS_ARCH_MIPS32R2) || \
+ defined(_MIPS_ARCH_MIPS32R2) || defined(__ARMEB__) ||\
defined(__AARCH64EL__) || defined(__aarch64__) || defined(__AARCH64EB__) || \
- defined(__riscv) || \
+ defined(__riscv) || defined(__e2k__) || \
defined(__or1k__) || defined(__arc__) || \
defined(__EMSCRIPTEN__)
#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
@@ -141,24 +150,24 @@ typedef uint16_t uc16;
// The following macro works on both 32 and 64-bit platforms.
// Usage: instead of writing 0x1234567890123456
-// write UINT64_2PART_C(0x12345678,90123456);
-#define UINT64_2PART_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
+// 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))
-// The expression ARRAY_SIZE(a) is a compile-time constant of type
+// 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
-// array. You should only use ARRAY_SIZE on statically allocated
+// array. You should only use DOUBLE_CONVERSION_ARRAY_SIZE on statically allocated
// arrays.
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(a) \
+#ifndef DOUBLE_CONVERSION_ARRAY_SIZE
+#define DOUBLE_CONVERSION_ARRAY_SIZE(a) \
((sizeof(a) / sizeof(*(a))) / \
static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
#endif
// A macro to disallow the evil copy constructor and operator= functions
// This should be used in the private: declarations for a class
-#ifndef DC_DISALLOW_COPY_AND_ASSIGN
-#define DC_DISALLOW_COPY_AND_ASSIGN(TypeName) \
+#ifndef DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN
+#define DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
#endif
@@ -169,10 +178,10 @@ typedef uint16_t uc16;
// This should be used in the private: declarations for a class
// that wants to prevent anyone from instantiating it. This is
// especially useful for classes containing only static methods.
-#ifndef DC_DISALLOW_IMPLICIT_CONSTRUCTORS
-#define DC_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
+#ifndef DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS
+#define DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
TypeName(); \
- DC_DISALLOW_COPY_AND_ASSIGN(TypeName)
+ DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(TypeName)
#endif
// ICU PATCH: Wrap in ICU namespace
@@ -180,25 +189,9 @@ U_NAMESPACE_BEGIN
namespace double_conversion {
-static const int kCharSize = sizeof(char);
-
-// Returns the maximum of the two parameters.
-template <typename T>
-static T Max(T a, T b) {
- return a < b ? b : a;
-}
-
-
-// Returns the minimum of the two parameters.
-template <typename T>
-static T Min(T a, T b) {
- return a < b ? a : b;
-}
-
-
inline int StrLength(const char* string) {
size_t length = strlen(string);
- ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
+ DOUBLE_CONVERSION_ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
return static_cast<int>(length);
}
@@ -208,15 +201,15 @@ class Vector {
public:
Vector() : start_(NULL), length_(0) {}
Vector(T* data, int len) : start_(data), length_(len) {
- ASSERT(len == 0 || (len > 0 && data != NULL));
+ DOUBLE_CONVERSION_ASSERT(len == 0 || (len > 0 && data != NULL));
}
// Returns a vector using the same backing storage as this one,
// spanning from and including 'from', to but not including 'to'.
Vector<T> SubVector(int from, int to) {
- ASSERT(to <= length_);
- ASSERT(from < to);
- ASSERT(0 <= from);
+ DOUBLE_CONVERSION_ASSERT(to <= length_);
+ DOUBLE_CONVERSION_ASSERT(from < to);
+ DOUBLE_CONVERSION_ASSERT(0 <= from);
return Vector<T>(start() + from, to - from);
}
@@ -231,7 +224,7 @@ class Vector {
// Access individual vector elements - checks bounds in debug mode.
T& operator[](int index) const {
- ASSERT(0 <= index && index < length_);
+ DOUBLE_CONVERSION_ASSERT(0 <= index && index < length_);
return start_[index];
}
@@ -239,6 +232,11 @@ class Vector {
T& last() { return start_[length_ - 1]; }
+ void pop_back() {
+ DOUBLE_CONVERSION_ASSERT(!is_empty());
+ --length_;
+ }
+
private:
T* start_;
int length_;
@@ -259,7 +257,7 @@ class StringBuilder {
// Get the current position in the builder.
int position() const {
- ASSERT(!is_finalized());
+ DOUBLE_CONVERSION_ASSERT(!is_finalized());
return position_;
}
@@ -270,8 +268,8 @@ class StringBuilder {
// 0-characters; use the Finalize() method to terminate the string
// instead.
void AddCharacter(char c) {
- ASSERT(c != '\0');
- ASSERT(!is_finalized() && position_ < buffer_.length());
+ DOUBLE_CONVERSION_ASSERT(c != '\0');
+ DOUBLE_CONVERSION_ASSERT(!is_finalized() && position_ < buffer_.length());
buffer_[position_++] = c;
}
@@ -284,9 +282,9 @@ class StringBuilder {
// Add the first 'n' characters of the given string 's' to the
// builder. The input string must have enough characters.
void AddSubstring(const char* s, int n) {
- ASSERT(!is_finalized() && position_ + n < buffer_.length());
- ASSERT(static_cast<size_t>(n) <= strlen(s));
- memmove(&buffer_[position_], s, n * kCharSize);
+ DOUBLE_CONVERSION_ASSERT(!is_finalized() && position_ + n < buffer_.length());
+ DOUBLE_CONVERSION_ASSERT(static_cast<size_t>(n) <= strlen(s));
+ memmove(&buffer_[position_], s, n);
position_ += n;
}
@@ -301,13 +299,13 @@ class StringBuilder {
// Finalize the string by 0-terminating it and returning the buffer.
char* Finalize() {
- ASSERT(!is_finalized() && position_ < buffer_.length());
+ DOUBLE_CONVERSION_ASSERT(!is_finalized() && position_ < buffer_.length());
buffer_[position_] = '\0';
// Make sure nobody managed to add a 0-character to the
// buffer while building the string.
- ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_));
+ DOUBLE_CONVERSION_ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_));
position_ = -1;
- ASSERT(is_finalized());
+ DOUBLE_CONVERSION_ASSERT(is_finalized());
return buffer_.start();
}
@@ -317,7 +315,7 @@ class StringBuilder {
bool is_finalized() const { return position_ < 0; }
- DC_DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
+ DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
};
// The type-based aliasing rule allows the compiler to assume that pointers of
@@ -345,13 +343,14 @@ class StringBuilder {
// enough that it can no longer see that you have cast one pointer type to
// another thus avoiding the warning.
template <class Dest, class Source>
-inline Dest BitCast(const Source& source) {
+Dest BitCast(const Source& source) {
// Compile time assertion: sizeof(Dest) == sizeof(Source)
// A compile error here means your Dest and Source have different sizes.
#if __cplusplus >= 201103L
static_assert(sizeof(Dest) == sizeof(Source),
"source and destination size mismatch");
#else
+ DOUBLE_CONVERSION_UNUSED
typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
#endif
@@ -361,7 +360,7 @@ inline Dest BitCast(const Source& source) {
}
template <class Dest, class Source>
-inline Dest BitCast(Source* source) {
+Dest BitCast(Source* source) {
return BitCast<Dest>(reinterpret_cast<uintptr_t>(source));
}
diff --git a/deps/icu-small/source/i18n/double-conversion.h b/deps/icu-small/source/i18n/double-conversion.h
index 377c710bf7..eddc38763b 100644
--- a/deps/icu-small/source/i18n/double-conversion.h
+++ b/deps/icu-small/source/i18n/double-conversion.h
@@ -39,561 +39,8 @@
// ICU PATCH: Customize header file paths for ICU.
-#include "double-conversion-utils.h"
-
-// ICU PATCH: Wrap in ICU namespace
-U_NAMESPACE_BEGIN
-
-namespace double_conversion {
-
-class DoubleToStringConverter {
- public:
-#if 0 // not needed for ICU
- // When calling ToFixed with a double > 10^kMaxFixedDigitsBeforePoint
- // or a requested_digits parameter > kMaxFixedDigitsAfterPoint then the
- // function returns false.
- static const int kMaxFixedDigitsBeforePoint = 60;
- static const int kMaxFixedDigitsAfterPoint = 60;
-
- // When calling ToExponential with a requested_digits
- // parameter > kMaxExponentialDigits then the function returns false.
- static const int kMaxExponentialDigits = 120;
-
- // When calling ToPrecision with a requested_digits
- // parameter < kMinPrecisionDigits or requested_digits > kMaxPrecisionDigits
- // then the function returns false.
- static const int kMinPrecisionDigits = 1;
- static const int kMaxPrecisionDigits = 120;
-
- enum Flags {
- NO_FLAGS = 0,
- EMIT_POSITIVE_EXPONENT_SIGN = 1,
- EMIT_TRAILING_DECIMAL_POINT = 2,
- EMIT_TRAILING_ZERO_AFTER_POINT = 4,
- UNIQUE_ZERO = 8
- };
-
- // Flags should be a bit-or combination of the possible Flags-enum.
- // - NO_FLAGS: no special flags.
- // - EMIT_POSITIVE_EXPONENT_SIGN: when the number is converted into exponent
- // form, emits a '+' for positive exponents. Example: 1.2e+2.
- // - EMIT_TRAILING_DECIMAL_POINT: when the input number is an integer and is
- // converted into decimal format then a trailing decimal point is appended.
- // Example: 2345.0 is converted to "2345.".
- // - EMIT_TRAILING_ZERO_AFTER_POINT: in addition to a trailing decimal point
- // emits a trailing '0'-character. This flag requires the
- // EXMIT_TRAILING_DECIMAL_POINT flag.
- // Example: 2345.0 is converted to "2345.0".
- // - UNIQUE_ZERO: "-0.0" is converted to "0.0".
- //
- // Infinity symbol and nan_symbol provide the string representation for these
- // special values. If the string is NULL and the special value is encountered
- // then the conversion functions return false.
- //
- // The exponent_character is used in exponential representations. It is
- // usually 'e' or 'E'.
- //
- // When converting to the shortest representation the converter will
- // represent input numbers in decimal format if they are in the interval
- // [10^decimal_in_shortest_low; 10^decimal_in_shortest_high[
- // (lower boundary included, greater boundary excluded).
- // Example: with decimal_in_shortest_low = -6 and
- // decimal_in_shortest_high = 21:
- // ToShortest(0.000001) -> "0.000001"
- // ToShortest(0.0000001) -> "1e-7"
- // ToShortest(111111111111111111111.0) -> "111111111111111110000"
- // ToShortest(100000000000000000000.0) -> "100000000000000000000"
- // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21"
- //
- // When converting to precision mode the converter may add
- // max_leading_padding_zeroes before returning the number in exponential
- // format.
- // Example with max_leading_padding_zeroes_in_precision_mode = 6.
- // ToPrecision(0.0000012345, 2) -> "0.0000012"
- // ToPrecision(0.00000012345, 2) -> "1.2e-7"
- // Similarily the converter may add up to
- // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid
- // returning an exponential representation. A zero added by the
- // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit.
- // Examples for max_trailing_padding_zeroes_in_precision_mode = 1:
- // ToPrecision(230.0, 2) -> "230"
- // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT.
- // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT.
- DoubleToStringConverter(int flags,
- const char* infinity_symbol,
- const char* nan_symbol,
- char exponent_character,
- int decimal_in_shortest_low,
- int decimal_in_shortest_high,
- int max_leading_padding_zeroes_in_precision_mode,
- int max_trailing_padding_zeroes_in_precision_mode)
- : flags_(flags),
- infinity_symbol_(infinity_symbol),
- nan_symbol_(nan_symbol),
- exponent_character_(exponent_character),
- decimal_in_shortest_low_(decimal_in_shortest_low),
- decimal_in_shortest_high_(decimal_in_shortest_high),
- max_leading_padding_zeroes_in_precision_mode_(
- max_leading_padding_zeroes_in_precision_mode),
- max_trailing_padding_zeroes_in_precision_mode_(
- max_trailing_padding_zeroes_in_precision_mode) {
- // When 'trailing zero after the point' is set, then 'trailing point'
- // must be set too.
- ASSERT(((flags & EMIT_TRAILING_DECIMAL_POINT) != 0) ||
- !((flags & EMIT_TRAILING_ZERO_AFTER_POINT) != 0));
- }
-
- // Returns a converter following the EcmaScript specification.
- static const DoubleToStringConverter& EcmaScriptConverter();
-
- // Computes the shortest string of digits that correctly represent the input
- // number. Depending on decimal_in_shortest_low and decimal_in_shortest_high
- // (see constructor) it then either returns a decimal representation, or an
- // exponential representation.
- // Example with decimal_in_shortest_low = -6,
- // decimal_in_shortest_high = 21,
- // EMIT_POSITIVE_EXPONENT_SIGN activated, and
- // EMIT_TRAILING_DECIMAL_POINT deactived:
- // ToShortest(0.000001) -> "0.000001"
- // ToShortest(0.0000001) -> "1e-7"
- // ToShortest(111111111111111111111.0) -> "111111111111111110000"
- // ToShortest(100000000000000000000.0) -> "100000000000000000000"
- // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21"
- //
- // Note: the conversion may round the output if the returned string
- // is accurate enough to uniquely identify the input-number.
- // For example the most precise representation of the double 9e59 equals
- // "899999999999999918767229449717619953810131273674690656206848", but
- // the converter will return the shorter (but still correct) "9e59".
- //
- // Returns true if the conversion succeeds. The conversion always succeeds
- // except when the input value is special and no infinity_symbol or
- // nan_symbol has been given to the constructor.
- bool ToShortest(double value, StringBuilder* result_builder) const {
- return ToShortestIeeeNumber(value, result_builder, SHORTEST);
- }
-
- // Same as ToShortest, but for single-precision floats.
- bool ToShortestSingle(float value, StringBuilder* result_builder) const {
- return ToShortestIeeeNumber(value, result_builder, SHORTEST_SINGLE);
- }
-
-
- // Computes a decimal representation with a fixed number of digits after the
- // decimal point. The last emitted digit is rounded.
- //
- // Examples:
- // ToFixed(3.12, 1) -> "3.1"
- // ToFixed(3.1415, 3) -> "3.142"
- // ToFixed(1234.56789, 4) -> "1234.5679"
- // ToFixed(1.23, 5) -> "1.23000"
- // ToFixed(0.1, 4) -> "0.1000"
- // ToFixed(1e30, 2) -> "1000000000000000019884624838656.00"
- // ToFixed(0.1, 30) -> "0.100000000000000005551115123126"
- // ToFixed(0.1, 17) -> "0.10000000000000001"
- //
- // If requested_digits equals 0, then the tail of the result depends on
- // the EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT.
- // Examples, for requested_digits == 0,
- // let EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT be
- // - false and false: then 123.45 -> 123
- // 0.678 -> 1
- // - true and false: then 123.45 -> 123.
- // 0.678 -> 1.
- // - true and true: then 123.45 -> 123.0
- // 0.678 -> 1.0
- //
- // Returns true if the conversion succeeds. The conversion always succeeds
- // except for the following cases:
- // - the input value is special and no infinity_symbol or nan_symbol has
- // been provided to the constructor,
- // - 'value' > 10^kMaxFixedDigitsBeforePoint, or
- // - 'requested_digits' > kMaxFixedDigitsAfterPoint.
- // The last two conditions imply that the result will never contain more than
- // 1 + kMaxFixedDigitsBeforePoint + 1 + kMaxFixedDigitsAfterPoint characters
- // (one additional character for the sign, and one for the decimal point).
- bool ToFixed(double value,
- int requested_digits,
- StringBuilder* result_builder) const;
-
- // Computes a representation in exponential format with requested_digits
- // after the decimal point. The last emitted digit is rounded.
- // If requested_digits equals -1, then the shortest exponential representation
- // is computed.
- //
- // Examples with EMIT_POSITIVE_EXPONENT_SIGN deactivated, and
- // exponent_character set to 'e'.
- // ToExponential(3.12, 1) -> "3.1e0"
- // ToExponential(5.0, 3) -> "5.000e0"
- // ToExponential(0.001, 2) -> "1.00e-3"
- // ToExponential(3.1415, -1) -> "3.1415e0"
- // ToExponential(3.1415, 4) -> "3.1415e0"
- // ToExponential(3.1415, 3) -> "3.142e0"
- // ToExponential(123456789000000, 3) -> "1.235e14"
- // ToExponential(1000000000000000019884624838656.0, -1) -> "1e30"
- // ToExponential(1000000000000000019884624838656.0, 32) ->
- // "1.00000000000000001988462483865600e30"
- // ToExponential(1234, 0) -> "1e3"
- //
- // Returns true if the conversion succeeds. The conversion always succeeds
- // except for the following cases:
- // - the input value is special and no infinity_symbol or nan_symbol has
- // been provided to the constructor,
- // - 'requested_digits' > kMaxExponentialDigits.
- // The last condition implies that the result will never contain more than
- // kMaxExponentialDigits + 8 characters (the sign, the digit before the
- // decimal point, the decimal point, the exponent character, the
- // exponent's sign, and at most 3 exponent digits).
- bool ToExponential(double value,
- int requested_digits,
- StringBuilder* result_builder) const;
-
- // Computes 'precision' leading digits of the given 'value' and returns them
- // either in exponential or decimal format, depending on
- // max_{leading|trailing}_padding_zeroes_in_precision_mode (given to the
- // constructor).
- // The last computed digit is rounded.
- //
- // Example with max_leading_padding_zeroes_in_precision_mode = 6.
- // ToPrecision(0.0000012345, 2) -> "0.0000012"
- // ToPrecision(0.00000012345, 2) -> "1.2e-7"
- // Similarily the converter may add up to
- // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid
- // returning an exponential representation. A zero added by the
- // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit.
- // Examples for max_trailing_padding_zeroes_in_precision_mode = 1:
- // ToPrecision(230.0, 2) -> "230"
- // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT.
- // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT.
- // Examples for max_trailing_padding_zeroes_in_precision_mode = 3, and no
- // EMIT_TRAILING_ZERO_AFTER_POINT:
- // ToPrecision(123450.0, 6) -> "123450"
- // ToPrecision(123450.0, 5) -> "123450"
- // ToPrecision(123450.0, 4) -> "123500"
- // ToPrecision(123450.0, 3) -> "123000"
- // ToPrecision(123450.0, 2) -> "1.2e5"
- //
- // Returns true if the conversion succeeds. The conversion always succeeds
- // except for the following cases:
- // - the input value is special and no infinity_symbol or nan_symbol has
- // been provided to the constructor,
- // - precision < kMinPericisionDigits
- // - precision > kMaxPrecisionDigits
- // The last condition implies that the result will never contain more than
- // kMaxPrecisionDigits + 7 characters (the sign, the decimal point, the
- // exponent character, the exponent's sign, and at most 3 exponent digits).
- bool ToPrecision(double value,
- int precision,
- StringBuilder* result_builder) const;
-#endif // not needed for ICU
-
- enum DtoaMode {
- // Produce the shortest correct representation.
- // For example the output of 0.299999999999999988897 is (the less accurate
- // but correct) 0.3.
- SHORTEST,
- // Same as SHORTEST, but for single-precision floats.
- SHORTEST_SINGLE,
- // Produce a fixed number of digits after the decimal point.
- // For instance fixed(0.1, 4) becomes 0.1000
- // If the input number is big, the output will be big.
- FIXED,
- // Fixed number of digits (independent of the decimal point).
- PRECISION
- };
-
- // The maximal number of digits that are needed to emit a double in base 10.
- // A higher precision can be achieved by using more digits, but the shortest
- // accurate representation of any double will never use more digits than
- // kBase10MaximalLength.
- // Note that DoubleToAscii null-terminates its input. So the given buffer
- // should be at least kBase10MaximalLength + 1 characters long.
- static const int kBase10MaximalLength = 17;
-
- // Converts the given double 'v' to digit characters. 'v' must not be NaN,
- // +Infinity, or -Infinity. In SHORTEST_SINGLE-mode this restriction also
- // applies to 'v' after it has been casted to a single-precision float. That
- // is, in this mode static_cast<float>(v) must not be NaN, +Infinity or
- // -Infinity.
- //
- // The result should be interpreted as buffer * 10^(point-length).
- //
- // The digits are written to the buffer in the platform's charset, which is
- // often UTF-8 (with ASCII-range digits) but may be another charset, such
- // as EBCDIC.
- //
- // The output depends on the given mode:
- // - SHORTEST: produce the least amount of digits for which the internal
- // identity requirement is still satisfied. If the digits are printed
- // (together with the correct exponent) then reading this number will give
- // 'v' again. The buffer will choose the representation that is closest to
- // 'v'. If there are two at the same distance, than the one farther away
- // from 0 is chosen (halfway cases - ending with 5 - are rounded up).
- // In this mode the 'requested_digits' parameter is ignored.
- // - SHORTEST_SINGLE: same as SHORTEST but with single-precision.
- // - FIXED: produces digits necessary to print a given number with
- // 'requested_digits' digits after the decimal point. The produced digits
- // might be too short in which case the caller has to fill the remainder
- // with '0's.
- // Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2.
- // Halfway cases are rounded towards +/-Infinity (away from 0). The call
- // toFixed(0.15, 2) thus returns buffer="2", point=0.
- // The returned buffer may contain digits that would be truncated from the
- // shortest representation of the input.
- // - PRECISION: produces 'requested_digits' where the first digit is not '0'.
- // Even though the length of produced digits usually equals
- // 'requested_digits', the function is allowed to return fewer digits, in
- // which case the caller has to fill the missing digits with '0's.
- // Halfway cases are again rounded away from 0.
- // DoubleToAscii expects the given buffer to be big enough to hold all
- // digits and a terminating null-character. In SHORTEST-mode it expects a
- // buffer of at least kBase10MaximalLength + 1. In all other modes the
- // requested_digits parameter and the padding-zeroes limit the size of the
- // output. Don't forget the decimal point, the exponent character and the
- // terminating null-character when computing the maximal output size.
- // The given length is only used in debug mode to ensure the buffer is big
- // enough.
- // ICU PATCH: Export this as U_I18N_API for unit tests.
- static void U_I18N_API DoubleToAscii(double v,
- DtoaMode mode,
- int requested_digits,
- char* buffer,
- int buffer_length,
- bool* sign,
- int* length,
- int* point);
-
-#if 0 // not needed for ICU
- private:
- // Implementation for ToShortest and ToShortestSingle.
- bool ToShortestIeeeNumber(double value,
- StringBuilder* result_builder,
- DtoaMode mode) const;
-
- // If the value is a special value (NaN or Infinity) constructs the
- // corresponding string using the configured infinity/nan-symbol.
- // If either of them is NULL or the value is not special then the
- // function returns false.
- bool HandleSpecialValues(double value, StringBuilder* result_builder) const;
- // Constructs an exponential representation (i.e. 1.234e56).
- // The given exponent assumes a decimal point after the first decimal digit.
- void CreateExponentialRepresentation(const char* decimal_digits,
- int length,
- int exponent,
- StringBuilder* result_builder) const;
- // Creates a decimal representation (i.e 1234.5678).
- void CreateDecimalRepresentation(const char* decimal_digits,
- int length,
- int decimal_point,
- int digits_after_point,
- StringBuilder* result_builder) const;
-
- const int flags_;
- const char* const infinity_symbol_;
- const char* const nan_symbol_;
- const char exponent_character_;
- const int decimal_in_shortest_low_;
- const int decimal_in_shortest_high_;
- const int max_leading_padding_zeroes_in_precision_mode_;
- const int max_trailing_padding_zeroes_in_precision_mode_;
-#endif // not needed for ICU
-
- DC_DISALLOW_IMPLICIT_CONSTRUCTORS(DoubleToStringConverter);
-};
-
-
-class StringToDoubleConverter {
- public:
- // Enumeration for allowing octals and ignoring junk when converting
- // strings to numbers.
- enum Flags {
- NO_FLAGS = 0,
- ALLOW_HEX = 1,
- ALLOW_OCTALS = 2,
- ALLOW_TRAILING_JUNK = 4,
- ALLOW_LEADING_SPACES = 8,
- ALLOW_TRAILING_SPACES = 16,
- ALLOW_SPACES_AFTER_SIGN = 32,
- ALLOW_CASE_INSENSIBILITY = 64,
- ALLOW_HEX_FLOATS = 128,
- };
-
- static const uc16 kNoSeparator = '\0';
-
- // Flags should be a bit-or combination of the possible Flags-enum.
- // - NO_FLAGS: no special flags.
- // - ALLOW_HEX: recognizes the prefix "0x". Hex numbers may only be integers.
- // Ex: StringToDouble("0x1234") -> 4660.0
- // In StringToDouble("0x1234.56") the characters ".56" are trailing
- // junk. The result of the call is hence dependent on
- // the ALLOW_TRAILING_JUNK flag and/or the junk value.
- // With this flag "0x" is a junk-string. Even with ALLOW_TRAILING_JUNK,
- // the string will not be parsed as "0" followed by junk.
- //
- // - ALLOW_OCTALS: recognizes the prefix "0" for octals:
- // If a sequence of octal digits starts with '0', then the number is
- // read as octal integer. Octal numbers may only be integers.
- // Ex: StringToDouble("01234") -> 668.0
- // StringToDouble("012349") -> 12349.0 // Not a sequence of octal
- // // digits.
- // In StringToDouble("01234.56") the characters ".56" are trailing
- // junk. The result of the call is hence dependent on
- // the ALLOW_TRAILING_JUNK flag and/or the junk value.
- // In StringToDouble("01234e56") the characters "e56" are trailing
- // junk, too.
- // - ALLOW_TRAILING_JUNK: ignore trailing characters that are not part of
- // a double literal.
- // - ALLOW_LEADING_SPACES: skip over leading whitespace, including spaces,
- // new-lines, and tabs.
- // - ALLOW_TRAILING_SPACES: ignore trailing whitespace.
- // - ALLOW_SPACES_AFTER_SIGN: ignore whitespace after the sign.
- // Ex: StringToDouble("- 123.2") -> -123.2.
- // StringToDouble("+ 123.2") -> 123.2
- // - ALLOW_CASE_INSENSIBILITY: ignore case of characters for special values:
- // infinity and nan.
- // - ALLOW_HEX_FLOATS: allows hexadecimal float literals.
- // This *must* start with "0x" and separate the exponent with "p".
- // Examples: 0x1.2p3 == 9.0
- // 0x10.1p0 == 16.0625
- // ALLOW_HEX and ALLOW_HEX_FLOATS are indendent.
- //
- // empty_string_value is returned when an empty string is given as input.
- // If ALLOW_LEADING_SPACES or ALLOW_TRAILING_SPACES are set, then a string
- // containing only spaces is converted to the 'empty_string_value', too.
- //
- // junk_string_value is returned when
- // a) ALLOW_TRAILING_JUNK is not set, and a junk character (a character not
- // part of a double-literal) is found.
- // b) ALLOW_TRAILING_JUNK is set, but the string does not start with a
- // double literal.
- //
- // infinity_symbol and nan_symbol are strings that are used to detect
- // inputs that represent infinity and NaN. They can be null, in which case
- // they are ignored.
- // The conversion routine first reads any possible signs. Then it compares the
- // following character of the input-string with the first character of
- // the infinity, and nan-symbol. If either matches, the function assumes, that
- // a match has been found, and expects the following input characters to match
- // the remaining characters of the special-value symbol.
- // This means that the following restrictions apply to special-value symbols:
- // - they must not start with signs ('+', or '-'),
- // - they must not have the same first character.
- // - they must not start with digits.
- //
- // If the separator character is not kNoSeparator, then that specific
- // character is ignored when in between two valid digits of the significant.
- // It is not allowed to appear in the exponent.
- // It is not allowed to lead or trail the number.
- // It is not allowed to appear twice next to each other.
- //
- // Examples:
- // flags = ALLOW_HEX | ALLOW_TRAILING_JUNK,
- // empty_string_value = 0.0,
- // junk_string_value = NaN,
- // infinity_symbol = "infinity",
- // nan_symbol = "nan":
- // StringToDouble("0x1234") -> 4660.0.
- // StringToDouble("0x1234K") -> 4660.0.
- // StringToDouble("") -> 0.0 // empty_string_value.
- // StringToDouble(" ") -> NaN // junk_string_value.
- // StringToDouble(" 1") -> NaN // junk_string_value.
- // StringToDouble("0x") -> NaN // junk_string_value.
- // StringToDouble("-123.45") -> -123.45.
- // StringToDouble("--123.45") -> NaN // junk_string_value.
- // StringToDouble("123e45") -> 123e45.
- // StringToDouble("123E45") -> 123e45.
- // StringToDouble("123e+45") -> 123e45.
- // StringToDouble("123E-45") -> 123e-45.
- // StringToDouble("123e") -> 123.0 // trailing junk ignored.
- // StringToDouble("123e-") -> 123.0 // trailing junk ignored.
- // StringToDouble("+NaN") -> NaN // NaN string literal.
- // StringToDouble("-infinity") -> -inf. // infinity literal.
- // StringToDouble("Infinity") -> NaN // junk_string_value.
- //
- // flags = ALLOW_OCTAL | ALLOW_LEADING_SPACES,
- // empty_string_value = 0.0,
- // junk_string_value = NaN,
- // infinity_symbol = NULL,
- // nan_symbol = NULL:
- // StringToDouble("0x1234") -> NaN // junk_string_value.
- // StringToDouble("01234") -> 668.0.
- // StringToDouble("") -> 0.0 // empty_string_value.
- // StringToDouble(" ") -> 0.0 // empty_string_value.
- // StringToDouble(" 1") -> 1.0
- // StringToDouble("0x") -> NaN // junk_string_value.
- // StringToDouble("0123e45") -> NaN // junk_string_value.
- // StringToDouble("01239E45") -> 1239e45.
- // StringToDouble("-infinity") -> NaN // junk_string_value.
- // StringToDouble("NaN") -> NaN // junk_string_value.
- //
- // flags = NO_FLAGS,
- // separator = ' ':
- // StringToDouble("1 2 3 4") -> 1234.0
- // StringToDouble("1 2") -> NaN // junk_string_value
- // StringToDouble("1 000 000.0") -> 1000000.0
- // StringToDouble("1.000 000") -> 1.0
- // StringToDouble("1.0e1 000") -> NaN // junk_string_value
- StringToDoubleConverter(int flags,
- double empty_string_value,
- double junk_string_value,
- const char* infinity_symbol,
- const char* nan_symbol,
- uc16 separator = kNoSeparator)
- : flags_(flags),
- empty_string_value_(empty_string_value),
- junk_string_value_(junk_string_value),
- infinity_symbol_(infinity_symbol),
- nan_symbol_(nan_symbol),
- separator_(separator) {
- }
-
- // Performs the conversion.
- // The output parameter 'processed_characters_count' is set to the number
- // of characters that have been processed to read the number.
- // Spaces than are processed with ALLOW_{LEADING|TRAILING}_SPACES are included
- // in the 'processed_characters_count'. Trailing junk is never included.
- double StringToDouble(const char* buffer,
- int length,
- int* processed_characters_count) const;
-
- // Same as StringToDouble above but for 16 bit characters.
- double StringToDouble(const uc16* buffer,
- int length,
- int* processed_characters_count) const;
-
- // Same as StringToDouble but reads a float.
- // Note that this is not equivalent to static_cast<float>(StringToDouble(...))
- // due to potential double-rounding.
- float StringToFloat(const char* buffer,
- int length,
- int* processed_characters_count) const;
-
- // Same as StringToFloat above but for 16 bit characters.
- float StringToFloat(const uc16* buffer,
- int length,
- int* processed_characters_count) const;
-
- private:
- const int flags_;
- const double empty_string_value_;
- const double junk_string_value_;
- const char* const infinity_symbol_;
- const char* const nan_symbol_;
- const uc16 separator_;
-
- template <class Iterator>
- double StringToIeee(Iterator start_pointer,
- int length,
- bool read_as_double,
- int* processed_characters_count) const;
-
- DC_DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter);
-};
-
-} // namespace double_conversion
-
-// ICU PATCH: Close ICU namespace
-U_NAMESPACE_END
+#include "double-conversion-string-to-double.h"
+#include "double-conversion-double-to-string.h"
#endif // DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
#endif // ICU PATCH: close #if !UCONFIG_NO_FORMATTING
diff --git a/deps/icu-small/source/i18n/dtfmtsym.cpp b/deps/icu-small/source/i18n/dtfmtsym.cpp
index 04aa01eb4c..9dde66c1fb 100644
--- a/deps/icu-small/source/i18n/dtfmtsym.cpp
+++ b/deps/icu-small/source/i18n/dtfmtsym.cpp
@@ -1246,7 +1246,7 @@ const UnicodeString**
DateFormatSymbols::getZoneStrings(int32_t& rowCount, int32_t& columnCount) const
{
const UnicodeString **result = NULL;
- static UMutex LOCK = U_MUTEX_INITIALIZER;
+ static UMutex LOCK;
umtx_lock(&LOCK);
if (fZoneStrings == NULL) {
@@ -2177,16 +2177,16 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
// The ordering of the following statements is important.
if (fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev].isEmpty()) {
fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatWide]);
- };
+ }
if (fLeapMonthPatterns[kLeapMonthPatternFormatNarrow].isEmpty()) {
fLeapMonthPatterns[kLeapMonthPatternFormatNarrow].setTo(fLeapMonthPatterns[kLeapMonthPatternStandaloneNarrow]);
- };
+ }
if (fLeapMonthPatterns[kLeapMonthPatternStandaloneWide].isEmpty()) {
fLeapMonthPatterns[kLeapMonthPatternStandaloneWide].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatWide]);
- };
+ }
if (fLeapMonthPatterns[kLeapMonthPatternStandaloneAbbrev].isEmpty()) {
fLeapMonthPatterns[kLeapMonthPatternStandaloneAbbrev].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev]);
- };
+ }
// end of hack
fLeapMonthPatternsCount = kMonthPatternsCount;
} else {
@@ -2338,11 +2338,21 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
assignArray(fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, fShortMonths, fShortMonthsCount);
}
- // Load AM/PM markers
+ // Load AM/PM markers; if wide or narrow not available, use short
+ UErrorCode ampmStatus = U_ZERO_ERROR;
initField(&fAmPms, fAmPmsCount, calendarSink,
- buildResourcePath(path, gAmPmMarkersTag, status), status);
+ buildResourcePath(path, gAmPmMarkersTag, ampmStatus), ampmStatus);
+ if (U_FAILURE(ampmStatus)) {
+ initField(&fAmPms, fAmPmsCount, calendarSink,
+ buildResourcePath(path, gAmPmMarkersAbbrTag, status), status);
+ }
+ ampmStatus = U_ZERO_ERROR;
initField(&fNarrowAmPms, fNarrowAmPmsCount, calendarSink,
- buildResourcePath(path, gAmPmMarkersNarrowTag, status), status);
+ buildResourcePath(path, gAmPmMarkersNarrowTag, ampmStatus), ampmStatus);
+ if (U_FAILURE(ampmStatus)) {
+ initField(&fNarrowAmPms, fNarrowAmPmsCount, calendarSink,
+ buildResourcePath(path, gAmPmMarkersAbbrTag, status), status);
+ }
// Load quarters
initField(&fQuarters, fQuartersCount, calendarSink,
diff --git a/deps/icu-small/source/i18n/dtitv_impl.h b/deps/icu-small/source/i18n/dtitv_impl.h
index 18fe0b8c9b..7c4d8a7214 100644
--- a/deps/icu-small/source/i18n/dtitv_impl.h
+++ b/deps/icu-small/source/i18n/dtitv_impl.h
@@ -88,7 +88,7 @@
#define MAX_E_COUNT 5
#define MAX_M_COUNT 5
//#define MAX_INTERVAL_INDEX 4
-#define MAX_POSITIVE_INT 56632;
+#define MAX_POSITIVE_INT 56632
#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/deps/icu-small/source/i18n/dtitvfmt.cpp b/deps/icu-small/source/i18n/dtitvfmt.cpp
index 0e124f5624..f47e7708cc 100644
--- a/deps/icu-small/source/i18n/dtitvfmt.cpp
+++ b/deps/icu-small/source/i18n/dtitvfmt.cpp
@@ -82,10 +82,7 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DateIntervalFormat)
// Mutex, protects access to fDateFormat, fFromCalendar and fToCalendar.
// Needed because these data members are modified by const methods of DateIntervalFormat.
-static UMutex *gFormatterMutex() {
- static UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static UMutex gFormatterMutex;
DateIntervalFormat* U_EXPORT2
DateIntervalFormat::createInstance(const UnicodeString& skeleton,
@@ -171,9 +168,9 @@ DateIntervalFormat::operator=(const DateIntervalFormat& itvfmt) {
delete fTimePattern;
delete fDateTimeFormat;
{
- Mutex lock(gFormatterMutex());
+ Mutex lock(&gFormatterMutex);
if ( itvfmt.fDateFormat ) {
- fDateFormat = (SimpleDateFormat*)itvfmt.fDateFormat->clone();
+ fDateFormat = itvfmt.fDateFormat->clone();
} else {
fDateFormat = NULL;
}
@@ -199,9 +196,9 @@ DateIntervalFormat::operator=(const DateIntervalFormat& itvfmt) {
fIntervalPatterns[i] = itvfmt.fIntervalPatterns[i];
}
fLocale = itvfmt.fLocale;
- fDatePattern = (itvfmt.fDatePattern)? (UnicodeString*)itvfmt.fDatePattern->clone(): NULL;
- fTimePattern = (itvfmt.fTimePattern)? (UnicodeString*)itvfmt.fTimePattern->clone(): NULL;
- fDateTimeFormat = (itvfmt.fDateTimeFormat)? (UnicodeString*)itvfmt.fDateTimeFormat->clone(): NULL;
+ fDatePattern = (itvfmt.fDatePattern)? itvfmt.fDatePattern->clone(): NULL;
+ fTimePattern = (itvfmt.fTimePattern)? itvfmt.fTimePattern->clone(): NULL;
+ fDateTimeFormat = (itvfmt.fDateTimeFormat)? itvfmt.fDateTimeFormat->clone(): NULL;
}
return *this;
}
@@ -218,8 +215,8 @@ DateIntervalFormat::~DateIntervalFormat() {
}
-Format*
-DateIntervalFormat::clone(void) const {
+DateIntervalFormat*
+DateIntervalFormat::clone() const {
return new DateIntervalFormat(*this);
}
@@ -233,7 +230,7 @@ DateIntervalFormat::operator==(const Format& other) const {
if ((fInfo != fmt->fInfo) && (fInfo == NULL || fmt->fInfo == NULL)) {return FALSE;}
if (fInfo && fmt->fInfo && (*fInfo != *fmt->fInfo )) {return FALSE;}
{
- Mutex lock(gFormatterMutex());
+ Mutex lock(&gFormatterMutex);
if (fDateFormat != fmt->fDateFormat && (fDateFormat == NULL || fmt->fDateFormat == NULL)) {return FALSE;}
if (fDateFormat && fmt->fDateFormat && (*fDateFormat != *fmt->fDateFormat)) {return FALSE;}
}
@@ -295,7 +292,7 @@ DateIntervalFormat::format(const DateInterval* dtInterval,
handler.setAcceptFirstOnly(TRUE);
int8_t ignore;
- Mutex lock(gFormatterMutex());
+ Mutex lock(&gFormatterMutex);
return formatIntervalImpl(*dtInterval, appendTo, ignore, handler, status);
}
@@ -312,7 +309,7 @@ FormattedDateInterval DateIntervalFormat::formatToValue(
auto handler = result->getHandler(status);
handler.setCategory(UFIELD_CATEGORY_DATE);
{
- Mutex lock(gFormatterMutex());
+ Mutex lock(&gFormatterMutex);
formatIntervalImpl(dtInterval, string, firstIndex, handler, status);
}
handler.getError(status);
@@ -344,7 +341,7 @@ DateIntervalFormat::format(Calendar& fromCalendar,
handler.setAcceptFirstOnly(TRUE);
int8_t ignore;
- Mutex lock(gFormatterMutex());
+ Mutex lock(&gFormatterMutex);
return formatImpl(fromCalendar, toCalendar, appendTo, ignore, handler, status);
}
@@ -362,7 +359,7 @@ FormattedDateInterval DateIntervalFormat::formatToValue(
auto handler = result->getHandler(status);
handler.setCategory(UFIELD_CATEGORY_DATE);
{
- Mutex lock(gFormatterMutex());
+ Mutex lock(&gFormatterMutex);
formatImpl(fromCalendar, toCalendar, string, firstIndex, handler, status);
}
handler.getError(status);
@@ -600,7 +597,7 @@ const TimeZone&
DateIntervalFormat::getTimeZone() const
{
if (fDateFormat != NULL) {
- Mutex lock(gFormatterMutex());
+ Mutex lock(&gFormatterMutex);
return fDateFormat->getTimeZone();
}
// If fDateFormat is NULL (unexpected), create default timezone.
diff --git a/deps/icu-small/source/i18n/dtitvinf.cpp b/deps/icu-small/source/i18n/dtitvinf.cpp
index c0a6980e55..35ee8c1626 100644
--- a/deps/icu-small/source/i18n/dtitvinf.cpp
+++ b/deps/icu-small/source/i18n/dtitvinf.cpp
@@ -42,7 +42,9 @@ U_NAMESPACE_BEGIN
#ifdef DTITVINF_DEBUG
-#define PRINTMESG(msg) { std::cout << "(" << __FILE__ << ":" << __LINE__ << ") " << msg << "\n"; }
+#define PRINTMESG(msg) UPRV_BLOCK_MACRO_BEGIN { \
+ std::cout << "(" << __FILE__ << ":" << __LINE__ << ") " << msg << "\n"; \
+} UPRV_BLOCK_MACRO_END
#endif
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DateIntervalInfo)
diff --git a/deps/icu-small/source/i18n/dtptngen.cpp b/deps/icu-small/source/i18n/dtptngen.cpp
index 9ca29a3cc7..50a377259a 100644
--- a/deps/icu-small/source/i18n/dtptngen.cpp
+++ b/deps/icu-small/source/i18n/dtptngen.cpp
@@ -28,6 +28,7 @@
#include "unicode/ures.h"
#include "unicode/ustring.h"
#include "unicode/rep.h"
+#include "unicode/region.h"
#include "cpputils.h"
#include "mutex.h"
#include "umutex.h"
@@ -613,29 +614,56 @@ U_CFUNC void U_CALLCONV DateTimePatternGenerator::loadAllowedHourFormatsData(UEr
ures_getAllItemsWithFallback(rb.getAlias(), "timeData", sink, status);
}
-void DateTimePatternGenerator::getAllowedHourFormats(const Locale &locale, UErrorCode &status) {
- if (U_FAILURE(status)) { return; }
- Locale maxLocale(locale);
- maxLocale.addLikelySubtags(status);
- if (U_FAILURE(status)) {
- return;
- }
-
- const char *country = maxLocale.getCountry();
- if (*country == '\0') { country = "001"; }
- const char *language = maxLocale.getLanguage();
-
+static int32_t* getAllowedHourFormatsLangCountry(const char* language, const char* country, UErrorCode& status) {
CharString langCountry;
- langCountry.append(language, static_cast<int32_t>(uprv_strlen(language)), status);
+ langCountry.append(language, status);
langCountry.append('_', status);
- langCountry.append(country, static_cast<int32_t>(uprv_strlen(country)), status);
+ langCountry.append(country, status);
- int32_t *allowedFormats;
+ int32_t* allowedFormats;
allowedFormats = (int32_t *)uhash_get(localeToAllowedHourFormatsMap, langCountry.data());
if (allowedFormats == nullptr) {
allowedFormats = (int32_t *)uhash_get(localeToAllowedHourFormatsMap, const_cast<char *>(country));
}
+ return allowedFormats;
+}
+
+void DateTimePatternGenerator::getAllowedHourFormats(const Locale &locale, UErrorCode &status) {
+ if (U_FAILURE(status)) { return; }
+
+ const char *language = locale.getLanguage();
+ const char *country = locale.getCountry();
+ Locale maxLocale; // must be here for correct lifetime
+ if (*language == '\0' || *country == '\0') {
+ maxLocale = locale;
+ UErrorCode localStatus = U_ZERO_ERROR;
+ maxLocale.addLikelySubtags(localStatus);
+ if (U_SUCCESS(localStatus)) {
+ language = maxLocale.getLanguage();
+ country = maxLocale.getCountry();
+ }
+ }
+ if (*language == '\0') {
+ // Unexpected, but fail gracefully
+ language = "und";
+ }
+ if (*country == '\0') {
+ country = "001";
+ }
+
+ int32_t* allowedFormats = getAllowedHourFormatsLangCountry(language, country, status);
+
+ // Check if the region has an alias
+ if (allowedFormats == nullptr) {
+ UErrorCode localStatus = U_ZERO_ERROR;
+ const Region* region = Region::getInstance(country, localStatus);
+ if (U_SUCCESS(localStatus)) {
+ country = region->getRegionCode(); // the real region code
+ allowedFormats = getAllowedHourFormatsLangCountry(language, country, status);
+ }
+ }
+
if (allowedFormats != nullptr) { // Lookup is successful
// Here allowedFormats points to a list consisting of key for preferredFormat,
// followed by one or more keys for allowedFormats, then followed by ALLOWED_HOUR_FORMAT_UNKNOWN.
@@ -787,6 +815,7 @@ void
DateTimePatternGenerator::getCalendarTypeToUse(const Locale& locale, CharString& destination, UErrorCode& err) {
destination.clear().append(DT_DateTimeGregorianTag, -1, err); // initial default
if ( U_SUCCESS(err) ) {
+ UErrorCode localStatus = U_ZERO_ERROR;
char localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY];
// obtain a locale that always has the calendar key value that should be used
ures_getFunctionalEquivalent(
@@ -798,8 +827,7 @@ DateTimePatternGenerator::getCalendarTypeToUse(const Locale& locale, CharString&
locale.getName(),
nullptr,
FALSE,
- &err);
- if (U_FAILURE(err)) { return; }
+ &localStatus);
localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY-1] = 0; // ensure null termination
// now get the calendar key value from that locale
char calendarType[ULOC_KEYWORDS_CAPACITY];
@@ -808,13 +836,17 @@ DateTimePatternGenerator::getCalendarTypeToUse(const Locale& locale, CharString&
"calendar",
calendarType,
ULOC_KEYWORDS_CAPACITY,
- &err);
- if (U_FAILURE(err)) { return; }
+ &localStatus);
+ // If the input locale was invalid, don't fail with missing resource error, instead
+ // continue with default of Gregorian.
+ if (U_FAILURE(localStatus) && localStatus != U_MISSING_RESOURCE_ERROR) {
+ err = localStatus;
+ return;
+ }
if (calendarTypeLen < ULOC_KEYWORDS_CAPACITY) {
destination.clear().append(calendarType, -1, err);
if (U_FAILURE(err)) { return; }
}
- err = U_ZERO_ERROR;
}
}
@@ -2543,7 +2575,8 @@ UChar SkeletonFields::getFirstChar() const {
}
-PtnSkeleton::PtnSkeleton() {
+PtnSkeleton::PtnSkeleton()
+ : addedDefaultDayPeriod(FALSE) {
}
PtnSkeleton::PtnSkeleton(const PtnSkeleton& other) {
@@ -2554,6 +2587,7 @@ void PtnSkeleton::copyFrom(const PtnSkeleton& other) {
uprv_memcpy(type, other.type, sizeof(type));
original.copyFrom(other.original);
baseOriginal.copyFrom(other.baseOriginal);
+ addedDefaultDayPeriod = other.addedDefaultDayPeriod;
}
void PtnSkeleton::clear() {
diff --git a/deps/icu-small/source/i18n/esctrn.cpp b/deps/icu-small/source/i18n/esctrn.cpp
index 900bed7e45..ba0e4c2c7b 100644
--- a/deps/icu-small/source/i18n/esctrn.cpp
+++ b/deps/icu-small/source/i18n/esctrn.cpp
@@ -122,7 +122,7 @@ EscapeTransliterator::~EscapeTransliterator() {
/**
* Transliterator API.
*/
-Transliterator* EscapeTransliterator::clone() const {
+EscapeTransliterator* EscapeTransliterator::clone() const {
return new EscapeTransliterator(*this);
}
diff --git a/deps/icu-small/source/i18n/esctrn.h b/deps/icu-small/source/i18n/esctrn.h
index 60ecc74b49..2a2c6dcfe9 100644
--- a/deps/icu-small/source/i18n/esctrn.h
+++ b/deps/icu-small/source/i18n/esctrn.h
@@ -115,7 +115,7 @@ class EscapeTransliterator : public Transliterator {
/**
* Transliterator API.
*/
- virtual Transliterator* clone() const;
+ virtual EscapeTransliterator* clone() const;
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
diff --git a/deps/icu-small/source/i18n/ethpccal.cpp b/deps/icu-small/source/i18n/ethpccal.cpp
index 4377c59b32..0b8ad0e814 100644
--- a/deps/icu-small/source/i18n/ethpccal.cpp
+++ b/deps/icu-small/source/i18n/ethpccal.cpp
@@ -46,7 +46,7 @@ EthiopicCalendar::~EthiopicCalendar()
{
}
-Calendar*
+EthiopicCalendar*
EthiopicCalendar::clone() const
{
return new EthiopicCalendar(*this);
diff --git a/deps/icu-small/source/i18n/ethpccal.h b/deps/icu-small/source/i18n/ethpccal.h
index 5fae2fb1be..179a20e853 100644
--- a/deps/icu-small/source/i18n/ethpccal.h
+++ b/deps/icu-small/source/i18n/ethpccal.h
@@ -141,7 +141,7 @@ public:
* @return return a polymorphic copy of this calendar.
* @internal
*/
- virtual Calendar* clone() const;
+ virtual EthiopicCalendar* clone() const;
/**
* return the calendar type, "ethiopic"
diff --git a/deps/icu-small/source/i18n/fmtable.cpp b/deps/icu-small/source/i18n/fmtable.cpp
index 9baa5ff480..10a6fdb0ff 100644
--- a/deps/icu-small/source/i18n/fmtable.cpp
+++ b/deps/icu-small/source/i18n/fmtable.cpp
@@ -736,7 +736,7 @@ CharString *Formattable::internalGetCharString(UErrorCode &status) {
fDecimalStr->append("Infinity", status);
} else if (fDecimalQuantity->isNaN()) {
fDecimalStr->append("NaN", status);
- } else if (fDecimalQuantity->isZero()) {
+ } else if (fDecimalQuantity->isZeroish()) {
fDecimalStr->append("0", -1, status);
} else if (fType==kLong || fType==kInt64 || // use toPlainString for integer types
(fDecimalQuantity->getMagnitude() != INT32_MIN && std::abs(fDecimalQuantity->getMagnitude()) < 5)) {
diff --git a/deps/icu-small/source/i18n/number_stringbuilder.cpp b/deps/icu-small/source/i18n/formatted_string_builder.cpp
index 03300b33ac..3024bff6ad 100644
--- a/deps/icu-small/source/i18n/number_stringbuilder.cpp
+++ b/deps/icu-small/source/i18n/formatted_string_builder.cpp
@@ -5,14 +5,9 @@
#if !UCONFIG_NO_FORMATTING
-#include "number_stringbuilder.h"
-#include "static_unicode_sets.h"
+#include "formatted_string_builder.h"
+#include "unicode/ustring.h"
#include "unicode/utf16.h"
-#include "number_utils.h"
-
-using namespace icu;
-using namespace icu::number;
-using namespace icu::number::impl;
namespace {
@@ -34,7 +29,10 @@ inline void uprv_memmove2(void* dest, const void* src, size_t len) {
} // namespace
-NumberStringBuilder::NumberStringBuilder() {
+
+U_NAMESPACE_BEGIN
+
+FormattedStringBuilder::FormattedStringBuilder() {
#if U_DEBUG
// Initializing the memory to non-zero helps catch some bugs that involve
// reading from an improperly terminated string.
@@ -44,18 +42,18 @@ NumberStringBuilder::NumberStringBuilder() {
#endif
}
-NumberStringBuilder::~NumberStringBuilder() {
+FormattedStringBuilder::~FormattedStringBuilder() {
if (fUsingHeap) {
uprv_free(fChars.heap.ptr);
uprv_free(fFields.heap.ptr);
}
}
-NumberStringBuilder::NumberStringBuilder(const NumberStringBuilder &other) {
+FormattedStringBuilder::FormattedStringBuilder(const FormattedStringBuilder &other) {
*this = other;
}
-NumberStringBuilder &NumberStringBuilder::operator=(const NumberStringBuilder &other) {
+FormattedStringBuilder &FormattedStringBuilder::operator=(const FormattedStringBuilder &other) {
// Check for self-assignment
if (this == &other) {
return *this;
@@ -78,7 +76,7 @@ NumberStringBuilder &NumberStringBuilder::operator=(const NumberStringBuilder &o
// UErrorCode is not available; fail silently.
uprv_free(newChars);
uprv_free(newFields);
- *this = NumberStringBuilder(); // can't fail
+ *this = FormattedStringBuilder(); // can't fail
return *this;
}
@@ -97,15 +95,15 @@ NumberStringBuilder &NumberStringBuilder::operator=(const NumberStringBuilder &o
return *this;
}
-int32_t NumberStringBuilder::length() const {
+int32_t FormattedStringBuilder::length() const {
return fLength;
}
-int32_t NumberStringBuilder::codePointCount() const {
+int32_t FormattedStringBuilder::codePointCount() const {
return u_countChar32(getCharPtr() + fZero, fLength);
}
-UChar32 NumberStringBuilder::getFirstCodePoint() const {
+UChar32 FormattedStringBuilder::getFirstCodePoint() const {
if (fLength == 0) {
return -1;
}
@@ -114,7 +112,7 @@ UChar32 NumberStringBuilder::getFirstCodePoint() const {
return cp;
}
-UChar32 NumberStringBuilder::getLastCodePoint() const {
+UChar32 FormattedStringBuilder::getLastCodePoint() const {
if (fLength == 0) {
return -1;
}
@@ -125,13 +123,13 @@ UChar32 NumberStringBuilder::getLastCodePoint() const {
return cp;
}
-UChar32 NumberStringBuilder::codePointAt(int32_t index) const {
+UChar32 FormattedStringBuilder::codePointAt(int32_t index) const {
UChar32 cp;
U16_GET(getCharPtr() + fZero, 0, index, fLength, cp);
return cp;
}
-UChar32 NumberStringBuilder::codePointBefore(int32_t index) const {
+UChar32 FormattedStringBuilder::codePointBefore(int32_t index) const {
int32_t offset = index;
U16_BACK_1(getCharPtr() + fZero, 0, offset);
UChar32 cp;
@@ -139,19 +137,15 @@ UChar32 NumberStringBuilder::codePointBefore(int32_t index) const {
return cp;
}
-NumberStringBuilder &NumberStringBuilder::clear() {
+FormattedStringBuilder &FormattedStringBuilder::clear() {
// TODO: Reset the heap here?
fZero = getCapacity() / 2;
fLength = 0;
return *this;
}
-int32_t NumberStringBuilder::appendCodePoint(UChar32 codePoint, Field field, UErrorCode &status) {
- return insertCodePoint(fLength, codePoint, field, status);
-}
-
int32_t
-NumberStringBuilder::insertCodePoint(int32_t index, UChar32 codePoint, Field field, UErrorCode &status) {
+FormattedStringBuilder::insertCodePoint(int32_t index, UChar32 codePoint, Field field, UErrorCode &status) {
int32_t count = U16_LENGTH(codePoint);
int32_t position = prepareForInsert(index, count, status);
if (U_FAILURE(status)) {
@@ -168,11 +162,7 @@ NumberStringBuilder::insertCodePoint(int32_t index, UChar32 codePoint, Field fie
return count;
}
-int32_t NumberStringBuilder::append(const UnicodeString &unistr, Field field, UErrorCode &status) {
- return insert(fLength, unistr, field, status);
-}
-
-int32_t NumberStringBuilder::insert(int32_t index, const UnicodeString &unistr, Field field,
+int32_t FormattedStringBuilder::insert(int32_t index, const UnicodeString &unistr, Field field,
UErrorCode &status) {
if (unistr.length() == 0) {
// Nothing to insert.
@@ -186,7 +176,7 @@ int32_t NumberStringBuilder::insert(int32_t index, const UnicodeString &unistr,
}
int32_t
-NumberStringBuilder::insert(int32_t index, const UnicodeString &unistr, int32_t start, int32_t end,
+FormattedStringBuilder::insert(int32_t index, const UnicodeString &unistr, int32_t start, int32_t end,
Field field, UErrorCode &status) {
int32_t count = end - start;
int32_t position = prepareForInsert(index, count, status);
@@ -201,7 +191,7 @@ NumberStringBuilder::insert(int32_t index, const UnicodeString &unistr, int32_t
}
int32_t
-NumberStringBuilder::splice(int32_t startThis, int32_t endThis, const UnicodeString &unistr,
+FormattedStringBuilder::splice(int32_t startThis, int32_t endThis, const UnicodeString &unistr,
int32_t startOther, int32_t endOther, Field field, UErrorCode& status) {
int32_t thisLength = endThis - startThis;
int32_t otherLength = endOther - startOther;
@@ -224,12 +214,12 @@ NumberStringBuilder::splice(int32_t startThis, int32_t endThis, const UnicodeSt
return count;
}
-int32_t NumberStringBuilder::append(const NumberStringBuilder &other, UErrorCode &status) {
+int32_t FormattedStringBuilder::append(const FormattedStringBuilder &other, UErrorCode &status) {
return insert(fLength, other, status);
}
int32_t
-NumberStringBuilder::insert(int32_t index, const NumberStringBuilder &other, UErrorCode &status) {
+FormattedStringBuilder::insert(int32_t index, const FormattedStringBuilder &other, UErrorCode &status) {
if (this == &other) {
status = U_ILLEGAL_ARGUMENT_ERROR;
return 0;
@@ -250,7 +240,7 @@ NumberStringBuilder::insert(int32_t index, const NumberStringBuilder &other, UEr
return count;
}
-void NumberStringBuilder::writeTerminator(UErrorCode& status) {
+void FormattedStringBuilder::writeTerminator(UErrorCode& status) {
int32_t position = prepareForInsert(fLength, 1, status);
if (U_FAILURE(status)) {
return;
@@ -260,7 +250,7 @@ void NumberStringBuilder::writeTerminator(UErrorCode& status) {
fLength--;
}
-int32_t NumberStringBuilder::prepareForInsert(int32_t index, int32_t count, UErrorCode &status) {
+int32_t FormattedStringBuilder::prepareForInsert(int32_t index, int32_t count, UErrorCode &status) {
U_ASSERT(index >= 0);
U_ASSERT(index <= fLength);
U_ASSERT(count >= 0);
@@ -279,7 +269,7 @@ int32_t NumberStringBuilder::prepareForInsert(int32_t index, int32_t count, UErr
}
}
-int32_t NumberStringBuilder::prepareForInsertHelper(int32_t index, int32_t count, UErrorCode &status) {
+int32_t FormattedStringBuilder::prepareForInsertHelper(int32_t index, int32_t count, UErrorCode &status) {
int32_t oldCapacity = getCapacity();
int32_t oldZero = fZero;
char16_t *oldChars = getCharPtr();
@@ -342,7 +332,7 @@ int32_t NumberStringBuilder::prepareForInsertHelper(int32_t index, int32_t count
return fZero + index;
}
-int32_t NumberStringBuilder::remove(int32_t index, int32_t count) {
+int32_t FormattedStringBuilder::remove(int32_t index, int32_t count) {
// TODO: Reset the heap here? (If the string after removal can fit on stack?)
int32_t position = index + fZero;
uprv_memmove2(getCharPtr() + position,
@@ -355,18 +345,18 @@ int32_t NumberStringBuilder::remove(int32_t index, int32_t count) {
return position;
}
-UnicodeString NumberStringBuilder::toUnicodeString() const {
+UnicodeString FormattedStringBuilder::toUnicodeString() const {
return UnicodeString(getCharPtr() + fZero, fLength);
}
-const UnicodeString NumberStringBuilder::toTempUnicodeString() const {
+const UnicodeString FormattedStringBuilder::toTempUnicodeString() const {
// Readonly-alias constructor:
return UnicodeString(FALSE, getCharPtr() + fZero, fLength);
}
-UnicodeString NumberStringBuilder::toDebugString() const {
+UnicodeString FormattedStringBuilder::toDebugString() const {
UnicodeString sb;
- sb.append(u"<NumberStringBuilder [", -1);
+ sb.append(u"<FormattedStringBuilder [", -1);
sb.append(toUnicodeString());
sb.append(u"] [", -1);
for (int i = 0; i < fLength; i++) {
@@ -419,11 +409,11 @@ UnicodeString NumberStringBuilder::toDebugString() const {
return sb;
}
-const char16_t *NumberStringBuilder::chars() const {
+const char16_t *FormattedStringBuilder::chars() const {
return getCharPtr() + fZero;
}
-bool NumberStringBuilder::contentEquals(const NumberStringBuilder &other) const {
+bool FormattedStringBuilder::contentEquals(const FormattedStringBuilder &other) const {
if (fLength != other.fLength) {
return false;
}
@@ -435,136 +425,7 @@ bool NumberStringBuilder::contentEquals(const NumberStringBuilder &other) const
return true;
}
-bool NumberStringBuilder::nextFieldPosition(FieldPosition& fp, UErrorCode& status) const {
- int32_t rawField = fp.getField();
-
- if (rawField == FieldPosition::DONT_CARE) {
- return FALSE;
- }
-
- if (rawField < 0 || rawField >= UNUM_FIELD_COUNT) {
- status = U_ILLEGAL_ARGUMENT_ERROR;
- return FALSE;
- }
-
- ConstrainedFieldPosition cfpos;
- cfpos.constrainField(UFIELD_CATEGORY_NUMBER, rawField);
- cfpos.setState(UFIELD_CATEGORY_NUMBER, rawField, fp.getBeginIndex(), fp.getEndIndex());
- if (nextPosition(cfpos, 0, status)) {
- fp.setBeginIndex(cfpos.getStart());
- fp.setEndIndex(cfpos.getLimit());
- return true;
- }
-
- // Special case: fraction should start after integer if fraction is not present
- if (rawField == UNUM_FRACTION_FIELD && fp.getEndIndex() == 0) {
- bool inside = false;
- int32_t i = fZero;
- for (; i < fZero + fLength; i++) {
- if (isIntOrGroup(getFieldPtr()[i]) || getFieldPtr()[i] == UNUM_DECIMAL_SEPARATOR_FIELD) {
- inside = true;
- } else if (inside) {
- break;
- }
- }
- fp.setBeginIndex(i - fZero);
- fp.setEndIndex(i - fZero);
- }
-
- return false;
-}
-
-void NumberStringBuilder::getAllFieldPositions(FieldPositionIteratorHandler& fpih,
- UErrorCode& status) const {
- ConstrainedFieldPosition cfpos;
- while (nextPosition(cfpos, 0, status)) {
- fpih.addAttribute(cfpos.getField(), cfpos.getStart(), cfpos.getLimit());
- }
-}
-
-// Signal the end of the string using a field that doesn't exist and that is
-// different from UNUM_FIELD_COUNT, which is used for "null number field".
-static constexpr Field kEndField = 0xff;
-
-bool NumberStringBuilder::nextPosition(ConstrainedFieldPosition& cfpos, Field numericField, UErrorCode& /*status*/) const {
- auto numericCAF = NumFieldUtils::expand(numericField);
- int32_t fieldStart = -1;
- Field currField = UNUM_FIELD_COUNT;
- for (int32_t i = fZero + cfpos.getLimit(); i <= fZero + fLength; i++) {
- Field _field = (i < fZero + fLength) ? getFieldPtr()[i] : kEndField;
- // Case 1: currently scanning a field.
- if (currField != UNUM_FIELD_COUNT) {
- if (currField != _field) {
- int32_t end = i - fZero;
- // Grouping separators can be whitespace; don't throw them out!
- if (currField != UNUM_GROUPING_SEPARATOR_FIELD) {
- end = trimBack(i - fZero);
- }
- if (end <= fieldStart) {
- // Entire field position is ignorable; skip.
- fieldStart = -1;
- currField = UNUM_FIELD_COUNT;
- i--; // look at this index again
- continue;
- }
- int32_t start = fieldStart;
- if (currField != UNUM_GROUPING_SEPARATOR_FIELD) {
- start = trimFront(start);
- }
- auto caf = NumFieldUtils::expand(currField);
- cfpos.setState(caf.category, caf.field, start, end);
- return true;
- }
- continue;
- }
- // Special case: coalesce the INTEGER if we are pointing at the end of the INTEGER.
- if (cfpos.matchesField(UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD)
- && i > fZero
- // don't return the same field twice in a row:
- && i - fZero > cfpos.getLimit()
- && isIntOrGroup(getFieldPtr()[i - 1])
- && !isIntOrGroup(_field)) {
- int j = i - 1;
- for (; j >= fZero && isIntOrGroup(getFieldPtr()[j]); j--) {}
- cfpos.setState(UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD, j - fZero + 1, i - fZero);
- return true;
- }
- // Special case: coalesce NUMERIC if we are pointing at the end of the NUMERIC.
- if (numericField != 0
- && cfpos.matchesField(numericCAF.category, numericCAF.field)
- && i > fZero
- // don't return the same field twice in a row:
- && (i - fZero > cfpos.getLimit()
- || cfpos.getCategory() != numericCAF.category
- || cfpos.getField() != numericCAF.field)
- && isNumericField(getFieldPtr()[i - 1])
- && !isNumericField(_field)) {
- int j = i - 1;
- for (; j >= fZero && isNumericField(getFieldPtr()[j]); j--) {}
- cfpos.setState(numericCAF.category, numericCAF.field, j - fZero + 1, i - fZero);
- return true;
- }
- // Special case: skip over INTEGER; will be coalesced later.
- if (_field == UNUM_INTEGER_FIELD) {
- _field = UNUM_FIELD_COUNT;
- }
- // Case 2: no field starting at this position.
- if (_field == UNUM_FIELD_COUNT || _field == kEndField) {
- continue;
- }
- // Case 3: check for field starting at this position
- auto caf = NumFieldUtils::expand(_field);
- if (cfpos.matchesField(caf.category, caf.field)) {
- fieldStart = i - fZero;
- currField = _field;
- }
- }
-
- U_ASSERT(currField == UNUM_FIELD_COUNT);
- return false;
-}
-
-bool NumberStringBuilder::containsField(Field field) const {
+bool FormattedStringBuilder::containsField(Field field) const {
for (int32_t i = 0; i < fLength; i++) {
if (field == fieldAt(i)) {
return true;
@@ -573,27 +434,6 @@ bool NumberStringBuilder::containsField(Field field) const {
return false;
}
-bool NumberStringBuilder::isIntOrGroup(Field field) {
- return field == UNUM_INTEGER_FIELD
- || field == UNUM_GROUPING_SEPARATOR_FIELD;
-}
-
-bool NumberStringBuilder::isNumericField(Field field) {
- return NumFieldUtils::isNumericField(field);
-}
-
-int32_t NumberStringBuilder::trimBack(int32_t limit) const {
- return unisets::get(unisets::DEFAULT_IGNORABLES)->spanBack(
- getCharPtr() + fZero,
- limit,
- USET_SPAN_CONTAINED);
-}
-
-int32_t NumberStringBuilder::trimFront(int32_t start) const {
- return start + unisets::get(unisets::DEFAULT_IGNORABLES)->span(
- getCharPtr() + fZero + start,
- fLength - start,
- USET_SPAN_CONTAINED);
-}
+U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/deps/icu-small/source/i18n/formatted_string_builder.h b/deps/icu-small/source/i18n/formatted_string_builder.h
new file mode 100644
index 0000000000..2949ae73e0
--- /dev/null
+++ b/deps/icu-small/source/i18n/formatted_string_builder.h
@@ -0,0 +1,253 @@
+// © 2017 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+#ifndef __NUMBER_STRINGBUILDER_H__
+#define __NUMBER_STRINGBUILDER_H__
+
+
+#include <cstdint>
+#include "unicode/unum.h" // for UNUM_FIELD_COUNT
+#include "cstring.h"
+#include "uassert.h"
+#include "fphdlimp.h"
+
+U_NAMESPACE_BEGIN
+
+class FormattedValueStringBuilderImpl;
+
+/**
+ * A StringBuilder optimized for formatting. It implements the following key
+ * features beyond a UnicodeString:
+ *
+ * <ol>
+ * <li>Efficient prepend as well as append.
+ * <li>Keeps tracks of Fields in an efficient manner.
+ * </ol>
+ *
+ * See also FormattedValueStringBuilderImpl.
+ *
+ * @author sffc (Shane Carr)
+ */
+class U_I18N_API FormattedStringBuilder : public UMemory {
+ private:
+ static const int32_t DEFAULT_CAPACITY = 40;
+
+ template<typename T>
+ union ValueOrHeapArray {
+ T value[DEFAULT_CAPACITY];
+ struct {
+ T *ptr;
+ int32_t capacity;
+ } heap;
+ };
+
+ public:
+ FormattedStringBuilder();
+
+ ~FormattedStringBuilder();
+
+ FormattedStringBuilder(const FormattedStringBuilder &other);
+
+ // Convention: bottom 4 bits for field, top 4 bits for field category.
+ // Field category 0 implies the number category so that the number field
+ // literals can be directly passed as a Field type.
+ // See the helper functions in "StringBuilderFieldUtils" below.
+ typedef uint8_t Field;
+
+ FormattedStringBuilder &operator=(const FormattedStringBuilder &other);
+
+ int32_t length() const;
+
+ int32_t codePointCount() const;
+
+ inline char16_t charAt(int32_t index) const {
+ U_ASSERT(index >= 0);
+ U_ASSERT(index < fLength);
+ return getCharPtr()[fZero + index];
+ }
+
+ inline Field fieldAt(int32_t index) const {
+ U_ASSERT(index >= 0);
+ U_ASSERT(index < fLength);
+ return getFieldPtr()[fZero + index];
+ }
+
+ UChar32 getFirstCodePoint() const;
+
+ UChar32 getLastCodePoint() const;
+
+ UChar32 codePointAt(int32_t index) const;
+
+ UChar32 codePointBefore(int32_t index) const;
+
+ FormattedStringBuilder &clear();
+
+ /** Appends a UTF-16 code unit. */
+ inline int32_t appendChar16(char16_t codeUnit, Field field, UErrorCode& status) {
+ // appendCodePoint handles both code units and code points.
+ return insertCodePoint(fLength, codeUnit, field, status);
+ }
+
+ /** Inserts a UTF-16 code unit. Note: insert at index 0 is very efficient. */
+ inline int32_t insertChar16(int32_t index, char16_t codeUnit, Field field, UErrorCode& status) {
+ // insertCodePoint handles both code units and code points.
+ return insertCodePoint(index, codeUnit, field, status);
+ }
+
+ /** Appends a Unicode code point. */
+ inline int32_t appendCodePoint(UChar32 codePoint, Field field, UErrorCode &status) {
+ return insertCodePoint(fLength, codePoint, field, status);
+ }
+
+ /** Inserts a Unicode code point. Note: insert at index 0 is very efficient. */
+ int32_t insertCodePoint(int32_t index, UChar32 codePoint, Field field, UErrorCode &status);
+
+ /** Appends a string. */
+ inline int32_t append(const UnicodeString &unistr, Field field, UErrorCode &status) {
+ return insert(fLength, unistr, field, status);
+ }
+
+ /** Inserts a string. Note: insert at index 0 is very efficient. */
+ int32_t insert(int32_t index, const UnicodeString &unistr, Field field, UErrorCode &status);
+
+ /** Inserts a substring. Note: insert at index 0 is very efficient.
+ *
+ * @param start Start index of the substring of unistr to be inserted.
+ * @param end End index of the substring of unistr to be inserted (exclusive).
+ */
+ int32_t insert(int32_t index, const UnicodeString &unistr, int32_t start, int32_t end, Field field,
+ UErrorCode &status);
+
+ /** Deletes a substring and then inserts a string at that same position.
+ * Similar to JavaScript Array.prototype.splice().
+ *
+ * @param startThis Start of the span to delete.
+ * @param endThis End of the span to delete (exclusive).
+ * @param unistr The string to insert at the deletion position.
+ * @param startOther Start index of the substring of unistr to be inserted.
+ * @param endOther End index of the substring of unistr to be inserted (exclusive).
+ */
+ int32_t splice(int32_t startThis, int32_t endThis, const UnicodeString &unistr,
+ int32_t startOther, int32_t endOther, Field field, UErrorCode& status);
+
+ /** Appends a formatted string. */
+ int32_t append(const FormattedStringBuilder &other, UErrorCode &status);
+
+ /** Inserts a formatted string. Note: insert at index 0 is very efficient. */
+ int32_t insert(int32_t index, const FormattedStringBuilder &other, UErrorCode &status);
+
+ /**
+ * Ensures that the string buffer contains a NUL terminator. The NUL terminator does
+ * not count toward the string length. Any further changes to the string (insert or
+ * append) may invalidate the NUL terminator.
+ *
+ * You should call this method after the formatted string is completely built if you
+ * plan to return a pointer to the string from a C API.
+ */
+ void writeTerminator(UErrorCode& status);
+
+ /**
+ * Gets a "safe" UnicodeString that can be used even after the FormattedStringBuilder is destructed.
+ */
+ UnicodeString toUnicodeString() const;
+
+ /**
+ * Gets an "unsafe" UnicodeString that is valid only as long as the FormattedStringBuilder is alive and
+ * unchanged. Slightly faster than toUnicodeString().
+ */
+ const UnicodeString toTempUnicodeString() const;
+
+ UnicodeString toDebugString() const;
+
+ const char16_t *chars() const;
+
+ bool contentEquals(const FormattedStringBuilder &other) const;
+
+ bool containsField(Field field) const;
+
+ private:
+ bool fUsingHeap = false;
+ ValueOrHeapArray<char16_t> fChars;
+ ValueOrHeapArray<Field> fFields;
+ int32_t fZero = DEFAULT_CAPACITY / 2;
+ int32_t fLength = 0;
+
+ inline char16_t *getCharPtr() {
+ return fUsingHeap ? fChars.heap.ptr : fChars.value;
+ }
+
+ inline const char16_t *getCharPtr() const {
+ return fUsingHeap ? fChars.heap.ptr : fChars.value;
+ }
+
+ inline Field *getFieldPtr() {
+ return fUsingHeap ? fFields.heap.ptr : fFields.value;
+ }
+
+ inline const Field *getFieldPtr() const {
+ return fUsingHeap ? fFields.heap.ptr : fFields.value;
+ }
+
+ inline int32_t getCapacity() const {
+ return fUsingHeap ? fChars.heap.capacity : DEFAULT_CAPACITY;
+ }
+
+ int32_t prepareForInsert(int32_t index, int32_t count, UErrorCode &status);
+
+ int32_t prepareForInsertHelper(int32_t index, int32_t count, UErrorCode &status);
+
+ int32_t remove(int32_t index, int32_t count);
+
+ friend class FormattedValueStringBuilderImpl;
+};
+
+/**
+ * Helper functions for dealing with the Field typedef, which stores fields
+ * in a compressed format.
+ */
+class StringBuilderFieldUtils {
+public:
+ struct CategoryFieldPair {
+ int32_t category;
+ int32_t field;
+ };
+
+ /** Compile-time function to construct a Field from a category and a field */
+ template <int32_t category, int32_t field>
+ static constexpr FormattedStringBuilder::Field compress() {
+ static_assert(category != 0, "cannot use Undefined category in FieldUtils");
+ static_assert(category <= 0xf, "only 4 bits for category");
+ static_assert(field <= 0xf, "only 4 bits for field");
+ return static_cast<int8_t>((category << 4) | field);
+ }
+
+ /** Runtime inline function to unpack the category and field from the Field */
+ static inline CategoryFieldPair expand(FormattedStringBuilder::Field field) {
+ if (field == UNUM_FIELD_COUNT) {
+ return {UFIELD_CATEGORY_UNDEFINED, 0};
+ }
+ CategoryFieldPair ret = {
+ (field >> 4),
+ (field & 0xf)
+ };
+ if (ret.category == 0) {
+ ret.category = UFIELD_CATEGORY_NUMBER;
+ }
+ return ret;
+ }
+
+ static inline bool isNumericField(FormattedStringBuilder::Field field) {
+ int8_t category = field >> 4;
+ return category == 0 || category == UFIELD_CATEGORY_NUMBER;
+ }
+};
+
+U_NAMESPACE_END
+
+
+#endif //__NUMBER_STRINGBUILDER_H__
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/deps/icu-small/source/i18n/formattedval_impl.h b/deps/icu-small/source/i18n/formattedval_impl.h
index 69ba0922ed..4ee53e4589 100644
--- a/deps/icu-small/source/i18n/formattedval_impl.h
+++ b/deps/icu-small/source/i18n/formattedval_impl.h
@@ -18,7 +18,7 @@
#include "fphdlimp.h"
#include "util.h"
#include "uvectr32.h"
-#include "number_stringbuilder.h"
+#include "formatted_string_builder.h"
/**
@@ -67,7 +67,9 @@ typedef enum UCFPosConstraintType {
U_NAMESPACE_BEGIN
-/** Implementation using FieldPositionHandler to accept fields. */
+/**
+ * Implementation of FormattedValue using FieldPositionHandler to accept fields.
+ */
class FormattedValueFieldPositionIteratorImpl : public UMemory, public FormattedValue {
public:
@@ -112,12 +114,21 @@ private:
};
-class FormattedValueNumberStringBuilderImpl : public UMemory, public FormattedValue {
+/**
+ * Implementation of FormattedValue based on FormattedStringBuilder.
+ *
+ * The implementation currently revolves around numbers and number fields.
+ * However, it can be generalized in the future when there is a need.
+ *
+ * @author sffc (Shane Carr)
+ */
+// Exported as U_I18N_API for tests
+class U_I18N_API FormattedValueStringBuilderImpl : public UMemory, public FormattedValue {
public:
- FormattedValueNumberStringBuilderImpl(number::impl::Field numericField);
+ FormattedValueStringBuilderImpl(FormattedStringBuilder::Field numericField);
- virtual ~FormattedValueNumberStringBuilderImpl();
+ virtual ~FormattedValueStringBuilderImpl();
// Implementation of FormattedValue (const):
@@ -126,17 +137,25 @@ public:
Appendable& appendTo(Appendable& appendable, UErrorCode& status) const U_OVERRIDE;
UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const U_OVERRIDE;
- inline number::impl::NumberStringBuilder& getStringRef() {
+ // Additional helper functions:
+ UBool nextFieldPosition(FieldPosition& fp, UErrorCode& status) const;
+ void getAllFieldPositions(FieldPositionIteratorHandler& fpih, UErrorCode& status) const;
+ inline FormattedStringBuilder& getStringRef() {
return fString;
}
-
- inline const number::impl::NumberStringBuilder& getStringRef() const {
+ inline const FormattedStringBuilder& getStringRef() const {
return fString;
}
private:
- number::impl::NumberStringBuilder fString;
- number::impl::Field fNumericField;
+ FormattedStringBuilder fString;
+ FormattedStringBuilder::Field fNumericField;
+
+ bool nextPositionImpl(ConstrainedFieldPosition& cfpos, FormattedStringBuilder::Field numericField, UErrorCode& status) const;
+ static bool isIntOrGroup(FormattedStringBuilder::Field field);
+ static bool isNumericField(FormattedStringBuilder::Field field);
+ int32_t trimBack(int32_t limit) const;
+ int32_t trimFront(int32_t start) const;
};
diff --git a/deps/icu-small/source/i18n/formattedval_sbimpl.cpp b/deps/icu-small/source/i18n/formattedval_sbimpl.cpp
index 1fbecf25ac..ca28f22281 100644
--- a/deps/icu-small/source/i18n/formattedval_sbimpl.cpp
+++ b/deps/icu-small/source/i18n/formattedval_sbimpl.cpp
@@ -9,35 +9,203 @@
// Other independent implementations should go into their own cpp file for
// better dependency modularization.
+#include "unicode/ustring.h"
#include "formattedval_impl.h"
+#include "number_types.h"
+#include "formatted_string_builder.h"
+#include "number_utils.h"
+#include "static_unicode_sets.h"
U_NAMESPACE_BEGIN
-FormattedValueNumberStringBuilderImpl::FormattedValueNumberStringBuilderImpl(number::impl::Field numericField)
+typedef FormattedStringBuilder::Field Field;
+
+
+FormattedValueStringBuilderImpl::FormattedValueStringBuilderImpl(Field numericField)
: fNumericField(numericField) {
}
-FormattedValueNumberStringBuilderImpl::~FormattedValueNumberStringBuilderImpl() {
+FormattedValueStringBuilderImpl::~FormattedValueStringBuilderImpl() {
}
-UnicodeString FormattedValueNumberStringBuilderImpl::toString(UErrorCode&) const {
+UnicodeString FormattedValueStringBuilderImpl::toString(UErrorCode&) const {
return fString.toUnicodeString();
}
-UnicodeString FormattedValueNumberStringBuilderImpl::toTempString(UErrorCode&) const {
+UnicodeString FormattedValueStringBuilderImpl::toTempString(UErrorCode&) const {
return fString.toTempUnicodeString();
}
-Appendable& FormattedValueNumberStringBuilderImpl::appendTo(Appendable& appendable, UErrorCode&) const {
+Appendable& FormattedValueStringBuilderImpl::appendTo(Appendable& appendable, UErrorCode&) const {
appendable.appendString(fString.chars(), fString.length());
return appendable;
}
-UBool FormattedValueNumberStringBuilderImpl::nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const {
+UBool FormattedValueStringBuilderImpl::nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const {
// NOTE: MSVC sometimes complains when implicitly converting between bool and UBool
- return fString.nextPosition(cfpos, fNumericField, status) ? TRUE : FALSE;
+ return nextPositionImpl(cfpos, fNumericField, status) ? TRUE : FALSE;
+}
+
+UBool FormattedValueStringBuilderImpl::nextFieldPosition(FieldPosition& fp, UErrorCode& status) const {
+ int32_t rawField = fp.getField();
+
+ if (rawField == FieldPosition::DONT_CARE) {
+ return FALSE;
+ }
+
+ if (rawField < 0 || rawField >= UNUM_FIELD_COUNT) {
+ status = U_ILLEGAL_ARGUMENT_ERROR;
+ return FALSE;
+ }
+
+ ConstrainedFieldPosition cfpos;
+ cfpos.constrainField(UFIELD_CATEGORY_NUMBER, rawField);
+ cfpos.setState(UFIELD_CATEGORY_NUMBER, rawField, fp.getBeginIndex(), fp.getEndIndex());
+ if (nextPositionImpl(cfpos, 0, status)) {
+ fp.setBeginIndex(cfpos.getStart());
+ fp.setEndIndex(cfpos.getLimit());
+ return TRUE;
+ }
+
+ // Special case: fraction should start after integer if fraction is not present
+ if (rawField == UNUM_FRACTION_FIELD && fp.getEndIndex() == 0) {
+ bool inside = false;
+ int32_t i = fString.fZero;
+ for (; i < fString.fZero + fString.fLength; i++) {
+ if (isIntOrGroup(fString.getFieldPtr()[i]) || fString.getFieldPtr()[i] == UNUM_DECIMAL_SEPARATOR_FIELD) {
+ inside = true;
+ } else if (inside) {
+ break;
+ }
+ }
+ fp.setBeginIndex(i - fString.fZero);
+ fp.setEndIndex(i - fString.fZero);
+ }
+
+ return FALSE;
+}
+
+void FormattedValueStringBuilderImpl::getAllFieldPositions(FieldPositionIteratorHandler& fpih,
+ UErrorCode& status) const {
+ ConstrainedFieldPosition cfpos;
+ while (nextPositionImpl(cfpos, 0, status)) {
+ fpih.addAttribute(cfpos.getField(), cfpos.getStart(), cfpos.getLimit());
+ }
+}
+
+// Signal the end of the string using a field that doesn't exist and that is
+// different from UNUM_FIELD_COUNT, which is used for "null number field".
+static constexpr Field kEndField = 0xff;
+
+bool FormattedValueStringBuilderImpl::nextPositionImpl(ConstrainedFieldPosition& cfpos, Field numericField, UErrorCode& /*status*/) const {
+ auto numericCAF = StringBuilderFieldUtils::expand(numericField);
+ int32_t fieldStart = -1;
+ Field currField = UNUM_FIELD_COUNT;
+ for (int32_t i = fString.fZero + cfpos.getLimit(); i <= fString.fZero + fString.fLength; i++) {
+ Field _field = (i < fString.fZero + fString.fLength) ? fString.getFieldPtr()[i] : kEndField;
+ // Case 1: currently scanning a field.
+ if (currField != UNUM_FIELD_COUNT) {
+ if (currField != _field) {
+ int32_t end = i - fString.fZero;
+ // Grouping separators can be whitespace; don't throw them out!
+ if (currField != UNUM_GROUPING_SEPARATOR_FIELD) {
+ end = trimBack(i - fString.fZero);
+ }
+ if (end <= fieldStart) {
+ // Entire field position is ignorable; skip.
+ fieldStart = -1;
+ currField = UNUM_FIELD_COUNT;
+ i--; // look at this index again
+ continue;
+ }
+ int32_t start = fieldStart;
+ if (currField != UNUM_GROUPING_SEPARATOR_FIELD) {
+ start = trimFront(start);
+ }
+ auto caf = StringBuilderFieldUtils::expand(currField);
+ cfpos.setState(caf.category, caf.field, start, end);
+ return true;
+ }
+ continue;
+ }
+ // Special case: coalesce the INTEGER if we are pointing at the end of the INTEGER.
+ if (cfpos.matchesField(UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD)
+ && i > fString.fZero
+ // don't return the same field twice in a row:
+ && i - fString.fZero > cfpos.getLimit()
+ && isIntOrGroup(fString.getFieldPtr()[i - 1])
+ && !isIntOrGroup(_field)) {
+ int j = i - 1;
+ for (; j >= fString.fZero && isIntOrGroup(fString.getFieldPtr()[j]); j--) {}
+ cfpos.setState(
+ UFIELD_CATEGORY_NUMBER,
+ UNUM_INTEGER_FIELD,
+ j - fString.fZero + 1,
+ i - fString.fZero);
+ return true;
+ }
+ // Special case: coalesce NUMERIC if we are pointing at the end of the NUMERIC.
+ if (numericField != 0
+ && cfpos.matchesField(numericCAF.category, numericCAF.field)
+ && i > fString.fZero
+ // don't return the same field twice in a row:
+ && (i - fString.fZero > cfpos.getLimit()
+ || cfpos.getCategory() != numericCAF.category
+ || cfpos.getField() != numericCAF.field)
+ && isNumericField(fString.getFieldPtr()[i - 1])
+ && !isNumericField(_field)) {
+ int j = i - 1;
+ for (; j >= fString.fZero && isNumericField(fString.getFieldPtr()[j]); j--) {}
+ cfpos.setState(
+ numericCAF.category,
+ numericCAF.field,
+ j - fString.fZero + 1,
+ i - fString.fZero);
+ return true;
+ }
+ // Special case: skip over INTEGER; will be coalesced later.
+ if (_field == UNUM_INTEGER_FIELD) {
+ _field = UNUM_FIELD_COUNT;
+ }
+ // Case 2: no field starting at this position.
+ if (_field == UNUM_FIELD_COUNT || _field == kEndField) {
+ continue;
+ }
+ // Case 3: check for field starting at this position
+ auto caf = StringBuilderFieldUtils::expand(_field);
+ if (cfpos.matchesField(caf.category, caf.field)) {
+ fieldStart = i - fString.fZero;
+ currField = _field;
+ }
+ }
+
+ U_ASSERT(currField == UNUM_FIELD_COUNT);
+ return false;
+}
+
+bool FormattedValueStringBuilderImpl::isIntOrGroup(Field field) {
+ return field == UNUM_INTEGER_FIELD
+ || field == UNUM_GROUPING_SEPARATOR_FIELD;
+}
+
+bool FormattedValueStringBuilderImpl::isNumericField(Field field) {
+ return StringBuilderFieldUtils::isNumericField(field);
+}
+
+int32_t FormattedValueStringBuilderImpl::trimBack(int32_t limit) const {
+ return unisets::get(unisets::DEFAULT_IGNORABLES)->spanBack(
+ fString.getCharPtr() + fString.fZero,
+ limit,
+ USET_SPAN_CONTAINED);
+}
+
+int32_t FormattedValueStringBuilderImpl::trimFront(int32_t start) const {
+ return start + unisets::get(unisets::DEFAULT_IGNORABLES)->span(
+ fString.getCharPtr() + fString.fZero + start,
+ fString.fLength - start,
+ USET_SPAN_CONTAINED);
}
diff --git a/deps/icu-small/source/i18n/funcrepl.cpp b/deps/icu-small/source/i18n/funcrepl.cpp
index 30bcebbf90..ceb456e1af 100644
--- a/deps/icu-small/source/i18n/funcrepl.cpp
+++ b/deps/icu-small/source/i18n/funcrepl.cpp
@@ -59,7 +59,7 @@ FunctionReplacer::~FunctionReplacer() {
/**
* Implement UnicodeFunctor
*/
-UnicodeFunctor* FunctionReplacer::clone() const {
+FunctionReplacer* FunctionReplacer::clone() const {
return new FunctionReplacer(*this);
}
diff --git a/deps/icu-small/source/i18n/funcrepl.h b/deps/icu-small/source/i18n/funcrepl.h
index a835d5be7c..fe41f6caaa 100644
--- a/deps/icu-small/source/i18n/funcrepl.h
+++ b/deps/icu-small/source/i18n/funcrepl.h
@@ -70,7 +70,7 @@ class FunctionReplacer : public UnicodeFunctor, public UnicodeReplacer {
/**
* Implement UnicodeFunctor
*/
- virtual UnicodeFunctor* clone() const;
+ virtual FunctionReplacer* clone() const;
/**
* UnicodeFunctor API. Cast 'this' to a UnicodeReplacer* pointer
diff --git a/deps/icu-small/source/i18n/gender.cpp b/deps/icu-small/source/i18n/gender.cpp
index 106cf424c5..03c03cecad 100644
--- a/deps/icu-small/source/i18n/gender.cpp
+++ b/deps/icu-small/source/i18n/gender.cpp
@@ -98,7 +98,7 @@ const GenderInfo* GenderInfo::getInstance(const Locale& locale, UErrorCode& stat
return NULL;
}
- static UMutex gGenderMetaLock = U_MUTEX_INITIALIZER;
+ static UMutex gGenderMetaLock;
const GenderInfo* result = NULL;
const char* key = locale.getName();
{
diff --git a/deps/icu-small/source/i18n/gregocal.cpp b/deps/icu-small/source/i18n/gregocal.cpp
index 4db66758df..028ab05aa9 100644
--- a/deps/icu-small/source/i18n/gregocal.cpp
+++ b/deps/icu-small/source/i18n/gregocal.cpp
@@ -286,7 +286,7 @@ fIsGregorian(source.fIsGregorian), fInvertGregorian(source.fInvertGregorian)
// -------------------------------------
-Calendar* GregorianCalendar::clone() const
+GregorianCalendar* GregorianCalendar::clone() const
{
return new GregorianCalendar(*this);
}
@@ -324,26 +324,26 @@ GregorianCalendar::setGregorianChange(UDate date, UErrorCode& status)
if (U_FAILURE(status))
return;
- fGregorianCutover = date;
-
// Precompute two internal variables which we use to do the actual
// cutover computations. These are the normalized cutover, which is the
// midnight at or before the cutover, and the cutover year. The
// normalized cutover is in pure date milliseconds; it contains no time
// of day or timezone component, and it used to compare against other
// pure date values.
- int32_t cutoverDay = (int32_t)ClockMath::floorDivide(fGregorianCutover, (double)kOneDay);
- fNormalizedGregorianCutover = cutoverDay * kOneDay;
-
- // Handle the rare case of numeric overflow. If the user specifies a
- // change of UDate(Long.MIN_VALUE), in order to get a pure Gregorian
- // calendar, then the epoch day is -106751991168, which when multiplied
- // by ONE_DAY gives 9223372036794351616 -- the negative value is too
- // large for 64 bits, and overflows into a positive value. We correct
- // this by using the next day, which for all intents is semantically
- // equivalent.
- if (cutoverDay < 0 && fNormalizedGregorianCutover > 0) {
- fNormalizedGregorianCutover = (cutoverDay + 1) * kOneDay;
+ double cutoverDay = ClockMath::floorDivide(date, (double)kOneDay);
+
+ // Handle the rare case of numeric overflow where the user specifies a time
+ // outside of INT32_MIN .. INT32_MAX number of days.
+
+ if (cutoverDay <= INT32_MIN) {
+ cutoverDay = INT32_MIN;
+ fGregorianCutover = fNormalizedGregorianCutover = cutoverDay * kOneDay;
+ } else if (cutoverDay >= INT32_MAX) {
+ cutoverDay = INT32_MAX;
+ fGregorianCutover = fNormalizedGregorianCutover = cutoverDay * kOneDay;
+ } else {
+ fNormalizedGregorianCutover = cutoverDay * kOneDay;
+ fGregorianCutover = date;
}
// Normalize the year so BC values are represented as 0 and negative
@@ -360,7 +360,7 @@ GregorianCalendar::setGregorianChange(UDate date, UErrorCode& status)
fGregorianCutoverYear = cal->get(UCAL_YEAR, status);
if (cal->get(UCAL_ERA, status) == BC)
fGregorianCutoverYear = 1 - fGregorianCutoverYear;
- fCutoverJulianDay = cutoverDay;
+ fCutoverJulianDay = (int32_t)cutoverDay;
delete cal;
}
diff --git a/deps/icu-small/source/i18n/hebrwcal.cpp b/deps/icu-small/source/i18n/hebrwcal.cpp
index 66a3e47a4f..085ded7846 100644
--- a/deps/icu-small/source/i18n/hebrwcal.cpp
+++ b/deps/icu-small/source/i18n/hebrwcal.cpp
@@ -169,7 +169,7 @@ const char *HebrewCalendar::getType() const {
return "hebrew";
}
-Calendar* HebrewCalendar::clone() const {
+HebrewCalendar* HebrewCalendar::clone() const {
return new HebrewCalendar(*this);
}
diff --git a/deps/icu-small/source/i18n/hebrwcal.h b/deps/icu-small/source/i18n/hebrwcal.h
index 9323ad62aa..97e8511705 100644
--- a/deps/icu-small/source/i18n/hebrwcal.h
+++ b/deps/icu-small/source/i18n/hebrwcal.h
@@ -192,7 +192,7 @@ public:
* @return return a polymorphic copy of this calendar.
* @internal
*/
- virtual Calendar* clone(void) const;
+ virtual HebrewCalendar* clone() const;
public:
/**
diff --git a/deps/icu-small/source/i18n/indiancal.cpp b/deps/icu-small/source/i18n/indiancal.cpp
index 667b6f2d7a..f1266bb775 100644
--- a/deps/icu-small/source/i18n/indiancal.cpp
+++ b/deps/icu-small/source/i18n/indiancal.cpp
@@ -35,7 +35,7 @@ U_NAMESPACE_BEGIN
//-------------------------------------------------------------------------
-Calendar* IndianCalendar::clone() const {
+IndianCalendar* IndianCalendar::clone() const {
return new IndianCalendar(*this);
}
diff --git a/deps/icu-small/source/i18n/indiancal.h b/deps/icu-small/source/i18n/indiancal.h
index ffd4ae8b8a..142597ce0e 100644
--- a/deps/icu-small/source/i18n/indiancal.h
+++ b/deps/icu-small/source/i18n/indiancal.h
@@ -186,7 +186,7 @@ public:
// TODO: copy c'tor, etc
// clone
- virtual Calendar* clone() const;
+ virtual IndianCalendar* clone() const;
private:
/**
diff --git a/deps/icu-small/source/i18n/islamcal.cpp b/deps/icu-small/source/i18n/islamcal.cpp
index 8d6171af01..4e4a664804 100644
--- a/deps/icu-small/source/i18n/islamcal.cpp
+++ b/deps/icu-small/source/i18n/islamcal.cpp
@@ -227,7 +227,7 @@ const char *IslamicCalendar::getType() const {
return sType;
}
-Calendar* IslamicCalendar::clone() const {
+IslamicCalendar* IslamicCalendar::clone() const {
return new IslamicCalendar(*this);
}
@@ -470,7 +470,7 @@ double IslamicCalendar::moonAge(UDate time, UErrorCode &status)
{
double age = 0;
- static UMutex astroLock = U_MUTEX_INITIALIZER; // pod bay door lock
+ static UMutex astroLock; // pod bay door lock
umtx_lock(&astroLock);
if(gIslamicCalendarAstro == NULL) {
gIslamicCalendarAstro = new CalendarAstronomer();
diff --git a/deps/icu-small/source/i18n/islamcal.h b/deps/icu-small/source/i18n/islamcal.h
index 17fb6687ef..aad8f07be0 100644
--- a/deps/icu-small/source/i18n/islamcal.h
+++ b/deps/icu-small/source/i18n/islamcal.h
@@ -230,7 +230,7 @@ class U_I18N_API IslamicCalendar : public Calendar {
// TODO: copy c'tor, etc
// clone
- virtual Calendar* clone() const;
+ virtual IslamicCalendar* clone() const;
private:
/**
diff --git a/deps/icu-small/source/i18n/japancal.cpp b/deps/icu-small/source/i18n/japancal.cpp
index cc061fd141..e7e5f4fc51 100644
--- a/deps/icu-small/source/i18n/japancal.cpp
+++ b/deps/icu-small/source/i18n/japancal.cpp
@@ -136,7 +136,7 @@ JapaneseCalendar& JapaneseCalendar::operator= ( const JapaneseCalendar& right)
return *this;
}
-Calendar* JapaneseCalendar::clone(void) const
+JapaneseCalendar* JapaneseCalendar::clone() const
{
return new JapaneseCalendar(*this);
}
diff --git a/deps/icu-small/source/i18n/japancal.h b/deps/icu-small/source/i18n/japancal.h
index a32f3db563..ee86c4ed0e 100644
--- a/deps/icu-small/source/i18n/japancal.h
+++ b/deps/icu-small/source/i18n/japancal.h
@@ -116,7 +116,7 @@ public:
* @return return a polymorphic copy of this calendar.
* @internal
*/
- virtual Calendar* clone(void) const;
+ virtual JapaneseCalendar* clone() const;
/**
* Return the extended year defined by the current fields. In the
diff --git a/deps/icu-small/source/i18n/listformatter.cpp b/deps/icu-small/source/i18n/listformatter.cpp
index 64d2e36ae1..35cc00de25 100644
--- a/deps/icu-small/source/i18n/listformatter.cpp
+++ b/deps/icu-small/source/i18n/listformatter.cpp
@@ -144,7 +144,7 @@ const ListFormatInternal* ListFormatter::getListFormatInternal(
keyBuffer.append(':', errorCode).append(style, errorCode);
UnicodeString key(keyBuffer.data(), -1, US_INV);
ListFormatInternal* result = nullptr;
- static UMutex listFormatterMutex = U_MUTEX_INITIALIZER;
+ static UMutex listFormatterMutex;
{
Mutex m(&listFormatterMutex);
if (listPatternHash == nullptr) {
@@ -478,8 +478,8 @@ UnicodeString& ListFormatter::format_(
if (index == 0) {
offset = 0;
}
- int32_t offsetFirst;
- int32_t offsetSecond;
+ int32_t offsetFirst = 0;
+ int32_t offsetSecond = 0;
int32_t prefixLength = 0;
// for n items, there are 2 * (n + 1) boundary including 0 and the upper
// edge.
diff --git a/deps/icu-small/source/i18n/measfmt.cpp b/deps/icu-small/source/i18n/measfmt.cpp
index 03e4417e64..47ffb140cf 100644
--- a/deps/icu-small/source/i18n/measfmt.cpp
+++ b/deps/icu-small/source/i18n/measfmt.cpp
@@ -55,28 +55,23 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(MeasureFormat)
class NumericDateFormatters : public UMemory {
public:
// Formats like H:mm
- SimpleDateFormat hourMinute;
+ UnicodeString hourMinute;
// formats like M:ss
- SimpleDateFormat minuteSecond;
+ UnicodeString minuteSecond;
// formats like H:mm:ss
- SimpleDateFormat hourMinuteSecond;
+ UnicodeString hourMinuteSecond;
// Constructor that takes the actual patterns for hour-minute,
// minute-second, and hour-minute-second respectively.
NumericDateFormatters(
const UnicodeString &hm,
const UnicodeString &ms,
- const UnicodeString &hms,
- UErrorCode &status) :
- hourMinute(hm, status),
- minuteSecond(ms, status),
- hourMinuteSecond(hms, status) {
- const TimeZone *gmt = TimeZone::getGMT();
- hourMinute.setTimeZone(*gmt);
- minuteSecond.setTimeZone(*gmt);
- hourMinuteSecond.setTimeZone(*gmt);
+ const UnicodeString &hms) :
+ hourMinute(hm),
+ minuteSecond(ms),
+ hourMinuteSecond(hms) {
}
private:
NumericDateFormatters(const NumericDateFormatters &other);
@@ -233,8 +228,7 @@ static NumericDateFormatters *loadNumericDateFormatters(
NumericDateFormatters *result = new NumericDateFormatters(
loadNumericDateFormatterPattern(resource, "hm", status),
loadNumericDateFormatterPattern(resource, "ms", status),
- loadNumericDateFormatterPattern(resource, "hms", status),
- status);
+ loadNumericDateFormatterPattern(resource, "hms", status));
if (U_FAILURE(status)) {
delete result;
return NULL;
@@ -466,7 +460,7 @@ UBool MeasureFormat::operator==(const Format &other) const {
**numberFormat == **rhs.numberFormat);
}
-Format *MeasureFormat::clone() const {
+MeasureFormat *MeasureFormat::clone() const {
return new MeasureFormat(*this);
}
@@ -691,9 +685,19 @@ UnicodeString &MeasureFormat::formatMeasure(
}
auto* df = dynamic_cast<const DecimalFormat*>(&nf);
if (df == nullptr) {
- // Don't know how to handle other types of NumberFormat
- status = U_UNSUPPORTED_ERROR;
- return appendTo;
+ // Handle other types of NumberFormat using the ICU 63 code, modified to
+ // get the unitPattern from LongNameHandler and handle fallback to OTHER.
+ UnicodeString formattedNumber;
+ StandardPlural::Form pluralForm = QuantityFormatter::selectPlural(
+ amtNumber, nf, **pluralRules, formattedNumber, pos, status);
+ UnicodeString pattern = number::impl::LongNameHandler::getUnitPattern(getLocale(status),
+ amtUnit, getUnitWidth(fWidth), pluralForm, status);
+ // The above handles fallback from other widths to short, and from other plural forms to OTHER
+ if (U_FAILURE(status)) {
+ return appendTo;
+ }
+ SimpleFormatter formatter(pattern, 0, 1, status);
+ return QuantityFormatter::format(formatter, formattedNumber, appendTo, pos, status);
}
number::FormattedNumber result;
if (auto* lnf = df->toNumberFormatter(status)) {
@@ -706,135 +710,112 @@ UnicodeString &MeasureFormat::formatMeasure(
return appendTo;
}
-// Formats hours-minutes-seconds as 5:37:23 or similar.
+
+// Formats numeric time duration as 5:00:47 or 3:54.
UnicodeString &MeasureFormat::formatNumeric(
const Formattable *hms, // always length 3
- int32_t bitMap, // 1=hourset, 2=minuteset, 4=secondset
+ int32_t bitMap, // 1=hour set, 2=minute set, 4=second set
UnicodeString &appendTo,
UErrorCode &status) const {
if (U_FAILURE(status)) {
return appendTo;
}
- UDate millis =
- (UDate) (((uprv_trunc(hms[0].getDouble(status)) * 60.0
- + uprv_trunc(hms[1].getDouble(status))) * 60.0
- + uprv_trunc(hms[2].getDouble(status))) * 1000.0);
- switch (bitMap) {
- case 5: // hs
- case 7: // hms
- return formatNumeric(
- millis,
- cache->getNumericDateFormatters()->hourMinuteSecond,
- UDAT_SECOND_FIELD,
- hms[2],
- appendTo,
- status);
- break;
- case 6: // ms
- return formatNumeric(
- millis,
- cache->getNumericDateFormatters()->minuteSecond,
- UDAT_SECOND_FIELD,
- hms[2],
- appendTo,
- status);
- break;
- case 3: // hm
- return formatNumeric(
- millis,
- cache->getNumericDateFormatters()->hourMinute,
- UDAT_MINUTE_FIELD,
- hms[1],
- appendTo,
- status);
- break;
- default:
- status = U_INTERNAL_PROGRAM_ERROR;
- return appendTo;
- break;
- }
-}
-
-static void appendRange(
- const UnicodeString &src,
- int32_t start,
- int32_t end,
- UnicodeString &dest) {
- dest.append(src, start, end - start);
-}
-static void appendRange(
- const UnicodeString &src,
- int32_t end,
- UnicodeString &dest) {
- dest.append(src, end, src.length() - end);
-}
+ UnicodeString pattern;
-// Formats time like 5:37:23
-UnicodeString &MeasureFormat::formatNumeric(
- UDate date, // Time since epoch 1:30:00 would be 5400000
- const DateFormat &dateFmt, // h:mm, m:ss, or h:mm:ss
- UDateFormatField smallestField, // seconds in 5:37:23.5
- const Formattable &smallestAmount, // 23.5 for 5:37:23.5
- UnicodeString &appendTo,
- UErrorCode &status) const {
+ double hours = hms[0].getDouble(status);
+ double minutes = hms[1].getDouble(status);
+ double seconds = hms[2].getDouble(status);
if (U_FAILURE(status)) {
return appendTo;
}
- // Format the smallest amount with this object's NumberFormat
- UnicodeString smallestAmountFormatted;
-
- // We keep track of the integer part of smallest amount so that
- // we can replace it later so that we get '0:00:09.3' instead of
- // '0:00:9.3'
- FieldPosition intFieldPosition(UNUM_INTEGER_FIELD);
- (*numberFormat)->format(
- smallestAmount, smallestAmountFormatted, intFieldPosition, status);
- if (
- intFieldPosition.getBeginIndex() == 0 &&
- intFieldPosition.getEndIndex() == 0) {
+
+ // All possible combinations: "h", "m", "s", "hm", "hs", "ms", "hms"
+ if (bitMap == 5 || bitMap == 7) { // "hms" & "hs" (we add minutes if "hs")
+ pattern = cache->getNumericDateFormatters()->hourMinuteSecond;
+ hours = uprv_trunc(hours);
+ minutes = uprv_trunc(minutes);
+ } else if (bitMap == 3) { // "hm"
+ pattern = cache->getNumericDateFormatters()->hourMinute;
+ hours = uprv_trunc(hours);
+ } else if (bitMap == 6) { // "ms"
+ pattern = cache->getNumericDateFormatters()->minuteSecond;
+ minutes = uprv_trunc(minutes);
+ } else { // h m s, handled outside formatNumeric. No value is also an error.
status = U_INTERNAL_PROGRAM_ERROR;
return appendTo;
}
- // Format time. draft becomes something like '5:30:45'
- // #13606: DateFormat is not thread-safe, but MeasureFormat advertises itself as thread-safe.
- FieldPosition smallestFieldPosition(smallestField);
- UnicodeString draft;
- static UMutex dateFmtMutex = U_MUTEX_INITIALIZER;
- umtx_lock(&dateFmtMutex);
- dateFmt.format(date, draft, smallestFieldPosition, status);
- umtx_unlock(&dateFmtMutex);
-
- // If we find field for smallest amount replace it with the formatted
- // smallest amount from above taking care to replace the integer part
- // with what is in original time. For example, If smallest amount
- // is 9.35s and the formatted time is 0:00:09 then 9.35 becomes 09.35
- // and replacing yields 0:00:09.35
- if (smallestFieldPosition.getBeginIndex() != 0 ||
- smallestFieldPosition.getEndIndex() != 0) {
- appendRange(draft, 0, smallestFieldPosition.getBeginIndex(), appendTo);
- appendRange(
- smallestAmountFormatted,
- 0,
- intFieldPosition.getBeginIndex(),
- appendTo);
- appendRange(
- draft,
- smallestFieldPosition.getBeginIndex(),
- smallestFieldPosition.getEndIndex(),
- appendTo);
- appendRange(
- smallestAmountFormatted,
- intFieldPosition.getEndIndex(),
- appendTo);
- appendRange(
- draft,
- smallestFieldPosition.getEndIndex(),
- appendTo);
+ const DecimalFormat *numberFormatter = dynamic_cast<const DecimalFormat*>(numberFormat->get());
+ if (!numberFormatter) {
+ status = U_INTERNAL_PROGRAM_ERROR;
+ return appendTo;
+ }
+ number::LocalizedNumberFormatter numberFormatter2;
+ if (auto* lnf = numberFormatter->toNumberFormatter(status)) {
+ numberFormatter2 = lnf->integerWidth(number::IntegerWidth::zeroFillTo(2));
} else {
- appendTo.append(draft);
+ return appendTo;
}
+
+ FormattedStringBuilder fsb;
+
+ UBool protect = FALSE;
+ const int32_t patternLength = pattern.length();
+ for (int32_t i = 0; i < patternLength; i++) {
+ char16_t c = pattern[i];
+
+ // Also set the proper field in this switch
+ // We don't use DateFormat.Field because this is not a date / time, is a duration.
+ double value = 0;
+ switch (c) {
+ case u'H': value = hours; break;
+ case u'm': value = minutes; break;
+ case u's': value = seconds; break;
+ }
+
+ // For undefined field we use UNUM_FIELD_COUNT, for historical reasons.
+ // See cleanup bug: https://unicode-org.atlassian.net/browse/ICU-20665
+ // But we give it a clear name, to keep "the ugly part" in one place.
+ constexpr UNumberFormatFields undefinedField = UNUM_FIELD_COUNT;
+
+ // There is not enough info to add Field(s) for the unit because all we have are plain
+ // text patterns. For example in "21:51" there is no text for something like "hour",
+ // while in something like "21h51" there is ("h"). But we can't really tell...
+ switch (c) {
+ case u'H':
+ case u'm':
+ case u's':
+ if (protect) {
+ fsb.appendChar16(c, undefinedField, status);
+ } else {
+ UnicodeString tmp;
+ if ((i + 1 < patternLength) && pattern[i + 1] == c) { // doubled
+ tmp = numberFormatter2.formatDouble(value, status).toString(status);
+ i++;
+ } else {
+ numberFormatter->format(value, tmp, status);
+ }
+ // TODO: Use proper Field
+ fsb.append(tmp, undefinedField, status);
+ }
+ break;
+ case u'\'':
+ // '' is escaped apostrophe
+ if ((i + 1 < patternLength) && pattern[i + 1] == c) {
+ fsb.appendChar16(c, undefinedField, status);
+ i++;
+ } else {
+ protect = !protect;
+ }
+ break;
+ default:
+ fsb.appendChar16(c, undefinedField, status);
+ }
+ }
+
+ appendTo.append(fsb.toTempUnicodeString());
+
return appendTo;
}
diff --git a/deps/icu-small/source/i18n/measunit.cpp b/deps/icu-small/source/i18n/measunit.cpp
index 428283e6dd..917c0cdfad 100644
--- a/deps/icu-small/source/i18n/measunit.cpp
+++ b/deps/icu-small/source/i18n/measunit.cpp
@@ -43,21 +43,22 @@ static const int32_t gOffsets[] = {
29,
328,
339,
- 354,
- 358,
- 366,
+ 355,
+ 359,
368,
- 372,
- 393,
- 395,
- 409,
- 412,
+ 370,
+ 374,
+ 381,
+ 402,
+ 404,
418,
- 426,
- 430,
- 434,
- 436,
- 463
+ 421,
+ 427,
+ 437,
+ 441,
+ 445,
+ 447,
+ 474
};
static const int32_t gIndexes[] = {
@@ -69,21 +70,22 @@ static const int32_t gIndexes[] = {
29,
29,
40,
- 55,
- 59,
- 67,
+ 56,
+ 60,
69,
- 73,
- 94,
- 96,
- 110,
- 113,
+ 71,
+ 75,
+ 82,
+ 103,
+ 105,
119,
- 127,
- 131,
- 135,
- 137,
- 164
+ 122,
+ 128,
+ 138,
+ 142,
+ 146,
+ 148,
+ 175
};
// Must be sorted alphabetically.
@@ -100,6 +102,7 @@ static const char * const gTypes[] = {
"energy",
"force",
"frequency",
+ "graphics",
"length",
"light",
"mass",
@@ -456,6 +459,7 @@ static const char * const gSubTypes[] = {
"century",
"day",
"day-person",
+ "decade",
"hour",
"microsecond",
"millisecond",
@@ -480,12 +484,20 @@ static const char * const gSubTypes[] = {
"kilocalorie",
"kilojoule",
"kilowatt-hour",
+ "therm-us",
"newton",
"pound-force",
"gigahertz",
"hertz",
"kilohertz",
"megahertz",
+ "dot-per-centimeter",
+ "dot-per-inch",
+ "em",
+ "megapixel",
+ "pixel",
+ "pixel-per-centimeter",
+ "pixel-per-inch",
"astronomical-unit",
"centimeter",
"decimeter",
@@ -533,12 +545,14 @@ static const char * const gSubTypes[] = {
"milliwatt",
"watt",
"atmosphere",
+ "bar",
"hectopascal",
"inch-hg",
"kilopascal",
"megapascal",
"millibar",
"millimeter-of-mercury",
+ "pascal",
"pound-per-square-inch",
"kilometer-per-hour",
"knot",
@@ -581,18 +595,20 @@ static const char * const gSubTypes[] = {
// Must be sorted by first value and then second value.
static int32_t unitPerUnitToSingleUnit[][4] = {
- {379, 342, 18, 0},
- {381, 349, 18, 2},
- {383, 342, 18, 3},
- {383, 452, 4, 2},
- {383, 453, 4, 3},
- {402, 449, 3, 1},
- {405, 12, 17, 7},
- {455, 379, 4, 1}
+ {378, 382, 12, 5},
+ {378, 387, 12, 6},
+ {388, 343, 19, 0},
+ {390, 350, 19, 2},
+ {392, 343, 19, 3},
+ {392, 463, 4, 2},
+ {392, 464, 4, 3},
+ {411, 460, 3, 1},
+ {414, 12, 18, 9},
+ {466, 388, 4, 1}
};
// Shortcuts to the base unit in order to make the default constructor fast
-static const int32_t kBaseTypeIdx = 15;
+static const int32_t kBaseTypeIdx = 16;
static const int32_t kBaseSubTypeIdx = 0;
MeasureUnit *MeasureUnit::createGForce(UErrorCode &status) {
@@ -939,102 +955,110 @@ MeasureUnit MeasureUnit::getDayPerson() {
return MeasureUnit(7, 2);
}
-MeasureUnit *MeasureUnit::createHour(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createDecade(UErrorCode &status) {
return MeasureUnit::create(7, 3, status);
}
-MeasureUnit MeasureUnit::getHour() {
+MeasureUnit MeasureUnit::getDecade() {
return MeasureUnit(7, 3);
}
-MeasureUnit *MeasureUnit::createMicrosecond(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createHour(UErrorCode &status) {
return MeasureUnit::create(7, 4, status);
}
-MeasureUnit MeasureUnit::getMicrosecond() {
+MeasureUnit MeasureUnit::getHour() {
return MeasureUnit(7, 4);
}
-MeasureUnit *MeasureUnit::createMillisecond(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createMicrosecond(UErrorCode &status) {
return MeasureUnit::create(7, 5, status);
}
-MeasureUnit MeasureUnit::getMillisecond() {
+MeasureUnit MeasureUnit::getMicrosecond() {
return MeasureUnit(7, 5);
}
-MeasureUnit *MeasureUnit::createMinute(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createMillisecond(UErrorCode &status) {
return MeasureUnit::create(7, 6, status);
}
-MeasureUnit MeasureUnit::getMinute() {
+MeasureUnit MeasureUnit::getMillisecond() {
return MeasureUnit(7, 6);
}
-MeasureUnit *MeasureUnit::createMonth(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createMinute(UErrorCode &status) {
return MeasureUnit::create(7, 7, status);
}
-MeasureUnit MeasureUnit::getMonth() {
+MeasureUnit MeasureUnit::getMinute() {
return MeasureUnit(7, 7);
}
-MeasureUnit *MeasureUnit::createMonthPerson(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createMonth(UErrorCode &status) {
return MeasureUnit::create(7, 8, status);
}
-MeasureUnit MeasureUnit::getMonthPerson() {
+MeasureUnit MeasureUnit::getMonth() {
return MeasureUnit(7, 8);
}
-MeasureUnit *MeasureUnit::createNanosecond(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createMonthPerson(UErrorCode &status) {
return MeasureUnit::create(7, 9, status);
}
-MeasureUnit MeasureUnit::getNanosecond() {
+MeasureUnit MeasureUnit::getMonthPerson() {
return MeasureUnit(7, 9);
}
-MeasureUnit *MeasureUnit::createSecond(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createNanosecond(UErrorCode &status) {
return MeasureUnit::create(7, 10, status);
}
-MeasureUnit MeasureUnit::getSecond() {
+MeasureUnit MeasureUnit::getNanosecond() {
return MeasureUnit(7, 10);
}
-MeasureUnit *MeasureUnit::createWeek(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createSecond(UErrorCode &status) {
return MeasureUnit::create(7, 11, status);
}
-MeasureUnit MeasureUnit::getWeek() {
+MeasureUnit MeasureUnit::getSecond() {
return MeasureUnit(7, 11);
}
-MeasureUnit *MeasureUnit::createWeekPerson(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createWeek(UErrorCode &status) {
return MeasureUnit::create(7, 12, status);
}
-MeasureUnit MeasureUnit::getWeekPerson() {
+MeasureUnit MeasureUnit::getWeek() {
return MeasureUnit(7, 12);
}
-MeasureUnit *MeasureUnit::createYear(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createWeekPerson(UErrorCode &status) {
return MeasureUnit::create(7, 13, status);
}
-MeasureUnit MeasureUnit::getYear() {
+MeasureUnit MeasureUnit::getWeekPerson() {
return MeasureUnit(7, 13);
}
-MeasureUnit *MeasureUnit::createYearPerson(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createYear(UErrorCode &status) {
return MeasureUnit::create(7, 14, status);
}
-MeasureUnit MeasureUnit::getYearPerson() {
+MeasureUnit MeasureUnit::getYear() {
return MeasureUnit(7, 14);
}
+MeasureUnit *MeasureUnit::createYearPerson(UErrorCode &status) {
+ return MeasureUnit::create(7, 15, status);
+}
+
+MeasureUnit MeasureUnit::getYearPerson() {
+ return MeasureUnit(7, 15);
+}
+
MeasureUnit *MeasureUnit::createAmpere(UErrorCode &status) {
return MeasureUnit::create(8, 0, status);
}
@@ -1131,6 +1155,14 @@ MeasureUnit MeasureUnit::getKilowattHour() {
return MeasureUnit(9, 7);
}
+MeasureUnit *MeasureUnit::createThermUs(UErrorCode &status) {
+ return MeasureUnit::create(9, 8, status);
+}
+
+MeasureUnit MeasureUnit::getThermUs() {
+ return MeasureUnit(9, 8);
+}
+
MeasureUnit *MeasureUnit::createNewton(UErrorCode &status) {
return MeasureUnit::create(10, 0, status);
}
@@ -1179,708 +1211,780 @@ MeasureUnit MeasureUnit::getMegahertz() {
return MeasureUnit(11, 3);
}
-MeasureUnit *MeasureUnit::createAstronomicalUnit(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createDotPerCentimeter(UErrorCode &status) {
return MeasureUnit::create(12, 0, status);
}
-MeasureUnit MeasureUnit::getAstronomicalUnit() {
+MeasureUnit MeasureUnit::getDotPerCentimeter() {
return MeasureUnit(12, 0);
}
-MeasureUnit *MeasureUnit::createCentimeter(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createDotPerInch(UErrorCode &status) {
return MeasureUnit::create(12, 1, status);
}
-MeasureUnit MeasureUnit::getCentimeter() {
+MeasureUnit MeasureUnit::getDotPerInch() {
return MeasureUnit(12, 1);
}
-MeasureUnit *MeasureUnit::createDecimeter(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createEm(UErrorCode &status) {
return MeasureUnit::create(12, 2, status);
}
-MeasureUnit MeasureUnit::getDecimeter() {
+MeasureUnit MeasureUnit::getEm() {
return MeasureUnit(12, 2);
}
-MeasureUnit *MeasureUnit::createFathom(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createMegapixel(UErrorCode &status) {
return MeasureUnit::create(12, 3, status);
}
-MeasureUnit MeasureUnit::getFathom() {
+MeasureUnit MeasureUnit::getMegapixel() {
return MeasureUnit(12, 3);
}
-MeasureUnit *MeasureUnit::createFoot(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createPixel(UErrorCode &status) {
return MeasureUnit::create(12, 4, status);
}
-MeasureUnit MeasureUnit::getFoot() {
+MeasureUnit MeasureUnit::getPixel() {
return MeasureUnit(12, 4);
}
-MeasureUnit *MeasureUnit::createFurlong(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createPixelPerCentimeter(UErrorCode &status) {
return MeasureUnit::create(12, 5, status);
}
-MeasureUnit MeasureUnit::getFurlong() {
+MeasureUnit MeasureUnit::getPixelPerCentimeter() {
return MeasureUnit(12, 5);
}
-MeasureUnit *MeasureUnit::createInch(UErrorCode &status) {
+MeasureUnit *MeasureUnit::createPixelPerInch(UErrorCode &status) {
return MeasureUnit::create(12, 6, status);
}
-MeasureUnit MeasureUnit::getInch() {
+MeasureUnit MeasureUnit::getPixelPerInch() {
return MeasureUnit(12, 6);
}
+MeasureUnit *MeasureUnit::createAstronomicalUnit(UErrorCode &status) {
+ return MeasureUnit::create(13, 0, status);
+}
+
+MeasureUnit MeasureUnit::getAstronomicalUnit() {
+ return MeasureUnit(13, 0);
+}
+
+MeasureUnit *MeasureUnit::createCentimeter(UErrorCode &status) {
+ return MeasureUnit::create(13, 1, status);
+}
+
+MeasureUnit MeasureUnit::getCentimeter() {
+ return MeasureUnit(13, 1);
+}
+
+MeasureUnit *MeasureUnit::createDecimeter(UErrorCode &status) {
+ return MeasureUnit::create(13, 2, status);
+}
+
+MeasureUnit MeasureUnit::getDecimeter() {
+ return MeasureUnit(13, 2);
+}
+
+MeasureUnit *MeasureUnit::createFathom(UErrorCode &status) {
+ return MeasureUnit::create(13, 3, status);
+}
+
+MeasureUnit MeasureUnit::getFathom() {
+ return MeasureUnit(13, 3);
+}
+
+MeasureUnit *MeasureUnit::createFoot(UErrorCode &status) {
+ return MeasureUnit::create(13, 4, status);
+}
+
+MeasureUnit MeasureUnit::getFoot() {
+ return MeasureUnit(13, 4);
+}
+
+MeasureUnit *MeasureUnit::createFurlong(UErrorCode &status) {
+ return MeasureUnit::create(13, 5, status);
+}
+
+MeasureUnit MeasureUnit::getFurlong() {
+ return MeasureUnit(13, 5);
+}
+
+MeasureUnit *MeasureUnit::createInch(UErrorCode &status) {
+ return MeasureUnit::create(13, 6, status);
+}
+
+MeasureUnit MeasureUnit::getInch() {
+ return MeasureUnit(13, 6);
+}
+
MeasureUnit *MeasureUnit::createKilometer(UErrorCode &status) {
- return MeasureUnit::create(12, 7, status);
+ return MeasureUnit::create(13, 7, status);
}
MeasureUnit MeasureUnit::getKilometer() {
- return MeasureUnit(12, 7);
+ return MeasureUnit(13, 7);
}
MeasureUnit *MeasureUnit::createLightYear(UErrorCode &status) {
- return MeasureUnit::create(12, 8, status);
+ return MeasureUnit::create(13, 8, status);
}
MeasureUnit MeasureUnit::getLightYear() {
- return MeasureUnit(12, 8);
+ return MeasureUnit(13, 8);
}
MeasureUnit *MeasureUnit::createMeter(UErrorCode &status) {
- return MeasureUnit::create(12, 9, status);
+ return MeasureUnit::create(13, 9, status);
}
MeasureUnit MeasureUnit::getMeter() {
- return MeasureUnit(12, 9);
+ return MeasureUnit(13, 9);
}
MeasureUnit *MeasureUnit::createMicrometer(UErrorCode &status) {
- return MeasureUnit::create(12, 10, status);
+ return MeasureUnit::create(13, 10, status);
}
MeasureUnit MeasureUnit::getMicrometer() {
- return MeasureUnit(12, 10);
+ return MeasureUnit(13, 10);
}
MeasureUnit *MeasureUnit::createMile(UErrorCode &status) {
- return MeasureUnit::create(12, 11, status);
+ return MeasureUnit::create(13, 11, status);
}
MeasureUnit MeasureUnit::getMile() {
- return MeasureUnit(12, 11);
+ return MeasureUnit(13, 11);
}
MeasureUnit *MeasureUnit::createMileScandinavian(UErrorCode &status) {
- return MeasureUnit::create(12, 12, status);
+ return MeasureUnit::create(13, 12, status);
}
MeasureUnit MeasureUnit::getMileScandinavian() {
- return MeasureUnit(12, 12);
+ return MeasureUnit(13, 12);
}
MeasureUnit *MeasureUnit::createMillimeter(UErrorCode &status) {
- return MeasureUnit::create(12, 13, status);
+ return MeasureUnit::create(13, 13, status);
}
MeasureUnit MeasureUnit::getMillimeter() {
- return MeasureUnit(12, 13);
+ return MeasureUnit(13, 13);
}
MeasureUnit *MeasureUnit::createNanometer(UErrorCode &status) {
- return MeasureUnit::create(12, 14, status);
+ return MeasureUnit::create(13, 14, status);
}
MeasureUnit MeasureUnit::getNanometer() {
- return MeasureUnit(12, 14);
+ return MeasureUnit(13, 14);
}
MeasureUnit *MeasureUnit::createNauticalMile(UErrorCode &status) {
- return MeasureUnit::create(12, 15, status);
+ return MeasureUnit::create(13, 15, status);
}
MeasureUnit MeasureUnit::getNauticalMile() {
- return MeasureUnit(12, 15);
+ return MeasureUnit(13, 15);
}
MeasureUnit *MeasureUnit::createParsec(UErrorCode &status) {
- return MeasureUnit::create(12, 16, status);
+ return MeasureUnit::create(13, 16, status);
}
MeasureUnit MeasureUnit::getParsec() {
- return MeasureUnit(12, 16);
+ return MeasureUnit(13, 16);
}
MeasureUnit *MeasureUnit::createPicometer(UErrorCode &status) {
- return MeasureUnit::create(12, 17, status);
+ return MeasureUnit::create(13, 17, status);
}
MeasureUnit MeasureUnit::getPicometer() {
- return MeasureUnit(12, 17);
+ return MeasureUnit(13, 17);
}
MeasureUnit *MeasureUnit::createPoint(UErrorCode &status) {
- return MeasureUnit::create(12, 18, status);
+ return MeasureUnit::create(13, 18, status);
}
MeasureUnit MeasureUnit::getPoint() {
- return MeasureUnit(12, 18);
+ return MeasureUnit(13, 18);
}
MeasureUnit *MeasureUnit::createSolarRadius(UErrorCode &status) {
- return MeasureUnit::create(12, 19, status);
+ return MeasureUnit::create(13, 19, status);
}
MeasureUnit MeasureUnit::getSolarRadius() {
- return MeasureUnit(12, 19);
+ return MeasureUnit(13, 19);
}
MeasureUnit *MeasureUnit::createYard(UErrorCode &status) {
- return MeasureUnit::create(12, 20, status);
+ return MeasureUnit::create(13, 20, status);
}
MeasureUnit MeasureUnit::getYard() {
- return MeasureUnit(12, 20);
+ return MeasureUnit(13, 20);
}
MeasureUnit *MeasureUnit::createLux(UErrorCode &status) {
- return MeasureUnit::create(13, 0, status);
+ return MeasureUnit::create(14, 0, status);
}
MeasureUnit MeasureUnit::getLux() {
- return MeasureUnit(13, 0);
+ return MeasureUnit(14, 0);
}
MeasureUnit *MeasureUnit::createSolarLuminosity(UErrorCode &status) {
- return MeasureUnit::create(13, 1, status);
+ return MeasureUnit::create(14, 1, status);
}
MeasureUnit MeasureUnit::getSolarLuminosity() {
- return MeasureUnit(13, 1);
+ return MeasureUnit(14, 1);
}
MeasureUnit *MeasureUnit::createCarat(UErrorCode &status) {
- return MeasureUnit::create(14, 0, status);
+ return MeasureUnit::create(15, 0, status);
}
MeasureUnit MeasureUnit::getCarat() {
- return MeasureUnit(14, 0);
+ return MeasureUnit(15, 0);
}
MeasureUnit *MeasureUnit::createDalton(UErrorCode &status) {
- return MeasureUnit::create(14, 1, status);
+ return MeasureUnit::create(15, 1, status);
}
MeasureUnit MeasureUnit::getDalton() {
- return MeasureUnit(14, 1);
+ return MeasureUnit(15, 1);
}
MeasureUnit *MeasureUnit::createEarthMass(UErrorCode &status) {
- return MeasureUnit::create(14, 2, status);
+ return MeasureUnit::create(15, 2, status);
}
MeasureUnit MeasureUnit::getEarthMass() {
- return MeasureUnit(14, 2);
+ return MeasureUnit(15, 2);
}
MeasureUnit *MeasureUnit::createGram(UErrorCode &status) {
- return MeasureUnit::create(14, 3, status);
+ return MeasureUnit::create(15, 3, status);
}
MeasureUnit MeasureUnit::getGram() {
- return MeasureUnit(14, 3);
+ return MeasureUnit(15, 3);
}
MeasureUnit *MeasureUnit::createKilogram(UErrorCode &status) {
- return MeasureUnit::create(14, 4, status);
+ return MeasureUnit::create(15, 4, status);
}
MeasureUnit MeasureUnit::getKilogram() {
- return MeasureUnit(14, 4);
+ return MeasureUnit(15, 4);
}
MeasureUnit *MeasureUnit::createMetricTon(UErrorCode &status) {
- return MeasureUnit::create(14, 5, status);
+ return MeasureUnit::create(15, 5, status);
}
MeasureUnit MeasureUnit::getMetricTon() {
- return MeasureUnit(14, 5);
+ return MeasureUnit(15, 5);
}
MeasureUnit *MeasureUnit::createMicrogram(UErrorCode &status) {
- return MeasureUnit::create(14, 6, status);
+ return MeasureUnit::create(15, 6, status);
}
MeasureUnit MeasureUnit::getMicrogram() {
- return MeasureUnit(14, 6);
+ return MeasureUnit(15, 6);
}
MeasureUnit *MeasureUnit::createMilligram(UErrorCode &status) {
- return MeasureUnit::create(14, 7, status);
+ return MeasureUnit::create(15, 7, status);
}
MeasureUnit MeasureUnit::getMilligram() {
- return MeasureUnit(14, 7);
+ return MeasureUnit(15, 7);
}
MeasureUnit *MeasureUnit::createOunce(UErrorCode &status) {
- return MeasureUnit::create(14, 8, status);
+ return MeasureUnit::create(15, 8, status);
}
MeasureUnit MeasureUnit::getOunce() {
- return MeasureUnit(14, 8);
+ return MeasureUnit(15, 8);
}
MeasureUnit *MeasureUnit::createOunceTroy(UErrorCode &status) {
- return MeasureUnit::create(14, 9, status);
+ return MeasureUnit::create(15, 9, status);
}
MeasureUnit MeasureUnit::getOunceTroy() {
- return MeasureUnit(14, 9);
+ return MeasureUnit(15, 9);
}
MeasureUnit *MeasureUnit::createPound(UErrorCode &status) {
- return MeasureUnit::create(14, 10, status);
+ return MeasureUnit::create(15, 10, status);
}
MeasureUnit MeasureUnit::getPound() {
- return MeasureUnit(14, 10);
+ return MeasureUnit(15, 10);
}
MeasureUnit *MeasureUnit::createSolarMass(UErrorCode &status) {
- return MeasureUnit::create(14, 11, status);
+ return MeasureUnit::create(15, 11, status);
}
MeasureUnit MeasureUnit::getSolarMass() {
- return MeasureUnit(14, 11);
+ return MeasureUnit(15, 11);
}
MeasureUnit *MeasureUnit::createStone(UErrorCode &status) {
- return MeasureUnit::create(14, 12, status);
+ return MeasureUnit::create(15, 12, status);
}
MeasureUnit MeasureUnit::getStone() {
- return MeasureUnit(14, 12);
+ return MeasureUnit(15, 12);
}
MeasureUnit *MeasureUnit::createTon(UErrorCode &status) {
- return MeasureUnit::create(14, 13, status);
+ return MeasureUnit::create(15, 13, status);
}
MeasureUnit MeasureUnit::getTon() {
- return MeasureUnit(14, 13);
+ return MeasureUnit(15, 13);
}
MeasureUnit *MeasureUnit::createGigawatt(UErrorCode &status) {
- return MeasureUnit::create(16, 0, status);
+ return MeasureUnit::create(17, 0, status);
}
MeasureUnit MeasureUnit::getGigawatt() {
- return MeasureUnit(16, 0);
+ return MeasureUnit(17, 0);
}
MeasureUnit *MeasureUnit::createHorsepower(UErrorCode &status) {
- return MeasureUnit::create(16, 1, status);
+ return MeasureUnit::create(17, 1, status);
}
MeasureUnit MeasureUnit::getHorsepower() {
- return MeasureUnit(16, 1);
+ return MeasureUnit(17, 1);
}
MeasureUnit *MeasureUnit::createKilowatt(UErrorCode &status) {
- return MeasureUnit::create(16, 2, status);
+ return MeasureUnit::create(17, 2, status);
}
MeasureUnit MeasureUnit::getKilowatt() {
- return MeasureUnit(16, 2);
+ return MeasureUnit(17, 2);
}
MeasureUnit *MeasureUnit::createMegawatt(UErrorCode &status) {
- return MeasureUnit::create(16, 3, status);
+ return MeasureUnit::create(17, 3, status);
}
MeasureUnit MeasureUnit::getMegawatt() {
- return MeasureUnit(16, 3);
+ return MeasureUnit(17, 3);
}
MeasureUnit *MeasureUnit::createMilliwatt(UErrorCode &status) {
- return MeasureUnit::create(16, 4, status);
+ return MeasureUnit::create(17, 4, status);
}
MeasureUnit MeasureUnit::getMilliwatt() {
- return MeasureUnit(16, 4);
+ return MeasureUnit(17, 4);
}
MeasureUnit *MeasureUnit::createWatt(UErrorCode &status) {
- return MeasureUnit::create(16, 5, status);
+ return MeasureUnit::create(17, 5, status);
}
MeasureUnit MeasureUnit::getWatt() {
- return MeasureUnit(16, 5);
+ return MeasureUnit(17, 5);
}
MeasureUnit *MeasureUnit::createAtmosphere(UErrorCode &status) {
- return MeasureUnit::create(17, 0, status);
+ return MeasureUnit::create(18, 0, status);
}
MeasureUnit MeasureUnit::getAtmosphere() {
- return MeasureUnit(17, 0);
+ return MeasureUnit(18, 0);
+}
+
+MeasureUnit *MeasureUnit::createBar(UErrorCode &status) {
+ return MeasureUnit::create(18, 1, status);
+}
+
+MeasureUnit MeasureUnit::getBar() {
+ return MeasureUnit(18, 1);
}
MeasureUnit *MeasureUnit::createHectopascal(UErrorCode &status) {
- return MeasureUnit::create(17, 1, status);
+ return MeasureUnit::create(18, 2, status);
}
MeasureUnit MeasureUnit::getHectopascal() {
- return MeasureUnit(17, 1);
+ return MeasureUnit(18, 2);
}
MeasureUnit *MeasureUnit::createInchHg(UErrorCode &status) {
- return MeasureUnit::create(17, 2, status);
+ return MeasureUnit::create(18, 3, status);
}
MeasureUnit MeasureUnit::getInchHg() {
- return MeasureUnit(17, 2);
+ return MeasureUnit(18, 3);
}
MeasureUnit *MeasureUnit::createKilopascal(UErrorCode &status) {
- return MeasureUnit::create(17, 3, status);
+ return MeasureUnit::create(18, 4, status);
}
MeasureUnit MeasureUnit::getKilopascal() {
- return MeasureUnit(17, 3);
+ return MeasureUnit(18, 4);
}
MeasureUnit *MeasureUnit::createMegapascal(UErrorCode &status) {
- return MeasureUnit::create(17, 4, status);
+ return MeasureUnit::create(18, 5, status);
}
MeasureUnit MeasureUnit::getMegapascal() {
- return MeasureUnit(17, 4);
+ return MeasureUnit(18, 5);
}
MeasureUnit *MeasureUnit::createMillibar(UErrorCode &status) {
- return MeasureUnit::create(17, 5, status);
+ return MeasureUnit::create(18, 6, status);
}
MeasureUnit MeasureUnit::getMillibar() {
- return MeasureUnit(17, 5);
+ return MeasureUnit(18, 6);
}
MeasureUnit *MeasureUnit::createMillimeterOfMercury(UErrorCode &status) {
- return MeasureUnit::create(17, 6, status);
+ return MeasureUnit::create(18, 7, status);
}
MeasureUnit MeasureUnit::getMillimeterOfMercury() {
- return MeasureUnit(17, 6);
+ return MeasureUnit(18, 7);
+}
+
+MeasureUnit *MeasureUnit::createPascal(UErrorCode &status) {
+ return MeasureUnit::create(18, 8, status);
+}
+
+MeasureUnit MeasureUnit::getPascal() {
+ return MeasureUnit(18, 8);
}
MeasureUnit *MeasureUnit::createPoundPerSquareInch(UErrorCode &status) {
- return MeasureUnit::create(17, 7, status);
+ return MeasureUnit::create(18, 9, status);
}
MeasureUnit MeasureUnit::getPoundPerSquareInch() {
- return MeasureUnit(17, 7);
+ return MeasureUnit(18, 9);
}
MeasureUnit *MeasureUnit::createKilometerPerHour(UErrorCode &status) {
- return MeasureUnit::create(18, 0, status);
+ return MeasureUnit::create(19, 0, status);
}
MeasureUnit MeasureUnit::getKilometerPerHour() {
- return MeasureUnit(18, 0);
+ return MeasureUnit(19, 0);
}
MeasureUnit *MeasureUnit::createKnot(UErrorCode &status) {
- return MeasureUnit::create(18, 1, status);
+ return MeasureUnit::create(19, 1, status);
}
MeasureUnit MeasureUnit::getKnot() {
- return MeasureUnit(18, 1);
+ return MeasureUnit(19, 1);
}
MeasureUnit *MeasureUnit::createMeterPerSecond(UErrorCode &status) {
- return MeasureUnit::create(18, 2, status);
+ return MeasureUnit::create(19, 2, status);
}
MeasureUnit MeasureUnit::getMeterPerSecond() {
- return MeasureUnit(18, 2);
+ return MeasureUnit(19, 2);
}
MeasureUnit *MeasureUnit::createMilePerHour(UErrorCode &status) {
- return MeasureUnit::create(18, 3, status);
+ return MeasureUnit::create(19, 3, status);
}
MeasureUnit MeasureUnit::getMilePerHour() {
- return MeasureUnit(18, 3);
+ return MeasureUnit(19, 3);
}
MeasureUnit *MeasureUnit::createCelsius(UErrorCode &status) {
- return MeasureUnit::create(19, 0, status);
+ return MeasureUnit::create(20, 0, status);
}
MeasureUnit MeasureUnit::getCelsius() {
- return MeasureUnit(19, 0);
+ return MeasureUnit(20, 0);
}
MeasureUnit *MeasureUnit::createFahrenheit(UErrorCode &status) {
- return MeasureUnit::create(19, 1, status);
+ return MeasureUnit::create(20, 1, status);
}
MeasureUnit MeasureUnit::getFahrenheit() {
- return MeasureUnit(19, 1);
+ return MeasureUnit(20, 1);
}
MeasureUnit *MeasureUnit::createGenericTemperature(UErrorCode &status) {
- return MeasureUnit::create(19, 2, status);
+ return MeasureUnit::create(20, 2, status);
}
MeasureUnit MeasureUnit::getGenericTemperature() {
- return MeasureUnit(19, 2);
+ return MeasureUnit(20, 2);
}
MeasureUnit *MeasureUnit::createKelvin(UErrorCode &status) {
- return MeasureUnit::create(19, 3, status);
+ return MeasureUnit::create(20, 3, status);
}
MeasureUnit MeasureUnit::getKelvin() {
- return MeasureUnit(19, 3);
+ return MeasureUnit(20, 3);
}
MeasureUnit *MeasureUnit::createNewtonMeter(UErrorCode &status) {
- return MeasureUnit::create(20, 0, status);
+ return MeasureUnit::create(21, 0, status);
}
MeasureUnit MeasureUnit::getNewtonMeter() {
- return MeasureUnit(20, 0);
+ return MeasureUnit(21, 0);
}
MeasureUnit *MeasureUnit::createPoundFoot(UErrorCode &status) {
- return MeasureUnit::create(20, 1, status);
+ return MeasureUnit::create(21, 1, status);
}
MeasureUnit MeasureUnit::getPoundFoot() {
- return MeasureUnit(20, 1);
+ return MeasureUnit(21, 1);
}
MeasureUnit *MeasureUnit::createAcreFoot(UErrorCode &status) {
- return MeasureUnit::create(21, 0, status);
+ return MeasureUnit::create(22, 0, status);
}
MeasureUnit MeasureUnit::getAcreFoot() {
- return MeasureUnit(21, 0);
+ return MeasureUnit(22, 0);
}
MeasureUnit *MeasureUnit::createBarrel(UErrorCode &status) {
- return MeasureUnit::create(21, 1, status);
+ return MeasureUnit::create(22, 1, status);
}
MeasureUnit MeasureUnit::getBarrel() {
- return MeasureUnit(21, 1);
+ return MeasureUnit(22, 1);
}
MeasureUnit *MeasureUnit::createBushel(UErrorCode &status) {
- return MeasureUnit::create(21, 2, status);
+ return MeasureUnit::create(22, 2, status);
}
MeasureUnit MeasureUnit::getBushel() {
- return MeasureUnit(21, 2);
+ return MeasureUnit(22, 2);
}
MeasureUnit *MeasureUnit::createCentiliter(UErrorCode &status) {
- return MeasureUnit::create(21, 3, status);
+ return MeasureUnit::create(22, 3, status);
}
MeasureUnit MeasureUnit::getCentiliter() {
- return MeasureUnit(21, 3);
+ return MeasureUnit(22, 3);
}
MeasureUnit *MeasureUnit::createCubicCentimeter(UErrorCode &status) {
- return MeasureUnit::create(21, 4, status);
+ return MeasureUnit::create(22, 4, status);
}
MeasureUnit MeasureUnit::getCubicCentimeter() {
- return MeasureUnit(21, 4);
+ return MeasureUnit(22, 4);
}
MeasureUnit *MeasureUnit::createCubicFoot(UErrorCode &status) {
- return MeasureUnit::create(21, 5, status);
+ return MeasureUnit::create(22, 5, status);
}
MeasureUnit MeasureUnit::getCubicFoot() {
- return MeasureUnit(21, 5);
+ return MeasureUnit(22, 5);
}
MeasureUnit *MeasureUnit::createCubicInch(UErrorCode &status) {
- return MeasureUnit::create(21, 6, status);
+ return MeasureUnit::create(22, 6, status);
}
MeasureUnit MeasureUnit::getCubicInch() {
- return MeasureUnit(21, 6);
+ return MeasureUnit(22, 6);
}
MeasureUnit *MeasureUnit::createCubicKilometer(UErrorCode &status) {
- return MeasureUnit::create(21, 7, status);
+ return MeasureUnit::create(22, 7, status);
}
MeasureUnit MeasureUnit::getCubicKilometer() {
- return MeasureUnit(21, 7);
+ return MeasureUnit(22, 7);
}
MeasureUnit *MeasureUnit::createCubicMeter(UErrorCode &status) {
- return MeasureUnit::create(21, 8, status);
+ return MeasureUnit::create(22, 8, status);
}
MeasureUnit MeasureUnit::getCubicMeter() {
- return MeasureUnit(21, 8);
+ return MeasureUnit(22, 8);
}
MeasureUnit *MeasureUnit::createCubicMile(UErrorCode &status) {
- return MeasureUnit::create(21, 9, status);
+ return MeasureUnit::create(22, 9, status);
}
MeasureUnit MeasureUnit::getCubicMile() {
- return MeasureUnit(21, 9);
+ return MeasureUnit(22, 9);
}
MeasureUnit *MeasureUnit::createCubicYard(UErrorCode &status) {
- return MeasureUnit::create(21, 10, status);
+ return MeasureUnit::create(22, 10, status);
}
MeasureUnit MeasureUnit::getCubicYard() {
- return MeasureUnit(21, 10);
+ return MeasureUnit(22, 10);
}
MeasureUnit *MeasureUnit::createCup(UErrorCode &status) {
- return MeasureUnit::create(21, 11, status);
+ return MeasureUnit::create(22, 11, status);
}
MeasureUnit MeasureUnit::getCup() {
- return MeasureUnit(21, 11);
+ return MeasureUnit(22, 11);
}
MeasureUnit *MeasureUnit::createCupMetric(UErrorCode &status) {
- return MeasureUnit::create(21, 12, status);
+ return MeasureUnit::create(22, 12, status);
}
MeasureUnit MeasureUnit::getCupMetric() {
- return MeasureUnit(21, 12);
+ return MeasureUnit(22, 12);
}
MeasureUnit *MeasureUnit::createDeciliter(UErrorCode &status) {
- return MeasureUnit::create(21, 13, status);
+ return MeasureUnit::create(22, 13, status);
}
MeasureUnit MeasureUnit::getDeciliter() {
- return MeasureUnit(21, 13);
+ return MeasureUnit(22, 13);
}
MeasureUnit *MeasureUnit::createFluidOunce(UErrorCode &status) {
- return MeasureUnit::create(21, 14, status);
+ return MeasureUnit::create(22, 14, status);
}
MeasureUnit MeasureUnit::getFluidOunce() {
- return MeasureUnit(21, 14);
+ return MeasureUnit(22, 14);
}
MeasureUnit *MeasureUnit::createFluidOunceImperial(UErrorCode &status) {
- return MeasureUnit::create(21, 15, status);
+ return MeasureUnit::create(22, 15, status);
}
MeasureUnit MeasureUnit::getFluidOunceImperial() {
- return MeasureUnit(21, 15);
+ return MeasureUnit(22, 15);
}
MeasureUnit *MeasureUnit::createGallon(UErrorCode &status) {
- return MeasureUnit::create(21, 16, status);
+ return MeasureUnit::create(22, 16, status);
}
MeasureUnit MeasureUnit::getGallon() {
- return MeasureUnit(21, 16);
+ return MeasureUnit(22, 16);
}
MeasureUnit *MeasureUnit::createGallonImperial(UErrorCode &status) {
- return MeasureUnit::create(21, 17, status);
+ return MeasureUnit::create(22, 17, status);
}
MeasureUnit MeasureUnit::getGallonImperial() {
- return MeasureUnit(21, 17);
+ return MeasureUnit(22, 17);
}
MeasureUnit *MeasureUnit::createHectoliter(UErrorCode &status) {
- return MeasureUnit::create(21, 18, status);
+ return MeasureUnit::create(22, 18, status);
}
MeasureUnit MeasureUnit::getHectoliter() {
- return MeasureUnit(21, 18);
+ return MeasureUnit(22, 18);
}
MeasureUnit *MeasureUnit::createLiter(UErrorCode &status) {
- return MeasureUnit::create(21, 19, status);
+ return MeasureUnit::create(22, 19, status);
}
MeasureUnit MeasureUnit::getLiter() {
- return MeasureUnit(21, 19);
+ return MeasureUnit(22, 19);
}
MeasureUnit *MeasureUnit::createMegaliter(UErrorCode &status) {
- return MeasureUnit::create(21, 20, status);
+ return MeasureUnit::create(22, 20, status);
}
MeasureUnit MeasureUnit::getMegaliter() {
- return MeasureUnit(21, 20);
+ return MeasureUnit(22, 20);
}
MeasureUnit *MeasureUnit::createMilliliter(UErrorCode &status) {
- return MeasureUnit::create(21, 21, status);
+ return MeasureUnit::create(22, 21, status);
}
MeasureUnit MeasureUnit::getMilliliter() {
- return MeasureUnit(21, 21);
+ return MeasureUnit(22, 21);
}
MeasureUnit *MeasureUnit::createPint(UErrorCode &status) {
- return MeasureUnit::create(21, 22, status);
+ return MeasureUnit::create(22, 22, status);
}
MeasureUnit MeasureUnit::getPint() {
- return MeasureUnit(21, 22);
+ return MeasureUnit(22, 22);
}
MeasureUnit *MeasureUnit::createPintMetric(UErrorCode &status) {
- return MeasureUnit::create(21, 23, status);
+ return MeasureUnit::create(22, 23, status);
}
MeasureUnit MeasureUnit::getPintMetric() {
- return MeasureUnit(21, 23);
+ return MeasureUnit(22, 23);
}
MeasureUnit *MeasureUnit::createQuart(UErrorCode &status) {
- return MeasureUnit::create(21, 24, status);
+ return MeasureUnit::create(22, 24, status);
}
MeasureUnit MeasureUnit::getQuart() {
- return MeasureUnit(21, 24);
+ return MeasureUnit(22, 24);
}
MeasureUnit *MeasureUnit::createTablespoon(UErrorCode &status) {
- return MeasureUnit::create(21, 25, status);
+ return MeasureUnit::create(22, 25, status);
}
MeasureUnit MeasureUnit::getTablespoon() {
- return MeasureUnit(21, 25);
+ return MeasureUnit(22, 25);
}
MeasureUnit *MeasureUnit::createTeaspoon(UErrorCode &status) {
- return MeasureUnit::create(21, 26, status);
+ return MeasureUnit::create(22, 26, status);
}
MeasureUnit MeasureUnit::getTeaspoon() {
- return MeasureUnit(21, 26);
+ return MeasureUnit(22, 26);
}
// End generated code
@@ -1923,7 +2027,7 @@ MeasureUnit &MeasureUnit::operator=(const MeasureUnit &other) {
return *this;
}
-UObject *MeasureUnit::clone() const {
+MeasureUnit *MeasureUnit::clone() const {
return new MeasureUnit(*this);
}
diff --git a/deps/icu-small/source/i18n/measure.cpp b/deps/icu-small/source/i18n/measure.cpp
index d9084f87db..bffa44215e 100644
--- a/deps/icu-small/source/i18n/measure.cpp
+++ b/deps/icu-small/source/i18n/measure.cpp
@@ -43,12 +43,12 @@ Measure& Measure::operator=(const Measure& other) {
if (this != &other) {
delete unit;
number = other.number;
- unit = (MeasureUnit*) other.unit->clone();
+ unit = other.unit->clone();
}
return *this;
}
-UObject *Measure::clone() const {
+Measure *Measure::clone() const {
return new Measure(*this);
}
diff --git a/deps/icu-small/source/i18n/msgfmt.cpp b/deps/icu-small/source/i18n/msgfmt.cpp
index e39b26b969..3ca368ef95 100644
--- a/deps/icu-small/source/i18n/msgfmt.cpp
+++ b/deps/icu-small/source/i18n/msgfmt.cpp
@@ -436,7 +436,7 @@ MessageFormat::operator==(const Format& rhs) const
// -------------------------------------
// Creates a copy of this MessageFormat, the caller owns the copy.
-Format*
+MessageFormat*
MessageFormat::clone() const
{
return new MessageFormat(*this);
@@ -813,7 +813,7 @@ MessageFormat::getFormats(int32_t& cnt) const
// Get total required capacity first (it's refreshed on each call).
int32_t totalCapacity = 0;
- for (int32_t partIndex = 0; (partIndex = nextTopLevelArgStart(partIndex)) >= 0; ++totalCapacity) {};
+ for (int32_t partIndex = 0; (partIndex = nextTopLevelArgStart(partIndex)) >= 0; ++totalCapacity) {}
MessageFormat* t = const_cast<MessageFormat*> (this);
cnt = 0;
@@ -1873,7 +1873,7 @@ UBool MessageFormat::DummyFormat::operator==(const Format&) const {
return TRUE;
}
-Format* MessageFormat::DummyFormat::clone() const {
+MessageFormat::DummyFormat* MessageFormat::DummyFormat::clone() const {
return new DummyFormat();
}
diff --git a/deps/icu-small/source/i18n/name2uni.cpp b/deps/icu-small/source/i18n/name2uni.cpp
index d901eb126a..90bca9d71b 100644
--- a/deps/icu-small/source/i18n/name2uni.cpp
+++ b/deps/icu-small/source/i18n/name2uni.cpp
@@ -100,7 +100,7 @@ NameUnicodeTransliterator::NameUnicodeTransliterator(const NameUnicodeTransliter
/**
* Transliterator API.
*/
-Transliterator* NameUnicodeTransliterator::clone(void) const {
+NameUnicodeTransliterator* NameUnicodeTransliterator::clone() const {
return new NameUnicodeTransliterator(*this);
}
diff --git a/deps/icu-small/source/i18n/name2uni.h b/deps/icu-small/source/i18n/name2uni.h
index 4c743def32..44ad85fb82 100644
--- a/deps/icu-small/source/i18n/name2uni.h
+++ b/deps/icu-small/source/i18n/name2uni.h
@@ -49,7 +49,7 @@ public:
* Transliterator API.
* @return A copy of the object.
*/
- virtual Transliterator* clone(void) const;
+ virtual NameUnicodeTransliterator* clone() const;
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
diff --git a/deps/icu-small/source/i18n/nortrans.cpp b/deps/icu-small/source/i18n/nortrans.cpp
index 589c82482e..6a8d2c7419 100644
--- a/deps/icu-small/source/i18n/nortrans.cpp
+++ b/deps/icu-small/source/i18n/nortrans.cpp
@@ -92,7 +92,7 @@ NormalizationTransliterator::NormalizationTransliterator(const NormalizationTran
/**
* Transliterator API.
*/
-Transliterator* NormalizationTransliterator::clone(void) const {
+NormalizationTransliterator* NormalizationTransliterator::clone() const {
return new NormalizationTransliterator(*this);
}
diff --git a/deps/icu-small/source/i18n/nortrans.h b/deps/icu-small/source/i18n/nortrans.h
index d309452f9a..198ed29c95 100644
--- a/deps/icu-small/source/i18n/nortrans.h
+++ b/deps/icu-small/source/i18n/nortrans.h
@@ -44,7 +44,7 @@ class NormalizationTransliterator : public Transliterator {
* Transliterator API.
* @return A copy of the object.
*/
- virtual Transliterator* clone(void) const;
+ virtual NormalizationTransliterator* clone() const;
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
diff --git a/deps/icu-small/source/i18n/nounit.cpp b/deps/icu-small/source/i18n/nounit.cpp
index db07387c59..076f76f199 100644
--- a/deps/icu-small/source/i18n/nounit.cpp
+++ b/deps/icu-small/source/i18n/nounit.cpp
@@ -29,7 +29,7 @@ NoUnit::NoUnit(const char* subtype) {
NoUnit::NoUnit(const NoUnit& other) : MeasureUnit(other) {
}
-UObject* NoUnit::clone() const {
+NoUnit* NoUnit::clone() const {
return new NoUnit(*this);
}
diff --git a/deps/icu-small/source/i18n/nultrans.cpp b/deps/icu-small/source/i18n/nultrans.cpp
index 62d1290ac7..439cc55d38 100644
--- a/deps/icu-small/source/i18n/nultrans.cpp
+++ b/deps/icu-small/source/i18n/nultrans.cpp
@@ -24,7 +24,7 @@ NullTransliterator::NullTransliterator() : Transliterator(UNICODE_STRING_SIMPLE(
NullTransliterator::~NullTransliterator() {}
-Transliterator* NullTransliterator::clone(void) const {
+NullTransliterator* NullTransliterator::clone() const {
return new NullTransliterator();
}
diff --git a/deps/icu-small/source/i18n/nultrans.h b/deps/icu-small/source/i18n/nultrans.h
index a01b04e9ba..36c92fa7b1 100644
--- a/deps/icu-small/source/i18n/nultrans.h
+++ b/deps/icu-small/source/i18n/nultrans.h
@@ -45,7 +45,7 @@ public:
* Transliterator API.
* @internal Use transliterator factory methods instead since this class will be removed in that release.
*/
- virtual Transliterator* clone(void) const;
+ virtual NullTransliterator* clone() const;
/**
* Implements {@link Transliterator#handleTransliterate}.
diff --git a/deps/icu-small/source/i18n/number_affixutils.cpp b/deps/icu-small/source/i18n/number_affixutils.cpp
index 3eb9c59bf4..1039a84c65 100644
--- a/deps/icu-small/source/i18n/number_affixutils.cpp
+++ b/deps/icu-small/source/i18n/number_affixutils.cpp
@@ -156,7 +156,7 @@ Field AffixUtils::getFieldForType(AffixPatternType type) {
}
int32_t
-AffixUtils::unescape(const UnicodeString &affixPattern, NumberStringBuilder &output, int32_t position,
+AffixUtils::unescape(const UnicodeString &affixPattern, FormattedStringBuilder &output, int32_t position,
const SymbolProvider &provider, Field field, UErrorCode &status) {
int32_t length = 0;
AffixTag tag;
@@ -230,7 +230,7 @@ UnicodeString AffixUtils::replaceType(const UnicodeString &affixPattern, AffixPa
UnicodeString output(affixPattern); // copy
if (affixPattern.length() == 0) {
return output;
- };
+ }
AffixTag tag;
while (hasNext(tag, affixPattern)) {
tag = nextToken(tag, affixPattern, status);
@@ -246,7 +246,7 @@ bool AffixUtils::containsOnlySymbolsAndIgnorables(const UnicodeString& affixPatt
const UnicodeSet& ignorables, UErrorCode& status) {
if (affixPattern.length() == 0) {
return true;
- };
+ }
AffixTag tag;
while (hasNext(tag, affixPattern)) {
tag = nextToken(tag, affixPattern, status);
@@ -262,7 +262,7 @@ void AffixUtils::iterateWithConsumer(const UnicodeString& affixPattern, TokenCon
UErrorCode& status) {
if (affixPattern.length() == 0) {
return;
- };
+ }
AffixTag tag;
while (hasNext(tag, affixPattern)) {
tag = nextToken(tag, affixPattern, status);
diff --git a/deps/icu-small/source/i18n/number_affixutils.h b/deps/icu-small/source/i18n/number_affixutils.h
index f011a54b31..5cfde61ffd 100644
--- a/deps/icu-small/source/i18n/number_affixutils.h
+++ b/deps/icu-small/source/i18n/number_affixutils.h
@@ -11,7 +11,7 @@
#include "number_types.h"
#include "unicode/stringpiece.h"
#include "unicode/unistr.h"
-#include "number_stringbuilder.h"
+#include "formatted_string_builder.h"
#include "unicode/uniset.h"
U_NAMESPACE_BEGIN namespace number {
@@ -134,16 +134,16 @@ class U_I18N_API AffixUtils {
/**
* Executes the unescape state machine. Replaces the unquoted characters "-", "+", "%", "‰", and
* "¤" with the corresponding symbols provided by the {@link SymbolProvider}, and inserts the
- * result into the NumberStringBuilder at the requested location.
+ * result into the FormattedStringBuilder at the requested location.
*
* <p>Example input: "'-'¤x"; example output: "-$x"
*
* @param affixPattern The original string to be unescaped.
- * @param output The NumberStringBuilder to mutate with the result.
- * @param position The index into the NumberStringBuilder to insert the string.
+ * @param output The FormattedStringBuilder to mutate with the result.
+ * @param position The index into the FormattedStringBuilder to insert the string.
* @param provider An object to generate locale symbols.
*/
- static int32_t unescape(const UnicodeString& affixPattern, NumberStringBuilder& output,
+ static int32_t unescape(const UnicodeString& affixPattern, FormattedStringBuilder& output,
int32_t position, const SymbolProvider& provider, Field field,
UErrorCode& status);
diff --git a/deps/icu-small/source/i18n/number_asformat.cpp b/deps/icu-small/source/i18n/number_asformat.cpp
index 9d3ea69f57..e876174fdc 100644
--- a/deps/icu-small/source/i18n/number_asformat.cpp
+++ b/deps/icu-small/source/i18n/number_asformat.cpp
@@ -43,7 +43,7 @@ UBool LocalizedNumberFormatterAsFormat::operator==(const Format& other) const {
return fFormatter.toSkeleton(localStatus) == _other->fFormatter.toSkeleton(localStatus);
}
-Format* LocalizedNumberFormatterAsFormat::clone() const {
+LocalizedNumberFormatterAsFormat* LocalizedNumberFormatterAsFormat::clone() const {
return new LocalizedNumberFormatterAsFormat(*this);
}
@@ -62,12 +62,12 @@ UnicodeString& LocalizedNumberFormatterAsFormat::format(const Formattable& obj,
// always return first occurrence:
pos.setBeginIndex(0);
pos.setEndIndex(0);
- bool found = data.getStringRef().nextFieldPosition(pos, status);
+ bool found = data.nextFieldPosition(pos, status);
if (found && appendTo.length() != 0) {
pos.setBeginIndex(pos.getBeginIndex() + appendTo.length());
pos.setEndIndex(pos.getEndIndex() + appendTo.length());
}
- appendTo.append(data.getStringRef().toTempUnicodeString());
+ appendTo.append(data.toTempString(status));
return appendTo;
}
@@ -84,10 +84,10 @@ UnicodeString& LocalizedNumberFormatterAsFormat::format(const Formattable& obj,
if (U_FAILURE(status)) {
return appendTo;
}
- appendTo.append(data.getStringRef().toTempUnicodeString());
+ appendTo.append(data.toTempString(status));
if (posIter != nullptr) {
FieldPositionIteratorHandler fpih(posIter, status);
- data.getStringRef().getAllFieldPositions(fpih, status);
+ data.getAllFieldPositions(fpih, status);
}
return appendTo;
}
diff --git a/deps/icu-small/source/i18n/number_asformat.h b/deps/icu-small/source/i18n/number_asformat.h
index bf82d72ae3..7b0a1dee6f 100644
--- a/deps/icu-small/source/i18n/number_asformat.h
+++ b/deps/icu-small/source/i18n/number_asformat.h
@@ -45,7 +45,7 @@ class U_I18N_API LocalizedNumberFormatterAsFormat : public Format {
/**
* Creates a copy of this object.
*/
- Format* clone() const U_OVERRIDE;
+ LocalizedNumberFormatterAsFormat* clone() const U_OVERRIDE;
/**
* Formats a Number using the wrapped LocalizedNumberFormatter. The provided formattable must be a
diff --git a/deps/icu-small/source/i18n/number_compact.cpp b/deps/icu-small/source/i18n/number_compact.cpp
index f330251be3..3d259999d6 100644
--- a/deps/icu-small/source/i18n/number_compact.cpp
+++ b/deps/icu-small/source/i18n/number_compact.cpp
@@ -272,15 +272,15 @@ void CompactHandler::processQuantity(DecimalQuantity &quantity, MicroProps &micr
parent->processQuantity(quantity, micros, status);
if (U_FAILURE(status)) { return; }
- // Treat zero as if it had magnitude 0
+ // Treat zero, NaN, and infinity as if they had magnitude 0
int32_t magnitude;
- if (quantity.isZero()) {
+ if (quantity.isZeroish()) {
magnitude = 0;
micros.rounder.apply(quantity, status);
} else {
// TODO: Revisit chooseMultiplierAndApply
int32_t multiplier = micros.rounder.chooseMultiplierAndApply(quantity, data, status);
- magnitude = quantity.isZero() ? 0 : quantity.getMagnitude();
+ magnitude = quantity.isZeroish() ? 0 : quantity.getMagnitude();
magnitude -= multiplier;
}
diff --git a/deps/icu-small/source/i18n/number_currencysymbols.cpp b/deps/icu-small/source/i18n/number_currencysymbols.cpp
index 0b79d6596f..4d6fb2cb1d 100644
--- a/deps/icu-small/source/i18n/number_currencysymbols.cpp
+++ b/deps/icu-small/source/i18n/number_currencysymbols.cpp
@@ -53,13 +53,12 @@ UnicodeString CurrencySymbols::getCurrencySymbol(UErrorCode& status) const {
UnicodeString CurrencySymbols::loadSymbol(UCurrNameStyle selector, UErrorCode& status) const {
const char16_t* isoCode = fCurrency.getISOCurrency();
- UBool ignoredIsChoiceFormatFillIn = FALSE;
int32_t symbolLen = 0;
const char16_t* symbol = ucurr_getName(
isoCode,
fLocaleName.data(),
selector,
- &ignoredIsChoiceFormatFillIn,
+ nullptr /* isChoiceFormat */,
&symbolLen,
&status);
// If given an unknown currency, ucurr_getName returns the input string, which we can't alias safely!
@@ -82,12 +81,11 @@ UnicodeString CurrencySymbols::getIntlCurrencySymbol(UErrorCode&) const {
UnicodeString CurrencySymbols::getPluralName(StandardPlural::Form plural, UErrorCode& status) const {
const char16_t* isoCode = fCurrency.getISOCurrency();
- UBool isChoiceFormat = FALSE;
int32_t symbolLen = 0;
const char16_t* symbol = ucurr_getPluralName(
isoCode,
fLocaleName.data(),
- &isChoiceFormat,
+ nullptr /* isChoiceFormat */,
StandardPlural::getKeyword(plural),
&symbolLen,
&status);
diff --git a/deps/icu-small/source/i18n/number_decimalquantity.cpp b/deps/icu-small/source/i18n/number_decimalquantity.cpp
index d899c27671..2c4c2ce7e9 100644
--- a/deps/icu-small/source/i18n/number_decimalquantity.cpp
+++ b/deps/icu-small/source/i18n/number_decimalquantity.cpp
@@ -205,7 +205,7 @@ void DecimalQuantity::roundToIncrement(double roundingIncrement, RoundingMode ro
}
void DecimalQuantity::multiplyBy(const DecNum& multiplicand, UErrorCode& status) {
- if (isInfinite() || isZero() || isNaN()) {
+ if (isZeroish()) {
return;
}
// Convert to DecNum, multiply, and convert back.
@@ -218,7 +218,7 @@ void DecimalQuantity::multiplyBy(const DecNum& multiplicand, UErrorCode& status)
}
void DecimalQuantity::divideBy(const DecNum& divisor, UErrorCode& status) {
- if (isInfinite() || isZero() || isNaN()) {
+ if (isZeroish()) {
return;
}
// Convert to DecNum, multiply, and convert back.
@@ -318,8 +318,14 @@ bool DecimalQuantity::isNegative() const {
return (flags & NEGATIVE_FLAG) != 0;
}
-int8_t DecimalQuantity::signum() const {
- return isNegative() ? -1 : isZero() ? 0 : 1;
+Signum DecimalQuantity::signum() const {
+ if (isNegative()) {
+ return SIGNUM_NEG;
+ } else if (isZeroish() && !isInfinite()) {
+ return SIGNUM_ZERO;
+ } else {
+ return SIGNUM_POS;
+ }
}
bool DecimalQuantity::isInfinite() const {
@@ -330,7 +336,7 @@ bool DecimalQuantity::isNaN() const {
return (flags & NAN_FLAG) != 0;
}
-bool DecimalQuantity::isZero() const {
+bool DecimalQuantity::isZeroish() const {
return precision == 0;
}
@@ -548,7 +554,10 @@ uint64_t DecimalQuantity::toFractionLong(bool includeTrailingZeros) const {
}
bool DecimalQuantity::fitsInLong(bool ignoreFraction) const {
- if (isZero()) {
+ if (isInfinite() || isNaN()) {
+ return false;
+ }
+ if (isZeroish()) {
return true;
}
if (scale < 0 && !ignoreFraction) {
diff --git a/deps/icu-small/source/i18n/number_decimalquantity.h b/deps/icu-small/source/i18n/number_decimalquantity.h
index 06cc836c77..4ec6c5a5b2 100644
--- a/deps/icu-small/source/i18n/number_decimalquantity.h
+++ b/deps/icu-small/source/i18n/number_decimalquantity.h
@@ -146,14 +146,17 @@ class U_I18N_API DecimalQuantity : public IFixedDecimal, public UMemory {
*/
int32_t getMagnitude() const;
- /** @return Whether the value represented by this {@link DecimalQuantity} is zero. */
- bool isZero() const;
+ /**
+ * @return Whether the value represented by this {@link DecimalQuantity} is
+ * zero, infinity, or NaN.
+ */
+ bool isZeroish() const;
/** @return Whether the value represented by this {@link DecimalQuantity} is less than zero. */
bool isNegative() const;
- /** @return -1 if the value is negative; 1 if positive; or 0 if zero. */
- int8_t signum() const;
+ /** @return The appropriate value from the Signum enum. */
+ Signum signum() const;
/** @return Whether the value represented by this {@link DecimalQuantity} is infinite. */
bool isInfinite() const U_OVERRIDE;
diff --git a/deps/icu-small/source/i18n/number_decnum.h b/deps/icu-small/source/i18n/number_decnum.h
index a7793470b5..0c7399dbdd 100644
--- a/deps/icu-small/source/i18n/number_decnum.h
+++ b/deps/icu-small/source/i18n/number_decnum.h
@@ -55,6 +55,8 @@ class U_I18N_API DecNum : public UMemory {
bool isZero() const;
+ void toString(ByteSink& output, UErrorCode& status) const;
+
inline const decNumber* getRawDecNumber() const {
return fData.getAlias();
}
diff --git a/deps/icu-small/source/i18n/number_fluent.cpp b/deps/icu-small/source/i18n/number_fluent.cpp
index 09e0905609..2dbd2fa6cd 100644
--- a/deps/icu-small/source/i18n/number_fluent.cpp
+++ b/deps/icu-small/source/i18n/number_fluent.cpp
@@ -696,8 +696,8 @@ void LocalizedNumberFormatter::formatImpl(impl::UFormattedNumberData* results, U
void LocalizedNumberFormatter::getAffixImpl(bool isPrefix, bool isNegative, UnicodeString& result,
UErrorCode& status) const {
- NumberStringBuilder string;
- auto signum = static_cast<int8_t>(isNegative ? -1 : 1);
+ FormattedStringBuilder string;
+ auto signum = static_cast<Signum>(isNegative ? SIGNUM_NEG : SIGNUM_POS);
// Always return affixes for plural form OTHER.
static const StandardPlural::Form plural = StandardPlural::OTHER;
int32_t prefixLength;
diff --git a/deps/icu-small/source/i18n/number_formatimpl.cpp b/deps/icu-small/source/i18n/number_formatimpl.cpp
index 08b833beb7..2e2c4a9620 100644
--- a/deps/icu-small/source/i18n/number_formatimpl.cpp
+++ b/deps/icu-small/source/i18n/number_formatimpl.cpp
@@ -72,7 +72,7 @@ NumberFormatterImpl::NumberFormatterImpl(const MacroProps& macros, UErrorCode& s
}
int32_t NumberFormatterImpl::formatStatic(const MacroProps& macros, DecimalQuantity& inValue,
- NumberStringBuilder& outString, UErrorCode& status) {
+ FormattedStringBuilder& outString, UErrorCode& status) {
NumberFormatterImpl impl(macros, false, status);
MicroProps& micros = impl.preProcessUnsafe(inValue, status);
if (U_FAILURE(status)) { return 0; }
@@ -81,9 +81,9 @@ int32_t NumberFormatterImpl::formatStatic(const MacroProps& macros, DecimalQuant
return length;
}
-int32_t NumberFormatterImpl::getPrefixSuffixStatic(const MacroProps& macros, int8_t signum,
+int32_t NumberFormatterImpl::getPrefixSuffixStatic(const MacroProps& macros, Signum signum,
StandardPlural::Form plural,
- NumberStringBuilder& outString, UErrorCode& status) {
+ FormattedStringBuilder& outString, UErrorCode& status) {
NumberFormatterImpl impl(macros, false, status);
return impl.getPrefixSuffixUnsafe(signum, plural, outString, status);
}
@@ -93,7 +93,7 @@ int32_t NumberFormatterImpl::getPrefixSuffixStatic(const MacroProps& macros, int
// The "unsafe" method simply re-uses fMicros, eliminating the extra copy operation.
// See MicroProps::processQuantity() for details.
-int32_t NumberFormatterImpl::format(DecimalQuantity& inValue, NumberStringBuilder& outString,
+int32_t NumberFormatterImpl::format(DecimalQuantity& inValue, FormattedStringBuilder& outString,
UErrorCode& status) const {
MicroProps micros;
preProcess(inValue, micros, status);
@@ -129,8 +129,8 @@ MicroProps& NumberFormatterImpl::preProcessUnsafe(DecimalQuantity& inValue, UErr
return fMicros;
}
-int32_t NumberFormatterImpl::getPrefixSuffix(int8_t signum, StandardPlural::Form plural,
- NumberStringBuilder& outString, UErrorCode& status) const {
+int32_t NumberFormatterImpl::getPrefixSuffix(Signum signum, StandardPlural::Form plural,
+ FormattedStringBuilder& outString, UErrorCode& status) const {
if (U_FAILURE(status)) { return 0; }
// #13453: DecimalFormat wants the affixes from the pattern only (modMiddle, aka pattern modifier).
// Safe path: use fImmutablePatternModifier.
@@ -140,8 +140,8 @@ int32_t NumberFormatterImpl::getPrefixSuffix(int8_t signum, StandardPlural::Form
return modifier->getPrefixLength();
}
-int32_t NumberFormatterImpl::getPrefixSuffixUnsafe(int8_t signum, StandardPlural::Form plural,
- NumberStringBuilder& outString, UErrorCode& status) {
+int32_t NumberFormatterImpl::getPrefixSuffixUnsafe(Signum signum, StandardPlural::Form plural,
+ FormattedStringBuilder& outString, UErrorCode& status) {
if (U_FAILURE(status)) { return 0; }
// #13453: DecimalFormat wants the affixes from the pattern only (modMiddle, aka pattern modifier).
// Unsafe path: use fPatternModifier.
@@ -215,7 +215,12 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe,
if (macros.symbols.isDecimalFormatSymbols()) {
fMicros.symbols = macros.symbols.getDecimalFormatSymbols();
} else {
- fMicros.symbols = new DecimalFormatSymbols(macros.locale, *ns, status);
+ auto newSymbols = new DecimalFormatSymbols(macros.locale, *ns, status);
+ if (newSymbols == nullptr) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return nullptr;
+ }
+ fMicros.symbols = newSymbols;
// Give ownership to the NumberFormatterImpl.
fSymbols.adoptInstead(fMicros.symbols);
}
@@ -229,7 +234,11 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe,
if (info.exists) {
pattern = info.pattern;
// It's clunky to clone an object here, but this code is not frequently executed.
- auto* symbols = new DecimalFormatSymbols(*fMicros.symbols);
+ auto symbols = new DecimalFormatSymbols(*fMicros.symbols);
+ if (symbols == nullptr) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return nullptr;
+ }
fMicros.symbols = symbols;
fSymbols.adoptInstead(symbols);
symbols->setSymbol(
@@ -260,6 +269,10 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe,
pattern = utils::getPatternForStyle(macros.locale, nsName, patternStyle, status);
}
auto patternInfo = new ParsedPatternInfo();
+ if (patternInfo == nullptr) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return nullptr;
+ }
fPatternInfo.adoptInstead(patternInfo);
PatternParser::parseToPatternInfo(UnicodeString(pattern), *patternInfo, status);
@@ -337,7 +350,12 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe,
// Inner modifier (scientific notation)
if (macros.notation.fType == Notation::NTN_SCIENTIFIC) {
- fScientificHandler.adoptInstead(new ScientificHandler(&macros.notation, fMicros.symbols, chain));
+ auto newScientificHandler = new ScientificHandler(&macros.notation, fMicros.symbols, chain);
+ if (newScientificHandler == nullptr) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return nullptr;
+ }
+ fScientificHandler.adoptInstead(newScientificHandler);
chain = fScientificHandler.getAlias();
} else {
// No inner modifier required
@@ -346,6 +364,10 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe,
// Middle modifier (patterns, positive/negative, currency symbols, percent)
auto patternModifier = new MutablePatternModifier(false);
+ if (patternModifier == nullptr) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return nullptr;
+ }
fPatternModifier.adoptInstead(patternModifier);
patternModifier->setPatternInfo(
macros.affixProvider != nullptr ? macros.affixProvider
@@ -401,16 +423,20 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe,
if (macros.notation.fType == Notation::NTN_COMPACT) {
CompactType compactType = (isCurrency && unitWidth != UNUM_UNIT_WIDTH_FULL_NAME)
? CompactType::TYPE_CURRENCY : CompactType::TYPE_DECIMAL;
- fCompactHandler.adoptInstead(
- new CompactHandler(
- macros.notation.fUnion.compactStyle,
- macros.locale,
- nsName,
- compactType,
- resolvePluralRules(macros.rules, macros.locale, status),
- safe ? patternModifier : nullptr,
- chain,
- status));
+ auto newCompactHandler = new CompactHandler(
+ macros.notation.fUnion.compactStyle,
+ macros.locale,
+ nsName,
+ compactType,
+ resolvePluralRules(macros.rules, macros.locale, status),
+ safe ? patternModifier : nullptr,
+ chain,
+ status);
+ if (newCompactHandler == nullptr) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return nullptr;
+ }
+ fCompactHandler.adoptInstead(newCompactHandler);
chain = fCompactHandler.getAlias();
}
@@ -430,7 +456,7 @@ NumberFormatterImpl::resolvePluralRules(const PluralRules* rulesPtr, const Local
return fRules.getAlias();
}
-int32_t NumberFormatterImpl::writeAffixes(const MicroProps& micros, NumberStringBuilder& string,
+int32_t NumberFormatterImpl::writeAffixes(const MicroProps& micros, FormattedStringBuilder& string,
int32_t start, int32_t end, UErrorCode& status) {
// Always apply the inner modifier (which is "strong").
int32_t length = micros.modInner->apply(string, start, end, status);
@@ -445,7 +471,7 @@ int32_t NumberFormatterImpl::writeAffixes(const MicroProps& micros, NumberString
}
int32_t NumberFormatterImpl::writeNumber(const MicroProps& micros, DecimalQuantity& quantity,
- NumberStringBuilder& string, int32_t index,
+ FormattedStringBuilder& string, int32_t index,
UErrorCode& status) {
int32_t length = 0;
if (quantity.isInfinite()) {
@@ -487,7 +513,7 @@ int32_t NumberFormatterImpl::writeNumber(const MicroProps& micros, DecimalQuanti
}
int32_t NumberFormatterImpl::writeIntegerDigits(const MicroProps& micros, DecimalQuantity& quantity,
- NumberStringBuilder& string, int32_t index,
+ FormattedStringBuilder& string, int32_t index,
UErrorCode& status) {
int length = 0;
int integerCount = quantity.getUpperDisplayMagnitude() + 1;
@@ -513,7 +539,7 @@ int32_t NumberFormatterImpl::writeIntegerDigits(const MicroProps& micros, Decima
}
int32_t NumberFormatterImpl::writeFractionDigits(const MicroProps& micros, DecimalQuantity& quantity,
- NumberStringBuilder& string, int32_t index,
+ FormattedStringBuilder& string, int32_t index,
UErrorCode& status) {
int length = 0;
int fractionCount = -quantity.getLowerDisplayMagnitude();
diff --git a/deps/icu-small/source/i18n/number_formatimpl.h b/deps/icu-small/source/i18n/number_formatimpl.h
index fd8708c532..206c5f58c5 100644
--- a/deps/icu-small/source/i18n/number_formatimpl.h
+++ b/deps/icu-small/source/i18n/number_formatimpl.h
@@ -8,7 +8,7 @@
#define __NUMBER_FORMATIMPL_H__
#include "number_types.h"
-#include "number_stringbuilder.h"
+#include "formatted_string_builder.h"
#include "number_patternstring.h"
#include "number_utils.h"
#include "number_patternmodifier.h"
@@ -35,7 +35,7 @@ class NumberFormatterImpl : public UMemory {
* Builds and evaluates an "unsafe" MicroPropsGenerator, which is cheaper but can be used only once.
*/
static int32_t
- formatStatic(const MacroProps &macros, DecimalQuantity &inValue, NumberStringBuilder &outString,
+ formatStatic(const MacroProps &macros, DecimalQuantity &inValue, FormattedStringBuilder &outString,
UErrorCode &status);
/**
@@ -44,14 +44,14 @@ class NumberFormatterImpl : public UMemory {
* @return The index into the output at which the prefix ends and the suffix starts; in other words,
* the prefix length.
*/
- static int32_t getPrefixSuffixStatic(const MacroProps& macros, int8_t signum,
- StandardPlural::Form plural, NumberStringBuilder& outString,
+ static int32_t getPrefixSuffixStatic(const MacroProps& macros, Signum signum,
+ StandardPlural::Form plural, FormattedStringBuilder& outString,
UErrorCode& status);
/**
* Evaluates the "safe" MicroPropsGenerator created by "fromMacros".
*/
- int32_t format(DecimalQuantity& inValue, NumberStringBuilder& outString, UErrorCode& status) const;
+ int32_t format(DecimalQuantity& inValue, FormattedStringBuilder& outString, UErrorCode& status) const;
/**
* Like format(), but saves the result into an output MicroProps without additional processing.
@@ -61,7 +61,7 @@ class NumberFormatterImpl : public UMemory {
/**
* Like getPrefixSuffixStatic() but uses the safe compiled object.
*/
- int32_t getPrefixSuffix(int8_t signum, StandardPlural::Form plural, NumberStringBuilder& outString,
+ int32_t getPrefixSuffix(Signum signum, StandardPlural::Form plural, FormattedStringBuilder& outString,
UErrorCode& status) const;
const MicroProps& getRawMicroProps() const {
@@ -73,12 +73,12 @@ class NumberFormatterImpl : public UMemory {
* This method formats only the main number, not affixes.
*/
static int32_t writeNumber(const MicroProps& micros, DecimalQuantity& quantity,
- NumberStringBuilder& string, int32_t index, UErrorCode& status);
+ FormattedStringBuilder& string, int32_t index, UErrorCode& status);
/**
* Adds the affixes. Intended to be called immediately after formatNumber.
*/
- static int32_t writeAffixes(const MicroProps& micros, NumberStringBuilder& string, int32_t start,
+ static int32_t writeAffixes(const MicroProps& micros, FormattedStringBuilder& string, int32_t start,
int32_t end, UErrorCode& status);
private:
@@ -109,8 +109,8 @@ class NumberFormatterImpl : public UMemory {
MicroProps& preProcessUnsafe(DecimalQuantity &inValue, UErrorCode &status);
- int32_t getPrefixSuffixUnsafe(int8_t signum, StandardPlural::Form plural,
- NumberStringBuilder& outString, UErrorCode& status);
+ int32_t getPrefixSuffixUnsafe(Signum signum, StandardPlural::Form plural,
+ FormattedStringBuilder& outString, UErrorCode& status);
/**
* If rulesPtr is non-null, return it. Otherwise, return a PluralRules owned by this object for the
@@ -136,11 +136,11 @@ class NumberFormatterImpl : public UMemory {
macrosToMicroGenerator(const MacroProps &macros, bool safe, UErrorCode &status);
static int32_t
- writeIntegerDigits(const MicroProps &micros, DecimalQuantity &quantity, NumberStringBuilder &string,
+ writeIntegerDigits(const MicroProps &micros, DecimalQuantity &quantity, FormattedStringBuilder &string,
int32_t index, UErrorCode &status);
static int32_t
- writeFractionDigits(const MicroProps &micros, DecimalQuantity &quantity, NumberStringBuilder &string,
+ writeFractionDigits(const MicroProps &micros, DecimalQuantity &quantity, FormattedStringBuilder &string,
int32_t index, UErrorCode &status);
};
diff --git a/deps/icu-small/source/i18n/number_longnames.cpp b/deps/icu-small/source/i18n/number_longnames.cpp
index 0cd160042a..817aa0e0d9 100644
--- a/deps/icu-small/source/i18n/number_longnames.cpp
+++ b/deps/icu-small/source/i18n/number_longnames.cpp
@@ -148,12 +148,11 @@ void getCurrencyLongNameData(const Locale &locale, const CurrencyUnit &currency,
if (pattern.isBogus()) {
continue;
}
- UBool isChoiceFormat = FALSE;
int32_t longNameLen = 0;
const char16_t *longName = ucurr_getPluralName(
currency.getISOCurrency(),
locale.getName(),
- &isChoiceFormat,
+ nullptr /* isChoiceFormat */,
StandardPlural::getKeyword(static_cast<StandardPlural::Form>(i)),
&longNameLen,
&status);
@@ -265,6 +264,26 @@ UnicodeString LongNameHandler::getUnitDisplayName(
return simpleFormats[DNAM_INDEX];
}
+UnicodeString LongNameHandler::getUnitPattern(
+ const Locale& loc,
+ const MeasureUnit& unit,
+ UNumberUnitWidth width,
+ StandardPlural::Form pluralForm,
+ UErrorCode& status) {
+ if (U_FAILURE(status)) {
+ return ICU_Utility::makeBogusString();
+ }
+ UnicodeString simpleFormats[ARRAY_LENGTH];
+ getMeasureData(loc, unit, width, simpleFormats, status);
+ // The above already handles fallback from other widths to short
+ if (U_FAILURE(status)) {
+ return ICU_Utility::makeBogusString();
+ }
+ // Now handle fallback from other plural forms to OTHER
+ return (!(simpleFormats[pluralForm]).isBogus())? simpleFormats[pluralForm]:
+ simpleFormats[StandardPlural::Form::OTHER];
+}
+
LongNameHandler* LongNameHandler::forCurrencyLongNames(const Locale &loc, const CurrencyUnit &currency,
const PluralRules *rules,
const MicroPropsGenerator *parent,
@@ -289,7 +308,7 @@ void LongNameHandler::simpleFormatsToModifiers(const UnicodeString *simpleFormat
if (U_FAILURE(status)) { return; }
SimpleFormatter compiledFormatter(simpleFormat, 0, 1, status);
if (U_FAILURE(status)) { return; }
- fModifiers[i] = SimpleModifier(compiledFormatter, field, false, {this, 0, plural});
+ fModifiers[i] = SimpleModifier(compiledFormatter, field, false, {this, SIGNUM_ZERO, plural});
}
}
@@ -306,7 +325,7 @@ void LongNameHandler::multiSimpleFormatsToModifiers(const UnicodeString *leadFor
if (U_FAILURE(status)) { return; }
SimpleFormatter compoundCompiled(compoundFormat, 0, 1, status);
if (U_FAILURE(status)) { return; }
- fModifiers[i] = SimpleModifier(compoundCompiled, field, false, {this, 0, plural});
+ fModifiers[i] = SimpleModifier(compoundCompiled, field, false, {this, SIGNUM_ZERO, plural});
}
}
@@ -317,7 +336,7 @@ void LongNameHandler::processQuantity(DecimalQuantity &quantity, MicroProps &mic
micros.modOuter = &fModifiers[pluralForm];
}
-const Modifier* LongNameHandler::getModifier(int8_t /*signum*/, StandardPlural::Form plural) const {
+const Modifier* LongNameHandler::getModifier(Signum /*signum*/, StandardPlural::Form plural) const {
return &fModifiers[plural];
}
diff --git a/deps/icu-small/source/i18n/number_longnames.h b/deps/icu-small/source/i18n/number_longnames.h
index 76fb82d744..a19425aa26 100644
--- a/deps/icu-small/source/i18n/number_longnames.h
+++ b/deps/icu-small/source/i18n/number_longnames.h
@@ -22,6 +22,13 @@ class LongNameHandler : public MicroPropsGenerator, public ModifierStore, public
UNumberUnitWidth width,
UErrorCode& status);
+ static UnicodeString getUnitPattern(
+ const Locale& loc,
+ const MeasureUnit& unit,
+ UNumberUnitWidth width,
+ StandardPlural::Form pluralForm,
+ UErrorCode& status);
+
static LongNameHandler*
forCurrencyLongNames(const Locale &loc, const CurrencyUnit &currency, const PluralRules *rules,
const MicroPropsGenerator *parent, UErrorCode &status);
@@ -34,7 +41,7 @@ class LongNameHandler : public MicroPropsGenerator, public ModifierStore, public
void
processQuantity(DecimalQuantity &quantity, MicroProps &micros, UErrorCode &status) const U_OVERRIDE;
- const Modifier* getModifier(int8_t signum, StandardPlural::Form plural) const U_OVERRIDE;
+ const Modifier* getModifier(Signum signum, StandardPlural::Form plural) const U_OVERRIDE;
private:
SimpleModifier fModifiers[StandardPlural::Form::COUNT];
diff --git a/deps/icu-small/source/i18n/number_mapper.h b/deps/icu-small/source/i18n/number_mapper.h
index d28e9cec39..de7d9c3865 100644
--- a/deps/icu-small/source/i18n/number_mapper.h
+++ b/deps/icu-small/source/i18n/number_mapper.h
@@ -126,8 +126,14 @@ struct DecimalFormatWarehouse {
* TODO: Make some of these fields by value instead of by LocalPointer?
*/
struct DecimalFormatFields : public UMemory {
+
+ DecimalFormatFields() {}
+
+ DecimalFormatFields(const DecimalFormatProperties& propsToCopy)
+ : properties(propsToCopy) {}
+
/** The property bag corresponding to user-specified settings and settings from the pattern string. */
- LocalPointer<DecimalFormatProperties> properties;
+ DecimalFormatProperties properties;
/** The symbols for the current locale. */
LocalPointer<const DecimalFormatSymbols> symbols;
@@ -136,7 +142,7 @@ struct DecimalFormatFields : public UMemory {
* The pre-computed formatter object. Setters cause this to be re-computed atomically. The {@link
* #format} method uses the formatter directly without needing to synchronize.
*/
- LocalPointer<LocalizedNumberFormatter> formatter;
+ LocalizedNumberFormatter formatter;
/** The lazy-computed parser for .parse() */
std::atomic<::icu::numparse::impl::NumberParserImpl*> atomicParser = {};
@@ -148,7 +154,7 @@ struct DecimalFormatFields : public UMemory {
DecimalFormatWarehouse warehouse;
/** The effective properties as exported from the formatter object. Used by some getters. */
- LocalPointer<DecimalFormatProperties> exportedProperties;
+ DecimalFormatProperties exportedProperties;
// Data for fastpath
bool canUseFastFormat = false;
diff --git a/deps/icu-small/source/i18n/number_modifiers.cpp b/deps/icu-small/source/i18n/number_modifiers.cpp
index 1fcbe7b9b7..3a44f8f6f1 100644
--- a/deps/icu-small/source/i18n/number_modifiers.cpp
+++ b/deps/icu-small/source/i18n/number_modifiers.cpp
@@ -57,7 +57,7 @@ Modifier::Parameters::Parameters()
: obj(nullptr) {}
Modifier::Parameters::Parameters(
- const ModifierStore* _obj, int8_t _signum, StandardPlural::Form _plural)
+ const ModifierStore* _obj, Signum _signum, StandardPlural::Form _plural)
: obj(_obj), signum(_signum), plural(_plural) {}
ModifierStore::~ModifierStore() = default;
@@ -69,7 +69,7 @@ AdoptingModifierStore::~AdoptingModifierStore() {
}
-int32_t ConstantAffixModifier::apply(NumberStringBuilder &output, int leftIndex, int rightIndex,
+int32_t ConstantAffixModifier::apply(FormattedStringBuilder &output, int leftIndex, int rightIndex,
UErrorCode &status) const {
// Insert the suffix first since inserting the prefix will change the rightIndex
int length = output.insert(rightIndex, fSuffix, fField, status);
@@ -154,7 +154,7 @@ SimpleModifier::SimpleModifier()
: fField(UNUM_FIELD_COUNT), fStrong(false), fPrefixLength(0), fSuffixLength(0) {
}
-int32_t SimpleModifier::apply(NumberStringBuilder &output, int leftIndex, int rightIndex,
+int32_t SimpleModifier::apply(FormattedStringBuilder &output, int leftIndex, int rightIndex,
UErrorCode &status) const {
return formatAsPrefixSuffix(output, leftIndex, rightIndex, status);
}
@@ -203,7 +203,7 @@ bool SimpleModifier::semanticallyEquivalent(const Modifier& other) const {
int32_t
-SimpleModifier::formatAsPrefixSuffix(NumberStringBuilder &result, int32_t startIndex, int32_t endIndex,
+SimpleModifier::formatAsPrefixSuffix(FormattedStringBuilder &result, int32_t startIndex, int32_t endIndex,
UErrorCode &status) const {
if (fSuffixOffset == -1 && fPrefixLength + fSuffixLength > 0) {
// There is no argument for the inner number; overwrite the entire segment with our string.
@@ -227,7 +227,7 @@ SimpleModifier::formatAsPrefixSuffix(NumberStringBuilder &result, int32_t startI
int32_t
-SimpleModifier::formatTwoArgPattern(const SimpleFormatter& compiled, NumberStringBuilder& result,
+SimpleModifier::formatTwoArgPattern(const SimpleFormatter& compiled, FormattedStringBuilder& result,
int32_t index, int32_t* outPrefixLength, int32_t* outSuffixLength,
Field field, UErrorCode& status) {
const UnicodeString& compiledPattern = compiled.compiledPattern;
@@ -284,7 +284,7 @@ SimpleModifier::formatTwoArgPattern(const SimpleFormatter& compiled, NumberStrin
}
-int32_t ConstantMultiFieldModifier::apply(NumberStringBuilder &output, int leftIndex, int rightIndex,
+int32_t ConstantMultiFieldModifier::apply(FormattedStringBuilder &output, int leftIndex, int rightIndex,
UErrorCode &status) const {
int32_t length = output.insert(leftIndex, fPrefix, status);
if (fOverwrite) {
@@ -333,8 +333,8 @@ bool ConstantMultiFieldModifier::semanticallyEquivalent(const Modifier& other) c
}
-CurrencySpacingEnabledModifier::CurrencySpacingEnabledModifier(const NumberStringBuilder &prefix,
- const NumberStringBuilder &suffix,
+CurrencySpacingEnabledModifier::CurrencySpacingEnabledModifier(const FormattedStringBuilder &prefix,
+ const FormattedStringBuilder &suffix,
bool overwrite,
bool strong,
const DecimalFormatSymbols &symbols,
@@ -374,7 +374,7 @@ CurrencySpacingEnabledModifier::CurrencySpacingEnabledModifier(const NumberStrin
}
}
-int32_t CurrencySpacingEnabledModifier::apply(NumberStringBuilder &output, int leftIndex, int rightIndex,
+int32_t CurrencySpacingEnabledModifier::apply(FormattedStringBuilder &output, int leftIndex, int rightIndex,
UErrorCode &status) const {
// Currency spacing logic
int length = 0;
@@ -395,7 +395,7 @@ int32_t CurrencySpacingEnabledModifier::apply(NumberStringBuilder &output, int l
}
int32_t
-CurrencySpacingEnabledModifier::applyCurrencySpacing(NumberStringBuilder &output, int32_t prefixStart,
+CurrencySpacingEnabledModifier::applyCurrencySpacing(FormattedStringBuilder &output, int32_t prefixStart,
int32_t prefixLen, int32_t suffixStart,
int32_t suffixLen,
const DecimalFormatSymbols &symbols,
@@ -414,7 +414,7 @@ CurrencySpacingEnabledModifier::applyCurrencySpacing(NumberStringBuilder &output
}
int32_t
-CurrencySpacingEnabledModifier::applyCurrencySpacingAffix(NumberStringBuilder &output, int32_t index,
+CurrencySpacingEnabledModifier::applyCurrencySpacingAffix(FormattedStringBuilder &output, int32_t index,
EAffix affix,
const DecimalFormatSymbols &symbols,
UErrorCode &status) {
diff --git a/deps/icu-small/source/i18n/number_modifiers.h b/deps/icu-small/source/i18n/number_modifiers.h
index 495128bb14..c84c6aa273 100644
--- a/deps/icu-small/source/i18n/number_modifiers.h
+++ b/deps/icu-small/source/i18n/number_modifiers.h
@@ -12,7 +12,7 @@
#include "unicode/uniset.h"
#include "unicode/simpleformatter.h"
#include "standardplural.h"
-#include "number_stringbuilder.h"
+#include "formatted_string_builder.h"
#include "number_types.h"
U_NAMESPACE_BEGIN namespace number {
@@ -28,7 +28,7 @@ class U_I18N_API ConstantAffixModifier : public Modifier, public UObject {
bool strong)
: fPrefix(prefix), fSuffix(suffix), fField(field), fStrong(strong) {}
- int32_t apply(NumberStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
+ int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
UErrorCode &status) const U_OVERRIDE;
int32_t getPrefixLength() const U_OVERRIDE;
@@ -64,7 +64,7 @@ class U_I18N_API SimpleModifier : public Modifier, public UMemory {
// Default constructor for LongNameHandler.h
SimpleModifier();
- int32_t apply(NumberStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
+ int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
UErrorCode &status) const U_OVERRIDE;
int32_t getPrefixLength() const U_OVERRIDE;
@@ -81,7 +81,7 @@ class U_I18N_API SimpleModifier : public Modifier, public UMemory {
/**
* TODO: This belongs in SimpleFormatterImpl. The only reason I haven't moved it there yet is because
- * NumberStringBuilder is an internal class and SimpleFormatterImpl feels like it should not depend on it.
+ * FormattedStringBuilder is an internal class and SimpleFormatterImpl feels like it should not depend on it.
*
* <p>
* Formats a value that is already stored inside the StringBuilder <code>result</code> between the indices
@@ -100,22 +100,22 @@ class U_I18N_API SimpleModifier : public Modifier, public UMemory {
* @return The number of characters (UTF-16 code points) that were added to the StringBuilder.
*/
int32_t
- formatAsPrefixSuffix(NumberStringBuilder& result, int32_t startIndex, int32_t endIndex,
+ formatAsPrefixSuffix(FormattedStringBuilder& result, int32_t startIndex, int32_t endIndex,
UErrorCode& status) const;
/**
* TODO: Like above, this belongs with the rest of the SimpleFormatterImpl code.
- * I put it here so that the SimpleFormatter uses in NumberStringBuilder are near each other.
+ * I put it here so that the SimpleFormatter uses in FormattedStringBuilder are near each other.
*
* <p>
- * Applies the compiled two-argument pattern to the NumberStringBuilder.
+ * Applies the compiled two-argument pattern to the FormattedStringBuilder.
*
* <p>
* This method is optimized for the case where the prefix and suffix are often empty, such as
* in the range pattern like "{0}-{1}".
*/
static int32_t
- formatTwoArgPattern(const SimpleFormatter& compiled, NumberStringBuilder& result,
+ formatTwoArgPattern(const SimpleFormatter& compiled, FormattedStringBuilder& result,
int32_t index, int32_t* outPrefixLength, int32_t* outSuffixLength,
Field field, UErrorCode& status);
@@ -131,13 +131,13 @@ class U_I18N_API SimpleModifier : public Modifier, public UMemory {
/**
* An implementation of {@link Modifier} that allows for multiple types of fields in the same modifier. Constructed
- * based on the contents of two {@link NumberStringBuilder} instances (one for the prefix, one for the suffix).
+ * based on the contents of two {@link FormattedStringBuilder} instances (one for the prefix, one for the suffix).
*/
class U_I18N_API ConstantMultiFieldModifier : public Modifier, public UMemory {
public:
ConstantMultiFieldModifier(
- const NumberStringBuilder &prefix,
- const NumberStringBuilder &suffix,
+ const FormattedStringBuilder &prefix,
+ const FormattedStringBuilder &suffix,
bool overwrite,
bool strong,
const Modifier::Parameters parameters)
@@ -148,8 +148,8 @@ class U_I18N_API ConstantMultiFieldModifier : public Modifier, public UMemory {
fParameters(parameters) {}
ConstantMultiFieldModifier(
- const NumberStringBuilder &prefix,
- const NumberStringBuilder &suffix,
+ const FormattedStringBuilder &prefix,
+ const FormattedStringBuilder &suffix,
bool overwrite,
bool strong)
: fPrefix(prefix),
@@ -157,7 +157,7 @@ class U_I18N_API ConstantMultiFieldModifier : public Modifier, public UMemory {
fOverwrite(overwrite),
fStrong(strong) {}
- int32_t apply(NumberStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
+ int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
UErrorCode &status) const U_OVERRIDE;
int32_t getPrefixLength() const U_OVERRIDE;
@@ -173,10 +173,10 @@ class U_I18N_API ConstantMultiFieldModifier : public Modifier, public UMemory {
bool semanticallyEquivalent(const Modifier& other) const U_OVERRIDE;
protected:
- // NOTE: In Java, these are stored as array pointers. In C++, the NumberStringBuilder is stored by
+ // NOTE: In Java, these are stored as array pointers. In C++, the FormattedStringBuilder is stored by
// value and is treated internally as immutable.
- NumberStringBuilder fPrefix;
- NumberStringBuilder fSuffix;
+ FormattedStringBuilder fPrefix;
+ FormattedStringBuilder fSuffix;
bool fOverwrite;
bool fStrong;
Modifier::Parameters fParameters;
@@ -187,19 +187,19 @@ class U_I18N_API CurrencySpacingEnabledModifier : public ConstantMultiFieldModif
public:
/** Safe code path */
CurrencySpacingEnabledModifier(
- const NumberStringBuilder &prefix,
- const NumberStringBuilder &suffix,
+ const FormattedStringBuilder &prefix,
+ const FormattedStringBuilder &suffix,
bool overwrite,
bool strong,
const DecimalFormatSymbols &symbols,
UErrorCode &status);
- int32_t apply(NumberStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
+ int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
UErrorCode &status) const U_OVERRIDE;
/** Unsafe code path */
static int32_t
- applyCurrencySpacing(NumberStringBuilder &output, int32_t prefixStart, int32_t prefixLen,
+ applyCurrencySpacing(FormattedStringBuilder &output, int32_t prefixStart, int32_t prefixLen,
int32_t suffixStart, int32_t suffixLen, const DecimalFormatSymbols &symbols,
UErrorCode &status);
@@ -218,7 +218,7 @@ class U_I18N_API CurrencySpacingEnabledModifier : public ConstantMultiFieldModif
};
/** Unsafe code path */
- static int32_t applyCurrencySpacingAffix(NumberStringBuilder &output, int32_t index, EAffix affix,
+ static int32_t applyCurrencySpacingAffix(FormattedStringBuilder &output, int32_t index, EAffix affix,
const DecimalFormatSymbols &symbols, UErrorCode &status);
static UnicodeSet
@@ -234,7 +234,7 @@ class U_I18N_API EmptyModifier : public Modifier, public UMemory {
public:
explicit EmptyModifier(bool isStrong) : fStrong(isStrong) {}
- int32_t apply(NumberStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
+ int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
UErrorCode &status) const U_OVERRIDE {
(void)output;
(void)leftIndex;
@@ -289,7 +289,7 @@ class U_I18N_API AdoptingModifierStore : public ModifierStore, public UMemory {
/**
* Sets the Modifier with the specified signum and plural form.
*/
- void adoptModifier(int8_t signum, StandardPlural::Form plural, const Modifier *mod) {
+ void adoptModifier(Signum signum, StandardPlural::Form plural, const Modifier *mod) {
U_ASSERT(mods[getModIndex(signum, plural)] == nullptr);
mods[getModIndex(signum, plural)] = mod;
}
@@ -298,13 +298,13 @@ class U_I18N_API AdoptingModifierStore : public ModifierStore, public UMemory {
* Sets the Modifier with the specified signum.
* The modifier will apply to all plural forms.
*/
- void adoptModifierWithoutPlural(int8_t signum, const Modifier *mod) {
+ void adoptModifierWithoutPlural(Signum signum, const Modifier *mod) {
U_ASSERT(mods[getModIndex(signum, DEFAULT_STANDARD_PLURAL)] == nullptr);
mods[getModIndex(signum, DEFAULT_STANDARD_PLURAL)] = mod;
}
/** Returns a reference to the modifier; no ownership change. */
- const Modifier *getModifier(int8_t signum, StandardPlural::Form plural) const U_OVERRIDE {
+ const Modifier *getModifier(Signum signum, StandardPlural::Form plural) const U_OVERRIDE {
const Modifier* modifier = mods[getModIndex(signum, plural)];
if (modifier == nullptr && plural != DEFAULT_STANDARD_PLURAL) {
modifier = mods[getModIndex(signum, DEFAULT_STANDARD_PLURAL)];
@@ -313,7 +313,7 @@ class U_I18N_API AdoptingModifierStore : public ModifierStore, public UMemory {
}
/** Returns a reference to the modifier; no ownership change. */
- const Modifier *getModifierWithoutPlural(int8_t signum) const {
+ const Modifier *getModifierWithoutPlural(Signum signum) const {
return mods[getModIndex(signum, DEFAULT_STANDARD_PLURAL)];
}
@@ -321,7 +321,7 @@ class U_I18N_API AdoptingModifierStore : public ModifierStore, public UMemory {
// NOTE: mods is zero-initialized (to nullptr)
const Modifier *mods[3 * StandardPlural::COUNT] = {};
- inline static int32_t getModIndex(int8_t signum, StandardPlural::Form plural) {
+ inline static int32_t getModIndex(Signum signum, StandardPlural::Form plural) {
U_ASSERT(signum >= -1 && signum <= 1);
U_ASSERT(plural >= 0 && plural < StandardPlural::COUNT);
return static_cast<int32_t>(plural) * 3 + (signum + 1);
diff --git a/deps/icu-small/source/i18n/number_output.cpp b/deps/icu-small/source/i18n/number_output.cpp
index 6f4e248204..e2f069139a 100644
--- a/deps/icu-small/source/i18n/number_output.cpp
+++ b/deps/icu-small/source/i18n/number_output.cpp
@@ -9,6 +9,7 @@
#include "number_utypes.h"
#include "util.h"
#include "number_decimalquantity.h"
+#include "number_decnum.h"
U_NAMESPACE_BEGIN
namespace number {
@@ -20,8 +21,7 @@ UPRV_FORMATTED_VALUE_SUBCLASS_AUTO_IMPL(FormattedNumber)
UBool FormattedNumber::nextFieldPosition(FieldPosition& fieldPosition, UErrorCode& status) const {
UPRV_FORMATTED_VALUE_METHOD_GUARD(FALSE)
- // NOTE: MSVC sometimes complains when implicitly converting between bool and UBool
- return fData->getStringRef().nextFieldPosition(fieldPosition, status) ? TRUE : FALSE;
+ return fData->nextFieldPosition(fieldPosition, status);
}
void FormattedNumber::getAllFieldPositions(FieldPositionIterator& iterator, UErrorCode& status) const {
@@ -29,10 +29,17 @@ void FormattedNumber::getAllFieldPositions(FieldPositionIterator& iterator, UErr
getAllFieldPositionsImpl(fpih, status);
}
+void FormattedNumber::toDecimalNumber(ByteSink& sink, UErrorCode& status) const {
+ UPRV_FORMATTED_VALUE_METHOD_GUARD(UPRV_NOARG)
+ impl::DecNum decnum;
+ fData->quantity.toDecNum(decnum, status);
+ decnum.toString(sink, status);
+}
+
void FormattedNumber::getAllFieldPositionsImpl(FieldPositionIteratorHandler& fpih,
UErrorCode& status) const {
UPRV_FORMATTED_VALUE_METHOD_GUARD(UPRV_NOARG)
- fData->getStringRef().getAllFieldPositions(fpih, status);
+ fData->getAllFieldPositions(fpih, status);
}
void FormattedNumber::getDecimalQuantity(impl::DecimalQuantity& output, UErrorCode& status) const {
diff --git a/deps/icu-small/source/i18n/number_padding.cpp b/deps/icu-small/source/i18n/number_padding.cpp
index 31684d7208..c68a9875b2 100644
--- a/deps/icu-small/source/i18n/number_padding.cpp
+++ b/deps/icu-small/source/i18n/number_padding.cpp
@@ -7,7 +7,7 @@
#include "unicode/numberformatter.h"
#include "number_types.h"
-#include "number_stringbuilder.h"
+#include "formatted_string_builder.h"
#include "number_decimfmtprops.h"
using namespace icu;
@@ -17,7 +17,7 @@ using namespace icu::number::impl;
namespace {
int32_t
-addPaddingHelper(UChar32 paddingCp, int32_t requiredPadding, NumberStringBuilder &string, int32_t index,
+addPaddingHelper(UChar32 paddingCp, int32_t requiredPadding, FormattedStringBuilder &string, int32_t index,
UErrorCode &status) {
for (int32_t i = 0; i < requiredPadding; i++) {
// TODO: If appending to the end, this will cause actual insertion operations. Improve.
@@ -60,7 +60,7 @@ Padder Padder::forProperties(const DecimalFormatProperties& properties) {
}
int32_t Padder::padAndApply(const Modifier &mod1, const Modifier &mod2,
- NumberStringBuilder &string, int32_t leftIndex, int32_t rightIndex,
+ FormattedStringBuilder &string, int32_t leftIndex, int32_t rightIndex,
UErrorCode &status) const {
int32_t modLength = mod1.getCodePointCount() + mod2.getCodePointCount();
int32_t requiredPadding = fWidth - modLength - string.codePointCount();
diff --git a/deps/icu-small/source/i18n/number_patternmodifier.cpp b/deps/icu-small/source/i18n/number_patternmodifier.cpp
index 75de439f3e..724f5b9741 100644
--- a/deps/icu-small/source/i18n/number_patternmodifier.cpp
+++ b/deps/icu-small/source/i18n/number_patternmodifier.cpp
@@ -43,7 +43,7 @@ void MutablePatternModifier::setSymbols(const DecimalFormatSymbols* symbols,
fRules = rules;
}
-void MutablePatternModifier::setNumberProperties(int8_t signum, StandardPlural::Form plural) {
+void MutablePatternModifier::setNumberProperties(Signum signum, StandardPlural::Form plural) {
fSignum = signum;
fPlural = plural;
}
@@ -79,12 +79,12 @@ MutablePatternModifier::createImmutableAndChain(const MicroPropsGenerator* paren
if (needsPlurals()) {
// Slower path when we require the plural keyword.
for (StandardPlural::Form plural : STANDARD_PLURAL_VALUES) {
- setNumberProperties(1, plural);
- pm->adoptModifier(1, plural, createConstantModifier(status));
- setNumberProperties(0, plural);
- pm->adoptModifier(0, plural, createConstantModifier(status));
- setNumberProperties(-1, plural);
- pm->adoptModifier(-1, plural, createConstantModifier(status));
+ setNumberProperties(SIGNUM_POS, plural);
+ pm->adoptModifier(SIGNUM_POS, plural, createConstantModifier(status));
+ setNumberProperties(SIGNUM_ZERO, plural);
+ pm->adoptModifier(SIGNUM_ZERO, plural, createConstantModifier(status));
+ setNumberProperties(SIGNUM_NEG, plural);
+ pm->adoptModifier(SIGNUM_NEG, plural, createConstantModifier(status));
}
if (U_FAILURE(status)) {
delete pm;
@@ -93,12 +93,12 @@ MutablePatternModifier::createImmutableAndChain(const MicroPropsGenerator* paren
return new ImmutablePatternModifier(pm, fRules, parent); // adopts pm
} else {
// Faster path when plural keyword is not needed.
- setNumberProperties(1, StandardPlural::Form::COUNT);
- pm->adoptModifierWithoutPlural(1, createConstantModifier(status));
- setNumberProperties(0, StandardPlural::Form::COUNT);
- pm->adoptModifierWithoutPlural(0, createConstantModifier(status));
- setNumberProperties(-1, StandardPlural::Form::COUNT);
- pm->adoptModifierWithoutPlural(-1, createConstantModifier(status));
+ setNumberProperties(SIGNUM_POS, StandardPlural::Form::COUNT);
+ pm->adoptModifierWithoutPlural(SIGNUM_POS, createConstantModifier(status));
+ setNumberProperties(SIGNUM_ZERO, StandardPlural::Form::COUNT);
+ pm->adoptModifierWithoutPlural(SIGNUM_ZERO, createConstantModifier(status));
+ setNumberProperties(SIGNUM_NEG, StandardPlural::Form::COUNT);
+ pm->adoptModifierWithoutPlural(SIGNUM_NEG, createConstantModifier(status));
if (U_FAILURE(status)) {
delete pm;
return nullptr;
@@ -108,8 +108,8 @@ MutablePatternModifier::createImmutableAndChain(const MicroPropsGenerator* paren
}
ConstantMultiFieldModifier* MutablePatternModifier::createConstantModifier(UErrorCode& status) {
- NumberStringBuilder a;
- NumberStringBuilder b;
+ FormattedStringBuilder a;
+ FormattedStringBuilder b;
insertPrefix(a, 0, status);
insertSuffix(b, 0, status);
if (fPatternInfo->hasCurrencySign()) {
@@ -140,7 +140,7 @@ void ImmutablePatternModifier::applyToMicros(
}
}
-const Modifier* ImmutablePatternModifier::getModifier(int8_t signum, StandardPlural::Form plural) const {
+const Modifier* ImmutablePatternModifier::getModifier(Signum signum, StandardPlural::Form plural) const {
if (rules == nullptr) {
return pm->getModifierWithoutPlural(signum);
} else {
@@ -170,7 +170,7 @@ void MutablePatternModifier::processQuantity(DecimalQuantity& fq, MicroProps& mi
micros.modMiddle = this;
}
-int32_t MutablePatternModifier::apply(NumberStringBuilder& output, int32_t leftIndex, int32_t rightIndex,
+int32_t MutablePatternModifier::apply(FormattedStringBuilder& output, int32_t leftIndex, int32_t rightIndex,
UErrorCode& status) const {
// The unsafe code path performs self-mutation, so we need a const_cast.
// This method needs to be const because it overrides a const method in the parent class.
@@ -248,13 +248,13 @@ bool MutablePatternModifier::semanticallyEquivalent(const Modifier& other) const
UPRV_UNREACHABLE;
}
-int32_t MutablePatternModifier::insertPrefix(NumberStringBuilder& sb, int position, UErrorCode& status) {
+int32_t MutablePatternModifier::insertPrefix(FormattedStringBuilder& sb, int position, UErrorCode& status) {
prepareAffix(true);
int32_t length = AffixUtils::unescape(currentAffix, sb, position, *this, fField, status);
return length;
}
-int32_t MutablePatternModifier::insertSuffix(NumberStringBuilder& sb, int position, UErrorCode& status) {
+int32_t MutablePatternModifier::insertSuffix(FormattedStringBuilder& sb, int position, UErrorCode& status) {
prepareAffix(false);
int32_t length = AffixUtils::unescape(currentAffix, sb, position, *this, fField, status);
return length;
diff --git a/deps/icu-small/source/i18n/number_patternmodifier.h b/deps/icu-small/source/i18n/number_patternmodifier.h
index 27e293b64c..b2c90e0af7 100644
--- a/deps/icu-small/source/i18n/number_patternmodifier.h
+++ b/deps/icu-small/source/i18n/number_patternmodifier.h
@@ -48,7 +48,7 @@ class U_I18N_API ImmutablePatternModifier : public MicroPropsGenerator, public U
void applyToMicros(MicroProps& micros, const DecimalQuantity& quantity, UErrorCode& status) const;
- const Modifier* getModifier(int8_t signum, StandardPlural::Form plural) const;
+ const Modifier* getModifier(Signum signum, StandardPlural::Form plural) const;
private:
ImmutablePatternModifier(AdoptingModifierStore* pm, const PluralRules* rules,
@@ -142,7 +142,7 @@ class U_I18N_API MutablePatternModifier
* The plural form of the number, required only if the pattern contains the triple
* currency sign, "¤¤¤" (and as indicated by {@link #needsPlurals()}).
*/
- void setNumberProperties(int8_t signum, StandardPlural::Form plural);
+ void setNumberProperties(Signum signum, StandardPlural::Form plural);
/**
* Returns true if the pattern represented by this MurkyModifier requires a plural keyword in order to localize.
@@ -184,7 +184,7 @@ class U_I18N_API MutablePatternModifier
void processQuantity(DecimalQuantity &, MicroProps &micros, UErrorCode &status) const U_OVERRIDE;
- int32_t apply(NumberStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
+ int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
UErrorCode &status) const U_OVERRIDE;
int32_t getPrefixLength() const U_OVERRIDE;
@@ -223,7 +223,7 @@ class U_I18N_API MutablePatternModifier
const PluralRules *fRules;
// Number details (initialized in setNumberProperties)
- int8_t fSignum;
+ Signum fSignum;
StandardPlural::Form fPlural;
// QuantityChain details (initialized in addToChain)
@@ -240,17 +240,17 @@ class U_I18N_API MutablePatternModifier
* CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP.
*
* @param a
- * A working NumberStringBuilder object; passed from the outside to prevent the need to create many new
+ * A working FormattedStringBuilder object; passed from the outside to prevent the need to create many new
* instances if this method is called in a loop.
* @param b
- * Another working NumberStringBuilder object.
+ * Another working FormattedStringBuilder object.
* @return The constant modifier object.
*/
ConstantMultiFieldModifier *createConstantModifier(UErrorCode &status);
- int32_t insertPrefix(NumberStringBuilder &sb, int position, UErrorCode &status);
+ int32_t insertPrefix(FormattedStringBuilder &sb, int position, UErrorCode &status);
- int32_t insertSuffix(NumberStringBuilder &sb, int position, UErrorCode &status);
+ int32_t insertSuffix(FormattedStringBuilder &sb, int position, UErrorCode &status);
void prepareAffix(bool isPrefix);
};
diff --git a/deps/icu-small/source/i18n/number_patternstring.cpp b/deps/icu-small/source/i18n/number_patternstring.cpp
index 9075424663..c7212c1e5c 100644
--- a/deps/icu-small/source/i18n/number_patternstring.cpp
+++ b/deps/icu-small/source/i18n/number_patternstring.cpp
@@ -352,7 +352,7 @@ void ParsedPatternInfo::consumeIntegerFormat(UErrorCode& status) {
result.groupingSizes += 1;
result.integerNumerals += 1;
result.integerTotal += 1;
- if (!result.rounding.isZero() || state.peek() != u'0') {
+ if (!result.rounding.isZeroish() || state.peek() != u'0') {
result.rounding.appendDigit(static_cast<int8_t>(state.peek() - u'0'), 0, true);
}
break;
@@ -532,7 +532,7 @@ PatternParser::patternInfoToProperties(DecimalFormatProperties& properties, Pars
properties.roundingIncrement = 0.0;
properties.minimumSignificantDigits = positive.integerAtSigns;
properties.maximumSignificantDigits = positive.integerAtSigns + positive.integerTrailingHashSigns;
- } else if (!positive.rounding.isZero()) {
+ } else if (!positive.rounding.isZeroish()) {
if (!ignoreRounding) {
properties.minimumFractionDigits = minFrac;
properties.maximumFractionDigits = positive.fractionTotal;
@@ -1000,7 +1000,7 @@ PatternStringUtils::convertLocalized(const UnicodeString& input, const DecimalFo
}
void PatternStringUtils::patternInfoToStringBuilder(const AffixPatternProvider& patternInfo, bool isPrefix,
- int8_t signum, UNumberSignDisplay signDisplay,
+ Signum signum, UNumberSignDisplay signDisplay,
StandardPlural::Form plural,
bool perMilleReplacesPercent, UnicodeString& output) {
@@ -1014,6 +1014,7 @@ void PatternStringUtils::patternInfoToStringBuilder(const AffixPatternProvider&
// Should we use the affix from the negative subpattern? (If not, we will use the positive
// subpattern.)
+ // TODO: Deal with signum
bool useNegativeAffixPattern = patternInfo.hasNegativeSubpattern() && (
signum == -1 || (patternInfo.negativeHasMinusSign() && plusReplacesMinusSign));
diff --git a/deps/icu-small/source/i18n/number_patternstring.h b/deps/icu-small/source/i18n/number_patternstring.h
index 42e7c39161..819c74d4bd 100644
--- a/deps/icu-small/source/i18n/number_patternstring.h
+++ b/deps/icu-small/source/i18n/number_patternstring.h
@@ -295,7 +295,7 @@ class U_I18N_API PatternStringUtils {
* substitution, and plural forms for CurrencyPluralInfo.
*/
static void patternInfoToStringBuilder(const AffixPatternProvider& patternInfo, bool isPrefix,
- int8_t signum, UNumberSignDisplay signDisplay,
+ Signum signum, UNumberSignDisplay signDisplay,
StandardPlural::Form plural, bool perMilleReplacesPercent,
UnicodeString& output);
diff --git a/deps/icu-small/source/i18n/number_rounding.cpp b/deps/icu-small/source/i18n/number_rounding.cpp
index 9e369f7925..813d4b680d 100644
--- a/deps/icu-small/source/i18n/number_rounding.cpp
+++ b/deps/icu-small/source/i18n/number_rounding.cpp
@@ -33,7 +33,7 @@ int32_t getRoundingMagnitudeSignificant(const DecimalQuantity &value, int maxSig
if (maxSig == -1) {
return INT32_MIN;
}
- int magnitude = value.isZero() ? 0 : value.getMagnitude();
+ int magnitude = value.isZeroish() ? 0 : value.getMagnitude();
return magnitude - maxSig + 1;
}
@@ -45,7 +45,7 @@ int32_t getDisplayMagnitudeFraction(int minFrac) {
}
int32_t getDisplayMagnitudeSignificant(const DecimalQuantity &value, int minSig) {
- int magnitude = value.isZero() ? 0 : value.getMagnitude();
+ int magnitude = value.isZeroish() ? 0 : value.getMagnitude();
return magnitude - minSig + 1;
}
@@ -306,8 +306,8 @@ bool RoundingImpl::isSignificantDigits() const {
int32_t
RoundingImpl::chooseMultiplierAndApply(impl::DecimalQuantity &input, const impl::MultiplierProducer &producer,
UErrorCode &status) {
- // Do not call this method with zero.
- U_ASSERT(!input.isZero());
+ // Do not call this method with zero, NaN, or infinity.
+ U_ASSERT(!input.isZeroish());
// Perform the first attempt at rounding.
int magnitude = input.getMagnitude();
@@ -316,7 +316,7 @@ RoundingImpl::chooseMultiplierAndApply(impl::DecimalQuantity &input, const impl:
apply(input, status);
// If the number rounded to zero, exit.
- if (input.isZero() || U_FAILURE(status)) {
+ if (input.isZeroish() || U_FAILURE(status)) {
return multiplier;
}
@@ -374,7 +374,7 @@ void RoundingImpl::apply(impl::DecimalQuantity &value, UErrorCode& status) const
value.setMinFraction(
uprv_max(0, -getDisplayMagnitudeSignificant(value, fPrecision.fUnion.fracSig.fMinSig)));
// Make sure that digits are displayed on zero.
- if (value.isZero() && fPrecision.fUnion.fracSig.fMinSig > 0) {
+ if (value.isZeroish() && fPrecision.fUnion.fracSig.fMinSig > 0) {
value.setMinInteger(1);
}
break;
@@ -436,7 +436,7 @@ void RoundingImpl::apply(impl::DecimalQuantity &value, UErrorCode& status) const
void RoundingImpl::apply(impl::DecimalQuantity &value, int32_t minInt, UErrorCode /*status*/) {
// This method is intended for the one specific purpose of helping print "00.000E0".
U_ASSERT(isSignificantDigits());
- U_ASSERT(value.isZero());
+ U_ASSERT(value.isZeroish());
value.setMinFraction(fPrecision.fUnion.fracSig.fMinSig - minInt);
}
diff --git a/deps/icu-small/source/i18n/number_scientific.cpp b/deps/icu-small/source/i18n/number_scientific.cpp
index 6df07b9cc9..20aa45bff0 100644
--- a/deps/icu-small/source/i18n/number_scientific.cpp
+++ b/deps/icu-small/source/i18n/number_scientific.cpp
@@ -8,7 +8,7 @@
#include <cstdlib>
#include "number_scientific.h"
#include "number_utils.h"
-#include "number_stringbuilder.h"
+#include "formatted_string_builder.h"
#include "unicode/unum.h"
#include "number_microprops.h"
@@ -36,7 +36,7 @@ void ScientificModifier::set(int32_t exponent, const ScientificHandler *handler)
fHandler = handler;
}
-int32_t ScientificModifier::apply(NumberStringBuilder &output, int32_t /*leftIndex*/, int32_t rightIndex,
+int32_t ScientificModifier::apply(FormattedStringBuilder &output, int32_t /*leftIndex*/, int32_t rightIndex,
UErrorCode &status) const {
// FIXME: Localized exponent separator location.
int i = rightIndex;
@@ -123,9 +123,15 @@ void ScientificHandler::processQuantity(DecimalQuantity &quantity, MicroProps &m
fParent->processQuantity(quantity, micros, status);
if (U_FAILURE(status)) { return; }
+ // Do not apply scientific notation to special doubles
+ if (quantity.isInfinite() || quantity.isNaN()) {
+ micros.modInner = &micros.helpers.emptyStrongModifier;
+ return;
+ }
+
// Treat zero as if it had magnitude 0
int32_t exponent;
- if (quantity.isZero()) {
+ if (quantity.isZeroish()) {
if (fSettings.fRequireMinInt && micros.rounder.isSignificantDigits()) {
// Show "00.000E0" on pattern "00.000E0"
micros.rounder.apply(quantity, fSettings.fEngineeringInterval, status);
diff --git a/deps/icu-small/source/i18n/number_scientific.h b/deps/icu-small/source/i18n/number_scientific.h
index e377bd941e..1c9ce1efa8 100644
--- a/deps/icu-small/source/i18n/number_scientific.h
+++ b/deps/icu-small/source/i18n/number_scientific.h
@@ -21,7 +21,7 @@ class U_I18N_API ScientificModifier : public UMemory, public Modifier {
void set(int32_t exponent, const ScientificHandler *handler);
- int32_t apply(NumberStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
+ int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
UErrorCode &status) const U_OVERRIDE;
int32_t getPrefixLength() const U_OVERRIDE;
diff --git a/deps/icu-small/source/i18n/number_skeletons.cpp b/deps/icu-small/source/i18n/number_skeletons.cpp
index 4c280ad11d..4025539239 100644
--- a/deps/icu-small/source/i18n/number_skeletons.cpp
+++ b/deps/icu-small/source/i18n/number_skeletons.cpp
@@ -20,6 +20,7 @@
#include "unicode/numberformatter.h"
#include "uinvchar.h"
#include "charstr.h"
+#include "string_segment.h"
using namespace icu;
using namespace icu::number;
@@ -119,17 +120,17 @@ inline void appendMultiple(UnicodeString& sb, UChar32 cp, int32_t count) {
#define CHECK_NULL(seen, field, status) (void)(seen); /* for auto-format line wrapping */ \
-{ \
+UPRV_BLOCK_MACRO_BEGIN { \
if ((seen).field) { \
(status) = U_NUMBER_SKELETON_SYNTAX_ERROR; \
return STATE_NULL; \
} \
(seen).field = true; \
-}
+} UPRV_BLOCK_MACRO_END
#define SKELETON_UCHAR_TO_CHAR(dest, src, start, end, status) (void)(dest); \
-{ \
+UPRV_BLOCK_MACRO_BEGIN { \
UErrorCode conversionStatus = U_ZERO_ERROR; \
(dest).appendInvariantChars({FALSE, (src).getBuffer() + (start), (end) - (start)}, conversionStatus); \
if (conversionStatus == U_INVARIANT_CONVERSION_ERROR) { \
@@ -140,7 +141,7 @@ inline void appendMultiple(UnicodeString& sb, UChar32 cp, int32_t count) {
(status) = conversionStatus; \
return; \
} \
-}
+} UPRV_BLOCK_MACRO_END
} // anonymous namespace
@@ -1217,7 +1218,7 @@ void blueprint_helpers::parseIntegerWidthOption(const StringSegment& segment, Ma
maxInt = 0;
}
for (; offset < segment.length(); offset++) {
- if (segment.charAt(offset) == u'#') {
+ if (maxInt != -1 && segment.charAt(offset) == u'#') {
maxInt++;
} else {
break;
diff --git a/deps/icu-small/source/i18n/number_skeletons.h b/deps/icu-small/source/i18n/number_skeletons.h
index bc228bd0d7..59af771928 100644
--- a/deps/icu-small/source/i18n/number_skeletons.h
+++ b/deps/icu-small/source/i18n/number_skeletons.h
@@ -10,10 +10,10 @@
#include "number_types.h"
#include "numparse_types.h"
#include "unicode/ucharstrie.h"
+#include "string_segment.h"
-using icu::numparse::impl::StringSegment;
-
-U_NAMESPACE_BEGIN namespace number {
+U_NAMESPACE_BEGIN
+namespace number {
namespace impl {
// Forward-declaration
diff --git a/deps/icu-small/source/i18n/number_stringbuilder.h b/deps/icu-small/source/i18n/number_stringbuilder.h
deleted file mode 100644
index d48f6e106c..0000000000
--- a/deps/icu-small/source/i18n/number_stringbuilder.h
+++ /dev/null
@@ -1,164 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-
-#include "unicode/utypes.h"
-
-#if !UCONFIG_NO_FORMATTING
-#ifndef __NUMBER_STRINGBUILDER_H__
-#define __NUMBER_STRINGBUILDER_H__
-
-
-#include <cstdint>
-#include "unicode/numfmt.h"
-#include "unicode/ustring.h"
-#include "cstring.h"
-#include "uassert.h"
-#include "number_types.h"
-#include "fphdlimp.h"
-
-U_NAMESPACE_BEGIN namespace number {
-namespace impl {
-
-class U_I18N_API NumberStringBuilder : public UMemory {
- private:
- static const int32_t DEFAULT_CAPACITY = 40;
-
- template<typename T>
- union ValueOrHeapArray {
- T value[DEFAULT_CAPACITY];
- struct {
- T *ptr;
- int32_t capacity;
- } heap;
- };
-
- public:
- NumberStringBuilder();
-
- ~NumberStringBuilder();
-
- NumberStringBuilder(const NumberStringBuilder &other);
-
- NumberStringBuilder &operator=(const NumberStringBuilder &other);
-
- int32_t length() const;
-
- int32_t codePointCount() const;
-
- inline char16_t charAt(int32_t index) const {
- U_ASSERT(index >= 0);
- U_ASSERT(index < fLength);
- return getCharPtr()[fZero + index];
- }
-
- inline Field fieldAt(int32_t index) const {
- U_ASSERT(index >= 0);
- U_ASSERT(index < fLength);
- return getFieldPtr()[fZero + index];
- }
-
- UChar32 getFirstCodePoint() const;
-
- UChar32 getLastCodePoint() const;
-
- UChar32 codePointAt(int32_t index) const;
-
- UChar32 codePointBefore(int32_t index) const;
-
- NumberStringBuilder &clear();
-
- int32_t appendCodePoint(UChar32 codePoint, Field field, UErrorCode &status);
-
- int32_t insertCodePoint(int32_t index, UChar32 codePoint, Field field, UErrorCode &status);
-
- int32_t append(const UnicodeString &unistr, Field field, UErrorCode &status);
-
- int32_t insert(int32_t index, const UnicodeString &unistr, Field field, UErrorCode &status);
-
- int32_t insert(int32_t index, const UnicodeString &unistr, int32_t start, int32_t end, Field field,
- UErrorCode &status);
-
- int32_t splice(int32_t startThis, int32_t endThis, const UnicodeString &unistr,
- int32_t startOther, int32_t endOther, Field field, UErrorCode& status);
-
- int32_t append(const NumberStringBuilder &other, UErrorCode &status);
-
- int32_t insert(int32_t index, const NumberStringBuilder &other, UErrorCode &status);
-
- void writeTerminator(UErrorCode& status);
-
- /**
- * Gets a "safe" UnicodeString that can be used even after the NumberStringBuilder is destructed.
- * */
- UnicodeString toUnicodeString() const;
-
- /**
- * Gets an "unsafe" UnicodeString that is valid only as long as the NumberStringBuilder is alive and
- * unchanged. Slightly faster than toUnicodeString().
- */
- const UnicodeString toTempUnicodeString() const;
-
- UnicodeString toDebugString() const;
-
- const char16_t *chars() const;
-
- bool contentEquals(const NumberStringBuilder &other) const;
-
- bool nextFieldPosition(FieldPosition& fp, UErrorCode& status) const;
-
- void getAllFieldPositions(FieldPositionIteratorHandler& fpih, UErrorCode& status) const;
-
- bool nextPosition(ConstrainedFieldPosition& cfpos, Field numericField, UErrorCode& status) const;
-
- bool containsField(Field field) const;
-
- private:
- bool fUsingHeap = false;
- ValueOrHeapArray<char16_t> fChars;
- ValueOrHeapArray<Field> fFields;
- int32_t fZero = DEFAULT_CAPACITY / 2;
- int32_t fLength = 0;
-
- inline char16_t *getCharPtr() {
- return fUsingHeap ? fChars.heap.ptr : fChars.value;
- }
-
- inline const char16_t *getCharPtr() const {
- return fUsingHeap ? fChars.heap.ptr : fChars.value;
- }
-
- inline Field *getFieldPtr() {
- return fUsingHeap ? fFields.heap.ptr : fFields.value;
- }
-
- inline const Field *getFieldPtr() const {
- return fUsingHeap ? fFields.heap.ptr : fFields.value;
- }
-
- inline int32_t getCapacity() const {
- return fUsingHeap ? fChars.heap.capacity : DEFAULT_CAPACITY;
- }
-
- int32_t prepareForInsert(int32_t index, int32_t count, UErrorCode &status);
-
- int32_t prepareForInsertHelper(int32_t index, int32_t count, UErrorCode &status);
-
- int32_t remove(int32_t index, int32_t count);
-
- static bool isIntOrGroup(Field field);
-
- static bool isNumericField(Field field);
-
- int32_t trimBack(int32_t limit) const;
-
- int32_t trimFront(int32_t start) const;
-};
-
-} // namespace impl
-} // namespace number
-U_NAMESPACE_END
-
-
-#endif //__NUMBER_STRINGBUILDER_H__
-
-#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/deps/icu-small/source/i18n/number_types.h b/deps/icu-small/source/i18n/number_types.h
index 225d1e5775..d62aa6a66b 100644
--- a/deps/icu-small/source/i18n/number_types.h
+++ b/deps/icu-small/source/i18n/number_types.h
@@ -17,17 +17,16 @@
#include "unicode/platform.h"
#include "unicode/uniset.h"
#include "standardplural.h"
+#include "formatted_string_builder.h"
-U_NAMESPACE_BEGIN namespace number {
+U_NAMESPACE_BEGIN
+namespace number {
namespace impl {
-// Typedef several enums for brevity and for easier comparison to Java.
+// For convenience and historical reasons, import the Field typedef to the namespace.
+typedef FormattedStringBuilder::Field Field;
-// Convention: bottom 4 bits for field, top 4 bits for field category.
-// Field category 0 implies the number category so that the number field
-// literals can be directly passed as a Field type.
-// See the helper functions in "NumFieldUtils" in number_utils.h
-typedef uint8_t Field;
+// Typedef several enums for brevity and for easier comparison to Java.
typedef UNumberFormatRoundingMode RoundingMode;
@@ -49,7 +48,6 @@ static constexpr char16_t kFallbackPaddingString[] = u" ";
class Modifier;
class MutablePatternModifier;
class DecimalQuantity;
-class NumberStringBuilder;
class ModifierStore;
struct MicroProps;
@@ -93,6 +91,12 @@ enum CompactType {
TYPE_DECIMAL, TYPE_CURRENCY
};
+enum Signum {
+ SIGNUM_NEG = -1,
+ SIGNUM_ZERO = 0,
+ SIGNUM_POS = 1
+};
+
class U_I18N_API AffixPatternProvider {
public:
@@ -160,7 +164,7 @@ class U_I18N_API Modifier {
* formatted.
* @return The number of characters (UTF-16 code units) that were added to the string builder.
*/
- virtual int32_t apply(NumberStringBuilder& output, int leftIndex, int rightIndex,
+ virtual int32_t apply(FormattedStringBuilder& output, int leftIndex, int rightIndex,
UErrorCode& status) const = 0;
/**
@@ -196,11 +200,11 @@ class U_I18N_API Modifier {
*/
struct U_I18N_API Parameters {
const ModifierStore* obj = nullptr;
- int8_t signum;
+ Signum signum;
StandardPlural::Form plural;
Parameters();
- Parameters(const ModifierStore* _obj, int8_t _signum, StandardPlural::Form _plural);
+ Parameters(const ModifierStore* _obj, Signum _signum, StandardPlural::Form _plural);
};
/**
@@ -231,7 +235,7 @@ class U_I18N_API ModifierStore {
/**
* Returns a Modifier with the given parameters (best-effort).
*/
- virtual const Modifier* getModifier(int8_t signum, StandardPlural::Form plural) const = 0;
+ virtual const Modifier* getModifier(Signum signum, StandardPlural::Form plural) const = 0;
};
diff --git a/deps/icu-small/source/i18n/number_utils.cpp b/deps/icu-small/source/i18n/number_utils.cpp
index 0983b7b072..91d7f335cd 100644
--- a/deps/icu-small/source/i18n/number_utils.cpp
+++ b/deps/icu-small/source/i18n/number_utils.cpp
@@ -252,4 +252,15 @@ bool DecNum::isZero() const {
return decNumberIsZero(fData.getAlias());
}
+void DecNum::toString(ByteSink& output, UErrorCode& status) const {
+ if (U_FAILURE(status)) {
+ return;
+ }
+ // "string must be at least dn->digits+14 characters long"
+ int32_t minCapacity = fData.getAlias()->digits + 14;
+ MaybeStackArray<char, 30> buffer(minCapacity);
+ uprv_decNumberToString(fData, buffer.getAlias());
+ output.Append(buffer.getAlias(), static_cast<int32_t>(uprv_strlen(buffer.getAlias())));
+}
+
#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/deps/icu-small/source/i18n/number_utils.h b/deps/icu-small/source/i18n/number_utils.h
index 203dec6d83..93195f080b 100644
--- a/deps/icu-small/source/i18n/number_utils.h
+++ b/deps/icu-small/source/i18n/number_utils.h
@@ -17,6 +17,7 @@
#include "number_roundingutils.h"
#include "decNumber.h"
#include "charstr.h"
+#include "formatted_string_builder.h"
U_NAMESPACE_BEGIN
@@ -32,52 +33,10 @@ enum CldrPatternStyle {
CLDR_PATTERN_STYLE_COUNT,
};
-
-/**
- * Helper functions for dealing with the Field typedef, which stores fields
- * in a compressed format.
- */
-class NumFieldUtils {
-public:
- struct CategoryFieldPair {
- int32_t category;
- int32_t field;
- };
-
- /** Compile-time function to construct a Field from a category and a field */
- template <int32_t category, int32_t field>
- static constexpr Field compress() {
- static_assert(category != 0, "cannot use Undefined category in NumFieldUtils");
- static_assert(category <= 0xf, "only 4 bits for category");
- static_assert(field <= 0xf, "only 4 bits for field");
- return static_cast<int8_t>((category << 4) | field);
- }
-
- /** Runtime inline function to unpack the category and field from the Field */
- static inline CategoryFieldPair expand(Field field) {
- if (field == UNUM_FIELD_COUNT) {
- return {UFIELD_CATEGORY_UNDEFINED, 0};
- }
- CategoryFieldPair ret = {
- (field >> 4),
- (field & 0xf)
- };
- if (ret.category == 0) {
- ret.category = UFIELD_CATEGORY_NUMBER;
- }
- return ret;
- }
-
- static inline bool isNumericField(Field field) {
- int8_t category = field >> 4;
- return category == 0 || category == UFIELD_CATEGORY_NUMBER;
- }
-};
-
// Namespace for naked functions
namespace utils {
-inline int32_t insertDigitFromSymbols(NumberStringBuilder& output, int32_t index, int8_t digit,
+inline int32_t insertDigitFromSymbols(FormattedStringBuilder& output, int32_t index, int8_t digit,
const DecimalFormatSymbols& symbols, Field field,
UErrorCode& status) {
if (symbols.getCodePointZero() != -1) {
diff --git a/deps/icu-small/source/i18n/number_utypes.h b/deps/icu-small/source/i18n/number_utypes.h
index 88b493cbc2..6dbe5bee68 100644
--- a/deps/icu-small/source/i18n/number_utypes.h
+++ b/deps/icu-small/source/i18n/number_utypes.h
@@ -10,7 +10,7 @@
#include "unicode/numberformatter.h"
#include "number_types.h"
#include "number_decimalquantity.h"
-#include "number_stringbuilder.h"
+#include "formatted_string_builder.h"
#include "formattedval_impl.h"
U_NAMESPACE_BEGIN namespace number {
@@ -31,9 +31,9 @@ const DecimalQuantity* validateUFormattedNumberToDecimalQuantity(
* The DecimalQuantity is not currently being used by FormattedNumber, but at some point it could be used
* to add a toDecNumber() or similar method.
*/
-class UFormattedNumberData : public FormattedValueNumberStringBuilderImpl {
+class UFormattedNumberData : public FormattedValueStringBuilderImpl {
public:
- UFormattedNumberData() : FormattedValueNumberStringBuilderImpl(0) {}
+ UFormattedNumberData() : FormattedValueStringBuilderImpl(0) {}
virtual ~UFormattedNumberData();
DecimalQuantity quantity;
diff --git a/deps/icu-small/source/i18n/numfmt.cpp b/deps/icu-small/source/i18n/numfmt.cpp
index 21efd18455..bf78179bcd 100644
--- a/deps/icu-small/source/i18n/numfmt.cpp
+++ b/deps/icu-small/source/i18n/numfmt.cpp
@@ -569,7 +569,7 @@ NumberFormat::format(const Formattable& obj,
if(arg.wasCurrency() && u_strcmp(iso, getCurrency())) {
// trying to format a different currency.
// Right now, we clone.
- LocalPointer<NumberFormat> cloneFmt((NumberFormat*)this->clone());
+ LocalPointer<NumberFormat> cloneFmt(this->clone());
cloneFmt->setCurrency(iso, status);
// next line should NOT recurse, because n is numeric whereas obj was a wrapper around currency amount.
return cloneFmt->format(*n, appendTo, pos, status);
@@ -624,7 +624,7 @@ NumberFormat::format(const Formattable& obj,
if(arg.wasCurrency() && u_strcmp(iso, getCurrency())) {
// trying to format a different currency.
// Right now, we clone.
- LocalPointer<NumberFormat> cloneFmt((NumberFormat*)this->clone());
+ LocalPointer<NumberFormat> cloneFmt(this->clone());
cloneFmt->setCurrency(iso, status);
// next line should NOT recurse, because n is numeric whereas obj was a wrapper around currency amount.
return cloneFmt->format(*n, appendTo, posIter, status);
@@ -986,15 +986,19 @@ static UBool haveService() {
URegistryKey U_EXPORT2
NumberFormat::registerFactory(NumberFormatFactory* toAdopt, UErrorCode& status)
{
- ICULocaleService *service = getNumberFormatService();
- if (service) {
- NFFactory *tempnnf = new NFFactory(toAdopt);
- if (tempnnf != NULL) {
- return service->registerFactory(tempnnf, status);
- }
- }
- status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
+ if (U_FAILURE(status)) {
+ delete toAdopt;
+ return nullptr;
+ }
+ ICULocaleService *service = getNumberFormatService();
+ if (service) {
+ NFFactory *tempnnf = new NFFactory(toAdopt);
+ if (tempnnf != NULL) {
+ return service->registerFactory(tempnnf, status);
+ }
+ }
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return NULL;
}
// -------------------------------------
@@ -1055,7 +1059,7 @@ NumberFormat::createInstance(const Locale& loc, UNumberFormatStyle kind, UErrorC
if (U_FAILURE(status)) {
return NULL;
}
- NumberFormat *result = static_cast<NumberFormat *>((*shared)->clone());
+ NumberFormat *result = (*shared)->clone();
shared->removeRef();
if (result == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
@@ -1362,7 +1366,7 @@ NumberFormat::makeInstance(const Locale& desiredLocale,
// TODO: Bad hash key usage, see ticket #8504.
int32_t hashKey = desiredLocale.hashCode();
- static icu::UMutex nscacheMutex = U_MUTEX_INITIALIZER;
+ static UMutex nscacheMutex;
Mutex lock(&nscacheMutex);
ns = (NumberingSystem *)uhash_iget(NumberingSystem_cache, hashKey);
if (ns == NULL) {
diff --git a/deps/icu-small/source/i18n/numparse_affixes.cpp b/deps/icu-small/source/i18n/numparse_affixes.cpp
index 12543a641b..4f83e0dd40 100644
--- a/deps/icu-small/source/i18n/numparse_affixes.cpp
+++ b/deps/icu-small/source/i18n/numparse_affixes.cpp
@@ -13,6 +13,7 @@
#include "numparse_affixes.h"
#include "numparse_utils.h"
#include "number_utils.h"
+#include "string_segment.h"
using namespace icu;
using namespace icu::numparse;
@@ -280,7 +281,9 @@ void AffixMatcherWarehouse::createAffixMatchers(const AffixPatternProvider& patt
AffixPatternMatcher* posSuffix = nullptr;
// Pre-process the affix strings to resolve LDML rules like sign display.
- for (int8_t signum = 1; signum >= -1; signum--) {
+ for (int8_t signumInt = 1; signumInt >= -1; signumInt--) {
+ auto signum = static_cast<Signum>(signumInt);
+
// Generate Prefix
bool hasPrefix = false;
PatternStringUtils::patternInfoToStringBuilder(
diff --git a/deps/icu-small/source/i18n/numparse_compositions.cpp b/deps/icu-small/source/i18n/numparse_compositions.cpp
index 19253da805..2f7e1ab28d 100644
--- a/deps/icu-small/source/i18n/numparse_compositions.cpp
+++ b/deps/icu-small/source/i18n/numparse_compositions.cpp
@@ -11,6 +11,7 @@
#include "numparse_types.h"
#include "numparse_compositions.h"
+#include "string_segment.h"
#include "unicode/uniset.h"
using namespace icu;
diff --git a/deps/icu-small/source/i18n/numparse_currency.cpp b/deps/icu-small/source/i18n/numparse_currency.cpp
index 598ace5653..6b53a73edf 100644
--- a/deps/icu-small/source/i18n/numparse_currency.cpp
+++ b/deps/icu-small/source/i18n/numparse_currency.cpp
@@ -14,6 +14,7 @@
#include "ucurrimp.h"
#include "unicode/errorcode.h"
#include "numparse_utils.h"
+#include "string_segment.h"
using namespace icu;
using namespace icu::numparse;
diff --git a/deps/icu-small/source/i18n/numparse_decimal.cpp b/deps/icu-small/source/i18n/numparse_decimal.cpp
index b120c5c6ad..cf1e815672 100644
--- a/deps/icu-small/source/i18n/numparse_decimal.cpp
+++ b/deps/icu-small/source/i18n/numparse_decimal.cpp
@@ -16,6 +16,7 @@
#include "unicode/uchar.h"
#include "putilimp.h"
#include "number_decimalquantity.h"
+#include "string_segment.h"
using namespace icu;
using namespace icu::numparse;
diff --git a/deps/icu-small/source/i18n/numparse_impl.cpp b/deps/icu-small/source/i18n/numparse_impl.cpp
index 412ea89c86..bf5829061a 100644
--- a/deps/icu-small/source/i18n/numparse_impl.cpp
+++ b/deps/icu-small/source/i18n/numparse_impl.cpp
@@ -39,7 +39,7 @@ NumberParserImpl::createSimpleParser(const Locale& locale, const UnicodeString&
LocalPointer<NumberParserImpl> parser(new NumberParserImpl(parseFlags));
DecimalFormatSymbols symbols(locale, status);
- parser->fLocalMatchers.ignorables = {unisets::DEFAULT_IGNORABLES};
+ parser->fLocalMatchers.ignorables = {parseFlags};
IgnorablesMatcher& ignorables = parser->fLocalMatchers.ignorables;
DecimalFormatSymbols dfs(locale, status);
@@ -114,6 +114,7 @@ NumberParserImpl::createParserFromProperties(const number::impl::DecimalFormatPr
parseFlags |= PARSE_FLAG_STRICT_SEPARATORS;
parseFlags |= PARSE_FLAG_USE_FULL_AFFIXES;
parseFlags |= PARSE_FLAG_EXACT_AFFIX;
+ parseFlags |= PARSE_FLAG_STRICT_IGNORABLES;
} else {
parseFlags |= PARSE_FLAG_INCLUDE_UNPAIRED_AFFIXES;
}
@@ -129,8 +130,7 @@ NumberParserImpl::createParserFromProperties(const number::impl::DecimalFormatPr
LocalPointer<NumberParserImpl> parser(new NumberParserImpl(parseFlags));
- parser->fLocalMatchers.ignorables = {
- isStrict ? unisets::STRICT_IGNORABLES : unisets::DEFAULT_IGNORABLES};
+ parser->fLocalMatchers.ignorables = {parseFlags};
IgnorablesMatcher& ignorables = parser->fLocalMatchers.ignorables;
//////////////////////
diff --git a/deps/icu-small/source/i18n/numparse_impl.h b/deps/icu-small/source/i18n/numparse_impl.h
index 7d5f0b6f0b..380d9aa4c6 100644
--- a/deps/icu-small/source/i18n/numparse_impl.h
+++ b/deps/icu-small/source/i18n/numparse_impl.h
@@ -18,6 +18,7 @@
#include "unicode/localpointer.h"
#include "numparse_validators.h"
#include "number_multiplier.h"
+#include "string_segment.h"
U_NAMESPACE_BEGIN
diff --git a/deps/icu-small/source/i18n/numparse_parsednumber.cpp b/deps/icu-small/source/i18n/numparse_parsednumber.cpp
index 3145f718dc..4b373a3c31 100644
--- a/deps/icu-small/source/i18n/numparse_parsednumber.cpp
+++ b/deps/icu-small/source/i18n/numparse_parsednumber.cpp
@@ -11,6 +11,7 @@
#include "numparse_types.h"
#include "number_decimalquantity.h"
+#include "string_segment.h"
#include "putilimp.h"
#include <cmath>
@@ -73,7 +74,7 @@ double ParsedNumber::getDouble(UErrorCode& status) const {
status = U_INVALID_STATE_ERROR;
return 0.0;
}
- if (quantity.isZero() && quantity.isNegative()) {
+ if (quantity.isZeroish() && quantity.isNegative()) {
return -0.0;
}
@@ -106,7 +107,7 @@ void ParsedNumber::populateFormattable(Formattable& output, parse_flags_t parseF
}
}
U_ASSERT(!quantity.bogus);
- if (quantity.isZero() && quantity.isNegative() && !integerOnly) {
+ if (quantity.isZeroish() && quantity.isNegative() && !integerOnly) {
output.setDouble(-0.0);
return;
}
diff --git a/deps/icu-small/source/i18n/numparse_scientific.cpp b/deps/icu-small/source/i18n/numparse_scientific.cpp
index de38957440..4b88cd998f 100644
--- a/deps/icu-small/source/i18n/numparse_scientific.cpp
+++ b/deps/icu-small/source/i18n/numparse_scientific.cpp
@@ -12,6 +12,7 @@
#include "numparse_types.h"
#include "numparse_scientific.h"
#include "static_unicode_sets.h"
+#include "string_segment.h"
using namespace icu;
using namespace icu::numparse;
@@ -33,7 +34,8 @@ inline const UnicodeSet& plusSignSet() {
ScientificMatcher::ScientificMatcher(const DecimalFormatSymbols& dfs, const Grouper& grouper)
: fExponentSeparatorString(dfs.getConstSymbol(DecimalFormatSymbols::kExponentialSymbol)),
- fExponentMatcher(dfs, grouper, PARSE_FLAG_INTEGER_ONLY | PARSE_FLAG_GROUPING_DISABLED) {
+ fExponentMatcher(dfs, grouper, PARSE_FLAG_INTEGER_ONLY | PARSE_FLAG_GROUPING_DISABLED),
+ fIgnorablesMatcher(PARSE_FLAG_STRICT_IGNORABLES) {
const UnicodeString& minusSign = dfs.getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
if (minusSignSet().contains(minusSign)) {
@@ -63,15 +65,25 @@ bool ScientificMatcher::match(StringSegment& segment, ParsedNumber& result, UErr
// First match the scientific separator, and then match another number after it.
// NOTE: This is guarded by the smoke test; no need to check fExponentSeparatorString length again.
- int overlap1 = segment.getCommonPrefixLength(fExponentSeparatorString);
- if (overlap1 == fExponentSeparatorString.length()) {
+ int32_t initialOffset = segment.getOffset();
+ int32_t overlap = segment.getCommonPrefixLength(fExponentSeparatorString);
+ if (overlap == fExponentSeparatorString.length()) {
// Full exponent separator match.
// First attempt to get a code point, returning true if we can't get one.
- if (segment.length() == overlap1) {
+ if (segment.length() == overlap) {
+ return true;
+ }
+ segment.adjustOffset(overlap);
+
+ // Allow ignorables before the sign.
+ // Note: call site is guarded by the segment.length() check above.
+ // Note: the ignorables matcher should not touch the result.
+ fIgnorablesMatcher.match(segment, result, status);
+ if (segment.length() == 0) {
+ segment.setOffset(initialOffset);
return true;
}
- segment.adjustOffset(overlap1);
// Allow a sign, and then try to match digits.
int8_t exponentSign = 1;
@@ -81,24 +93,37 @@ bool ScientificMatcher::match(StringSegment& segment, ParsedNumber& result, UErr
} else if (segment.startsWith(plusSignSet())) {
segment.adjustOffsetByCodePoint();
} else if (segment.startsWith(fCustomMinusSign)) {
- // Note: call site is guarded with startsWith, which returns false on empty string
- int32_t overlap2 = segment.getCommonPrefixLength(fCustomMinusSign);
- if (overlap2 != fCustomMinusSign.length()) {
- // Partial custom sign match; un-match the exponent separator.
- segment.adjustOffset(-overlap1);
+ overlap = segment.getCommonPrefixLength(fCustomMinusSign);
+ if (overlap != fCustomMinusSign.length()) {
+ // Partial custom sign match
+ segment.setOffset(initialOffset);
return true;
}
exponentSign = -1;
- segment.adjustOffset(overlap2);
+ segment.adjustOffset(overlap);
} else if (segment.startsWith(fCustomPlusSign)) {
- // Note: call site is guarded with startsWith, which returns false on empty string
- int32_t overlap2 = segment.getCommonPrefixLength(fCustomPlusSign);
- if (overlap2 != fCustomPlusSign.length()) {
- // Partial custom sign match; un-match the exponent separator.
- segment.adjustOffset(-overlap1);
+ overlap = segment.getCommonPrefixLength(fCustomPlusSign);
+ if (overlap != fCustomPlusSign.length()) {
+ // Partial custom sign match
+ segment.setOffset(initialOffset);
return true;
}
- segment.adjustOffset(overlap2);
+ segment.adjustOffset(overlap);
+ }
+
+ // Return true if the segment is empty.
+ if (segment.length() == 0) {
+ segment.setOffset(initialOffset);
+ return true;
+ }
+
+ // Allow ignorables after the sign.
+ // Note: call site is guarded by the segment.length() check above.
+ // Note: the ignorables matcher should not touch the result.
+ fIgnorablesMatcher.match(segment, result, status);
+ if (segment.length() == 0) {
+ segment.setOffset(initialOffset);
+ return true;
}
// We are supposed to accept E0 after NaN, so we need to make sure result.quantity is available.
@@ -112,12 +137,12 @@ bool ScientificMatcher::match(StringSegment& segment, ParsedNumber& result, UErr
// At least one exponent digit was matched.
result.flags |= FLAG_HAS_EXPONENT;
} else {
- // No exponent digits were matched; un-match the exponent separator.
- segment.adjustOffset(-overlap1);
+ // No exponent digits were matched
+ segment.setOffset(initialOffset);
}
return digitsReturnValue;
- } else if (overlap1 == segment.length()) {
+ } else if (overlap == segment.length()) {
// Partial exponent separator match
return true;
}
diff --git a/deps/icu-small/source/i18n/numparse_scientific.h b/deps/icu-small/source/i18n/numparse_scientific.h
index ddecf858af..5617c0c6a6 100644
--- a/deps/icu-small/source/i18n/numparse_scientific.h
+++ b/deps/icu-small/source/i18n/numparse_scientific.h
@@ -9,6 +9,7 @@
#include "numparse_types.h"
#include "numparse_decimal.h"
+#include "numparse_symbols.h"
#include "unicode/numberformatter.h"
using icu::number::impl::Grouper;
@@ -32,6 +33,7 @@ class ScientificMatcher : public NumberParseMatcher, public UMemory {
private:
UnicodeString fExponentSeparatorString;
DecimalMatcher fExponentMatcher;
+ IgnorablesMatcher fIgnorablesMatcher;
UnicodeString fCustomMinusSign;
UnicodeString fCustomPlusSign;
};
diff --git a/deps/icu-small/source/i18n/numparse_stringsegment.h b/deps/icu-small/source/i18n/numparse_stringsegment.h
deleted file mode 100644
index 7a84444d41..0000000000
--- a/deps/icu-small/source/i18n/numparse_stringsegment.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// © 2018 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-
-#include "unicode/utypes.h"
-
-#if !UCONFIG_NO_FORMATTING
-#ifndef __NUMPARSE_STRINGSEGMENT_H__
-#define __NUMPARSE_STRINGSEGMENT_H__
-
-#include "numparse_types.h"
-#include "number_types.h"
-#include "unicode/unistr.h"
-
-U_NAMESPACE_BEGIN
-namespace numparse {
-namespace impl {
-
-
-} // namespace impl
-} // namespace numparse
-U_NAMESPACE_END
-
-#endif //__NUMPARSE_STRINGSEGMENT_H__
-#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/deps/icu-small/source/i18n/numparse_symbols.cpp b/deps/icu-small/source/i18n/numparse_symbols.cpp
index e0daab9374..608f4f5c8b 100644
--- a/deps/icu-small/source/i18n/numparse_symbols.cpp
+++ b/deps/icu-small/source/i18n/numparse_symbols.cpp
@@ -12,6 +12,7 @@
#include "numparse_types.h"
#include "numparse_symbols.h"
#include "numparse_utils.h"
+#include "string_segment.h"
using namespace icu;
using namespace icu::numparse;
@@ -68,8 +69,12 @@ UnicodeString SymbolMatcher::toString() const {
}
-IgnorablesMatcher::IgnorablesMatcher(unisets::Key key)
- : SymbolMatcher({}, key) {
+IgnorablesMatcher::IgnorablesMatcher(parse_flags_t parseFlags) :
+ SymbolMatcher(
+ {},
+ (0 != (parseFlags & PARSE_FLAG_STRICT_IGNORABLES)) ?
+ unisets::STRICT_IGNORABLES :
+ unisets::DEFAULT_IGNORABLES) {
}
bool IgnorablesMatcher::isFlexible() const {
diff --git a/deps/icu-small/source/i18n/numparse_symbols.h b/deps/icu-small/source/i18n/numparse_symbols.h
index 8912ee95b0..beb133f7d0 100644
--- a/deps/icu-small/source/i18n/numparse_symbols.h
+++ b/deps/icu-small/source/i18n/numparse_symbols.h
@@ -50,7 +50,7 @@ class U_I18N_API IgnorablesMatcher : public SymbolMatcher {
public:
IgnorablesMatcher() = default; // WARNING: Leaves the object in an unusable state
- IgnorablesMatcher(unisets::Key key);
+ IgnorablesMatcher(parse_flags_t parseFlags);
bool isFlexible() const override;
diff --git a/deps/icu-small/source/i18n/numparse_types.h b/deps/icu-small/source/i18n/numparse_types.h
index f837d8d279..b4007c2ff5 100644
--- a/deps/icu-small/source/i18n/numparse_types.h
+++ b/deps/icu-small/source/i18n/numparse_types.h
@@ -9,12 +9,13 @@
#include "unicode/uobject.h"
#include "number_decimalquantity.h"
+#include "string_segment.h"
-U_NAMESPACE_BEGIN namespace numparse {
+U_NAMESPACE_BEGIN
+namespace numparse {
namespace impl {
// Forward-declarations
-class StringSegment;
class ParsedNumber;
typedef int32_t result_flags_t;
@@ -50,6 +51,7 @@ enum ParseFlags {
// PARSE_FLAG_FORCE_BIG_DECIMAL = 0x1000, // not used in ICU4C
PARSE_FLAG_NO_FOREIGN_CURRENCY = 0x2000,
PARSE_FLAG_ALLOW_INFINITE_RECURSION = 0x4000,
+ PARSE_FLAG_STRICT_IGNORABLES = 0x8000,
};
@@ -170,115 +172,6 @@ class U_I18N_API ParsedNumber {
/**
- * A mutable class allowing for a String with a variable offset and length. The charAt, length, and
- * subSequence methods all operate relative to the fixed offset into the String.
- *
- * @author sffc
- */
-// Exported as U_I18N_API for tests
-class U_I18N_API StringSegment : public UMemory {
- public:
- StringSegment(const UnicodeString& str, bool ignoreCase);
-
- int32_t getOffset() const;
-
- void setOffset(int32_t start);
-
- /**
- * Equivalent to <code>setOffset(getOffset()+delta)</code>.
- *
- * <p>
- * This method is usually called by a Matcher to register that a char was consumed. If the char is
- * strong (it usually is, except for things like whitespace), follow this with a call to
- * {@link ParsedNumber#setCharsConsumed}. For more information on strong chars, see that method.
- */
- void adjustOffset(int32_t delta);
-
- /**
- * Adjusts the offset by the width of the current code point, either 1 or 2 chars.
- */
- void adjustOffsetByCodePoint();
-
- void setLength(int32_t length);
-
- void resetLength();
-
- int32_t length() const;
-
- char16_t charAt(int32_t index) const;
-
- UChar32 codePointAt(int32_t index) const;
-
- UnicodeString toUnicodeString() const;
-
- const UnicodeString toTempUnicodeString() const;
-
- /**
- * Returns the first code point in the string segment, or -1 if the string starts with an invalid
- * code point.
- *
- * <p>
- * <strong>Important:</strong> Most of the time, you should use {@link #matches}, which handles case
- * folding logic, instead of this method.
- */
- UChar32 getCodePoint() const;
-
- /**
- * Returns true if the first code point of this StringSegment equals the given code point.
- *
- * <p>
- * This method will perform case folding if case folding is enabled for the parser.
- */
- bool startsWith(UChar32 otherCp) const;
-
- /**
- * Returns true if the first code point of this StringSegment is in the given UnicodeSet.
- */
- bool startsWith(const UnicodeSet& uniset) const;
-
- /**
- * Returns true if there is at least one code point of overlap between this StringSegment and the
- * given UnicodeString.
- */
- bool startsWith(const UnicodeString& other) const;
-
- /**
- * Returns the length of the prefix shared by this StringSegment and the given CharSequence. For
- * example, if this string segment is "aab", and the char sequence is "aac", this method returns 2,
- * since the first 2 characters are the same.
- *
- * <p>
- * This method only returns offsets along code point boundaries.
- *
- * <p>
- * This method will perform case folding if case folding was enabled in the constructor.
- *
- * <p>
- * IMPORTANT: The given UnicodeString must not be empty! It is the caller's responsibility to check.
- */
- int32_t getCommonPrefixLength(const UnicodeString& other);
-
- /**
- * Like {@link #getCommonPrefixLength}, but never performs case folding, even if case folding is
- * enabled for the parser.
- */
- int32_t getCaseSensitivePrefixLength(const UnicodeString& other);
-
- bool operator==(const UnicodeString& other) const;
-
- private:
- const UnicodeString& fStr;
- int32_t fStart;
- int32_t fEnd;
- bool fFoldCase;
-
- int32_t getPrefixLengthInternal(const UnicodeString& other, bool foldCase);
-
- static bool codePointsEqual(UChar32 cp1, UChar32 cp2, bool foldCase);
-};
-
-
-/**
* The core interface implemented by all matchers used for number parsing.
*
* Given a string, there should NOT be more than one way to consume the string with the same matcher
diff --git a/deps/icu-small/source/i18n/numrange_fluent.cpp b/deps/icu-small/source/i18n/numrange_fluent.cpp
index b284561cdc..654cafaf00 100644
--- a/deps/icu-small/source/i18n/numrange_fluent.cpp
+++ b/deps/icu-small/source/i18n/numrange_fluent.cpp
@@ -382,7 +382,7 @@ UPRV_FORMATTED_VALUE_SUBCLASS_AUTO_IMPL(FormattedNumberRange)
UBool FormattedNumberRange::nextFieldPosition(FieldPosition& fieldPosition, UErrorCode& status) const {
UPRV_FORMATTED_VALUE_METHOD_GUARD(FALSE)
// NOTE: MSVC sometimes complains when implicitly converting between bool and UBool
- return fData->getStringRef().nextFieldPosition(fieldPosition, status) ? TRUE : FALSE;
+ return fData->nextFieldPosition(fieldPosition, status);
}
void FormattedNumberRange::getAllFieldPositions(FieldPositionIterator& iterator, UErrorCode& status) const {
@@ -393,7 +393,7 @@ void FormattedNumberRange::getAllFieldPositions(FieldPositionIterator& iterator,
void FormattedNumberRange::getAllFieldPositionsImpl(
FieldPositionIteratorHandler& fpih, UErrorCode& status) const {
UPRV_FORMATTED_VALUE_METHOD_GUARD(UPRV_NOARG)
- fData->getStringRef().getAllFieldPositions(fpih, status);
+ fData->getAllFieldPositions(fpih, status);
}
UnicodeString FormattedNumberRange::getFirstDecimal(UErrorCode& status) const {
diff --git a/deps/icu-small/source/i18n/numrange_impl.cpp b/deps/icu-small/source/i18n/numrange_impl.cpp
index 05eb2b84de..7d732b31ec 100644
--- a/deps/icu-small/source/i18n/numrange_impl.cpp
+++ b/deps/icu-small/source/i18n/numrange_impl.cpp
@@ -397,7 +397,7 @@ void NumberRangeFormatterImpl::formatRange(UFormattedNumberRangeData& data,
break;
}
- NumberStringBuilder& string = data.getStringRef();
+ FormattedStringBuilder& string = data.getStringRef();
int32_t lengthPrefix = 0;
int32_t length1 = 0;
int32_t lengthInfix = 0;
diff --git a/deps/icu-small/source/i18n/numrange_impl.h b/deps/icu-small/source/i18n/numrange_impl.h
index dc25dd4d67..f88e300913 100644
--- a/deps/icu-small/source/i18n/numrange_impl.h
+++ b/deps/icu-small/source/i18n/numrange_impl.h
@@ -13,7 +13,7 @@
#include "number_types.h"
#include "number_decimalquantity.h"
#include "number_formatimpl.h"
-#include "number_stringbuilder.h"
+#include "formatted_string_builder.h"
#include "formattedval_impl.h"
U_NAMESPACE_BEGIN namespace number {
@@ -29,9 +29,9 @@ namespace impl {
* Possible magic number: 0x46445200
* Reads in ASCII as "FDR" (FormatteDnumberRange with room at the end)
*/
-class UFormattedNumberRangeData : public FormattedValueNumberStringBuilderImpl {
+class UFormattedNumberRangeData : public FormattedValueStringBuilderImpl {
public:
- UFormattedNumberRangeData() : FormattedValueNumberStringBuilderImpl(0) {}
+ UFormattedNumberRangeData() : FormattedValueStringBuilderImpl(0) {}
virtual ~UFormattedNumberRangeData();
DecimalQuantity quantity1;
diff --git a/deps/icu-small/source/i18n/numsys.cpp b/deps/icu-small/source/i18n/numsys.cpp
index 80056f925b..e3fe54bc1b 100644
--- a/deps/icu-small/source/i18n/numsys.cpp
+++ b/deps/icu-small/source/i18n/numsys.cpp
@@ -37,7 +37,7 @@ U_NAMESPACE_BEGIN
// Useful constants
-#define DEFAULT_DIGITS UNICODE_STRING_SIMPLE("0123456789");
+#define DEFAULT_DIGITS UNICODE_STRING_SIMPLE("0123456789")
static const char gNumberingSystems[] = "numberingSystems";
static const char gNumberElements[] = "NumberElements";
static const char gDefault[] = "default";
diff --git a/deps/icu-small/source/i18n/olsontz.cpp b/deps/icu-small/source/i18n/olsontz.cpp
index 95fc56bcd7..dd01180f8c 100644
--- a/deps/icu-small/source/i18n/olsontz.cpp
+++ b/deps/icu-small/source/i18n/olsontz.cpp
@@ -287,8 +287,7 @@ OlsonTimeZone& OlsonTimeZone::operator=(const OlsonTimeZone& other) {
typeMapData = other.typeMapData;
delete finalZone;
- finalZone = (other.finalZone != 0) ?
- (SimpleTimeZone*) other.finalZone->clone() : 0;
+ finalZone = (other.finalZone != 0) ? other.finalZone->clone() : 0;
finalStartYear = other.finalStartYear;
finalStartMillis = other.finalStartMillis;
@@ -319,7 +318,7 @@ UBool OlsonTimeZone::operator==(const TimeZone& other) const {
/**
* TimeZone API.
*/
-TimeZone* OlsonTimeZone::clone() const {
+OlsonTimeZone* OlsonTimeZone::clone() const {
return new OlsonTimeZone(*this);
}
@@ -816,7 +815,7 @@ OlsonTimeZone::initTransitionRules(UErrorCode& status) {
* For now, we do not set the valid start year when the construction time
* and create a clone and set the start year when extracting rules.
*/
- finalZoneWithStartYear = (SimpleTimeZone*)finalZone->clone();
+ finalZoneWithStartYear = finalZone->clone();
// Check to make sure finalZone was actually cloned.
if (finalZoneWithStartYear == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
@@ -837,7 +836,7 @@ OlsonTimeZone::initTransitionRules(UErrorCode& status) {
startTime = tzt.getTime();
} else {
// final rule with no transitions
- finalZoneWithStartYear = (SimpleTimeZone*)finalZone->clone();
+ finalZoneWithStartYear = finalZone->clone();
// Check to make sure finalZone was actually cloned.
if (finalZoneWithStartYear == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
diff --git a/deps/icu-small/source/i18n/olsontz.h b/deps/icu-small/source/i18n/olsontz.h
index 6f0d36e5de..7960154698 100644
--- a/deps/icu-small/source/i18n/olsontz.h
+++ b/deps/icu-small/source/i18n/olsontz.h
@@ -151,7 +151,7 @@ class U_I18N_API OlsonTimeZone: public BasicTimeZone {
/**
* TimeZone API.
*/
- virtual TimeZone* clone() const;
+ virtual OlsonTimeZone* clone() const;
/**
* TimeZone API.
@@ -398,7 +398,7 @@ private:
TimeArrayTimeZoneRule **historicRules;
int16_t historicRuleCount;
SimpleTimeZone *finalZoneWithStartYear; // hack
- UInitOnce transitionRulesInitOnce;
+ UInitOnce transitionRulesInitOnce = U_INITONCE_INITIALIZER;
};
inline int16_t
diff --git a/deps/icu-small/source/i18n/persncal.cpp b/deps/icu-small/source/i18n/persncal.cpp
index 3d391f4e3f..4d366d41f0 100644
--- a/deps/icu-small/source/i18n/persncal.cpp
+++ b/deps/icu-small/source/i18n/persncal.cpp
@@ -74,7 +74,7 @@ const char *PersianCalendar::getType() const {
return "persian";
}
-Calendar* PersianCalendar::clone() const {
+PersianCalendar* PersianCalendar::clone() const {
return new PersianCalendar(*this);
}
diff --git a/deps/icu-small/source/i18n/persncal.h b/deps/icu-small/source/i18n/persncal.h
index ec818822b3..a9d940db78 100644
--- a/deps/icu-small/source/i18n/persncal.h
+++ b/deps/icu-small/source/i18n/persncal.h
@@ -164,7 +164,7 @@ class PersianCalendar : public Calendar {
// TODO: copy c'tor, etc
// clone
- virtual Calendar* clone() const;
+ virtual PersianCalendar* clone() const;
private:
/**
diff --git a/deps/icu-small/source/i18n/plurfmt.cpp b/deps/icu-small/source/i18n/plurfmt.cpp
index 678d91b9c8..b99437630e 100644
--- a/deps/icu-small/source/i18n/plurfmt.cpp
+++ b/deps/icu-small/source/i18n/plurfmt.cpp
@@ -159,7 +159,7 @@ PluralFormat::copyObjects(const PluralFormat& other) {
if (other.numberFormat == NULL) {
numberFormat = NumberFormat::createInstance(locale, status);
} else {
- numberFormat = (NumberFormat*)other.numberFormat->clone();
+ numberFormat = other.numberFormat->clone();
}
if (other.pluralRulesWrapper.pluralRules == NULL) {
pluralRulesWrapper.pluralRules = PluralRules::forLocale(locale, status);
@@ -277,7 +277,14 @@ PluralFormat::format(const Formattable& numberObject, double number,
UnicodeString numberString;
auto *decFmt = dynamic_cast<DecimalFormat *>(numberFormat);
if(decFmt != nullptr) {
- decFmt->toNumberFormatter().formatImpl(&data, status); // mutates &data
+ const number::LocalizedNumberFormatter* lnf = decFmt->toNumberFormatter(status);
+ if (U_FAILURE(status)) {
+ return appendTo;
+ }
+ lnf->formatImpl(&data, status); // mutates &data
+ if (U_FAILURE(status)) {
+ return appendTo;
+ }
numberString = data.getStringRef().toUnicodeString();
} else {
if (offset == 0) {
@@ -346,7 +353,7 @@ PluralFormat::setNumberFormat(const NumberFormat* format, UErrorCode& status) {
if (U_FAILURE(status)) {
return;
}
- NumberFormat* nf = (NumberFormat*)format->clone();
+ NumberFormat* nf = format->clone();
if (nf != NULL) {
delete numberFormat;
numberFormat = nf;
@@ -355,7 +362,7 @@ PluralFormat::setNumberFormat(const NumberFormat* format, UErrorCode& status) {
}
}
-Format*
+PluralFormat*
PluralFormat::clone() const
{
return new PluralFormat(*this);
diff --git a/deps/icu-small/source/i18n/quant.cpp b/deps/icu-small/source/i18n/quant.cpp
index 1908a50484..b0e7a3ed52 100644
--- a/deps/icu-small/source/i18n/quant.cpp
+++ b/deps/icu-small/source/i18n/quant.cpp
@@ -47,7 +47,7 @@ Quantifier::~Quantifier() {
/**
* Implement UnicodeFunctor
*/
-UnicodeFunctor* Quantifier::clone() const {
+Quantifier* Quantifier::clone() const {
return new Quantifier(*this);
}
diff --git a/deps/icu-small/source/i18n/quant.h b/deps/icu-small/source/i18n/quant.h
index 1abb0db61a..d5aa8e5eee 100644
--- a/deps/icu-small/source/i18n/quant.h
+++ b/deps/icu-small/source/i18n/quant.h
@@ -45,7 +45,7 @@ class Quantifier : public UnicodeFunctor, public UnicodeMatcher {
* Implement UnicodeFunctor
* @return a copy of the object.
*/
- virtual UnicodeFunctor* clone() const;
+ virtual Quantifier* clone() const;
/**
* Implement UnicodeMatcher
diff --git a/deps/icu-small/source/i18n/quantityformatter.cpp b/deps/icu-small/source/i18n/quantityformatter.cpp
index 9182f9e7d3..e88b70fbd7 100644
--- a/deps/icu-small/source/i18n/quantityformatter.cpp
+++ b/deps/icu-small/source/i18n/quantityformatter.cpp
@@ -26,7 +26,7 @@
#include "uassert.h"
#include "number_decimalquantity.h"
#include "number_utypes.h"
-#include "number_stringbuilder.h"
+#include "formatted_string_builder.h"
U_NAMESPACE_BEGIN
@@ -180,7 +180,7 @@ void QuantityFormatter::formatAndSelect(
double quantity,
const NumberFormat& fmt,
const PluralRules& rules,
- number::impl::NumberStringBuilder& output,
+ FormattedStringBuilder& output,
StandardPlural::Form& pluralForm,
UErrorCode& status) {
UnicodeString pluralKeyword;
@@ -188,7 +188,11 @@ void QuantityFormatter::formatAndSelect(
if (df != nullptr) {
number::impl::UFormattedNumberData fn;
fn.quantity.setToDouble(quantity);
- df->toNumberFormatter().formatImpl(&fn, status);
+ const number::LocalizedNumberFormatter* lnf = df->toNumberFormatter(status);
+ if (U_FAILURE(status)) {
+ return;
+ }
+ lnf->formatImpl(&fn, status);
if (U_FAILURE(status)) {
return;
}
diff --git a/deps/icu-small/source/i18n/quantityformatter.h b/deps/icu-small/source/i18n/quantityformatter.h
index 3e3f29de57..88c3f3844e 100644
--- a/deps/icu-small/source/i18n/quantityformatter.h
+++ b/deps/icu-small/source/i18n/quantityformatter.h
@@ -26,12 +26,7 @@ class PluralRules;
class NumberFormat;
class Formattable;
class FieldPosition;
-
-namespace number {
-namespace impl {
-class NumberStringBuilder;
-}
-}
+class FormattedStringBuilder;
/**
* A plural aware formatter that is good for expressing a single quantity and
@@ -129,7 +124,7 @@ public:
/**
* Formats a quantity and selects its plural form. The output is appended
- * to a NumberStringBuilder in order to retain field information.
+ * to a FormattedStringBuilder in order to retain field information.
*
* @param quantity The number to format.
* @param fmt The formatter to use to format the number.
@@ -144,7 +139,7 @@ public:
double quantity,
const NumberFormat& fmt,
const PluralRules& rules,
- number::impl::NumberStringBuilder& output,
+ FormattedStringBuilder& output,
StandardPlural::Form& pluralForm,
UErrorCode& status);
diff --git a/deps/icu-small/source/i18n/rbnf.cpp b/deps/icu-small/source/i18n/rbnf.cpp
index 74707ccd22..c25e61e6b2 100644
--- a/deps/icu-small/source/i18n/rbnf.cpp
+++ b/deps/icu-small/source/i18n/rbnf.cpp
@@ -355,10 +355,16 @@ private:
};
#ifdef RBNF_DEBUG
-#define ERROR(msg) parseError(msg); return NULL;
+#define ERROR(msg) UPRV_BLOCK_MACRO_BEGIN { \
+ parseError(msg); \
+ return NULL; \
+} UPRV_BLOCK_MACRO_END
#define EXPLANATION_ARG explanationArg
#else
-#define ERROR(msg) parseError(NULL); return NULL;
+#define ERROR(msg) UPRV_BLOCK_MACRO_BEGIN { \
+ parseError(NULL); \
+ return NULL; \
+} UPRV_BLOCK_MACRO_END
#define EXPLANATION_ARG
#endif
@@ -924,8 +930,8 @@ RuleBasedNumberFormat::~RuleBasedNumberFormat()
dispose();
}
-Format*
-RuleBasedNumberFormat::clone(void) const
+RuleBasedNumberFormat*
+RuleBasedNumberFormat::clone() const
{
return new RuleBasedNumberFormat(*this);
}
@@ -1112,45 +1118,6 @@ RuleBasedNumberFormat::findRuleSet(const UnicodeString& name, UErrorCode& status
UnicodeString&
RuleBasedNumberFormat::format(const DecimalQuantity &number,
- UnicodeString &appendTo,
- FieldPositionIterator *posIter,
- UErrorCode &status) const {
- if (U_FAILURE(status)) {
- return appendTo;
- }
- DecimalQuantity copy(number);
- if (copy.fitsInLong()) {
- format(number.toLong(), appendTo, posIter, status);
- }
- else {
- copy.roundToMagnitude(0, number::impl::RoundingMode::UNUM_ROUND_HALFEVEN, status);
- if (copy.fitsInLong()) {
- format(number.toDouble(), appendTo, posIter, status);
- }
- else {
- // We're outside of our normal range that this framework can handle.
- // The DecimalFormat will provide more accurate results.
-
- // TODO this section should probably be optimized. The DecimalFormat is shared in ICU4J.
- LocalPointer<NumberFormat> decimalFormat(NumberFormat::createInstance(locale, UNUM_DECIMAL, status), status);
- if (decimalFormat.isNull()) {
- return appendTo;
- }
- Formattable f;
- LocalPointer<DecimalQuantity> decimalQuantity(new DecimalQuantity(number), status);
- if (decimalQuantity.isNull()) {
- return appendTo;
- }
- f.adoptDecimalQuantity(decimalQuantity.orphan()); // f now owns decimalQuantity.
- decimalFormat->format(f, appendTo, posIter, status);
- }
- }
- return appendTo;
-}
-
-
-UnicodeString&
-RuleBasedNumberFormat::format(const DecimalQuantity &number,
UnicodeString& appendTo,
FieldPosition& pos,
UErrorCode &status) const {
diff --git a/deps/icu-small/source/i18n/rbt.cpp b/deps/icu-small/source/i18n/rbt.cpp
index 8ba6a60ff4..02d0ce6ceb 100644
--- a/deps/icu-small/source/i18n/rbt.cpp
+++ b/deps/icu-small/source/i18n/rbt.cpp
@@ -191,8 +191,8 @@ RuleBasedTransliterator::~RuleBasedTransliterator() {
}
}
-Transliterator* // Covariant return NOT ALLOWED (for portability)
-RuleBasedTransliterator::clone(void) const {
+RuleBasedTransliterator*
+RuleBasedTransliterator::clone() const {
return new RuleBasedTransliterator(*this);
}
@@ -253,7 +253,7 @@ RuleBasedTransliterator::handleTransliterate(Replaceable& text, UTransPosition&
//
// TODO(andy): Need a better scheme for handling this.
- static UMutex transliteratorDataMutex = U_MUTEX_INITIALIZER;
+ static UMutex transliteratorDataMutex;
UBool needToLock;
{
Mutex m;
diff --git a/deps/icu-small/source/i18n/rbt.h b/deps/icu-small/source/i18n/rbt.h
index a18452ab2e..b450dc23f4 100644
--- a/deps/icu-small/source/i18n/rbt.h
+++ b/deps/icu-small/source/i18n/rbt.h
@@ -144,7 +144,7 @@ public:
* Implement Transliterator API.
* @internal Use transliterator factory methods instead since this class will be removed in that release.
*/
- virtual Transliterator* clone(void) const;
+ virtual RuleBasedTransliterator* clone() const;
protected:
/**
diff --git a/deps/icu-small/source/i18n/rbt_pars.cpp b/deps/icu-small/source/i18n/rbt_pars.cpp
index e07cc8b63a..3eb58a2a90 100644
--- a/deps/icu-small/source/i18n/rbt_pars.cpp
+++ b/deps/icu-small/source/i18n/rbt_pars.cpp
@@ -1111,7 +1111,7 @@ void TransliteratorParser::parseRules(const UnicodeString& rule,
int32_t p = UHASH_FIRST;
const UHashElement* he = variableNames.nextElement(p);
while (he != NULL) {
- UnicodeString* tempus = (UnicodeString*)(((UnicodeString*)(he->value.pointer))->clone());
+ UnicodeString* tempus = ((UnicodeString*)(he->value.pointer))->clone();
if (tempus == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
return;
diff --git a/deps/icu-small/source/i18n/rbt_rule.cpp b/deps/icu-small/source/i18n/rbt_rule.cpp
index db02f76035..cd7bd5d9df 100644
--- a/deps/icu-small/source/i18n/rbt_rule.cpp
+++ b/deps/icu-small/source/i18n/rbt_rule.cpp
@@ -180,13 +180,13 @@ TransliterationRule::TransliterationRule(TransliterationRule& other) :
}
if (other.anteContext != NULL) {
- anteContext = (StringMatcher*) other.anteContext->clone();
+ anteContext = other.anteContext->clone();
}
if (other.key != NULL) {
- key = (StringMatcher*) other.key->clone();
+ key = other.key->clone();
}
if (other.postContext != NULL) {
- postContext = (StringMatcher*) other.postContext->clone();
+ postContext = other.postContext->clone();
}
output = other.output->clone();
}
diff --git a/deps/icu-small/source/i18n/rbtz.cpp b/deps/icu-small/source/i18n/rbtz.cpp
index b8dca395fc..2c3747abda 100644
--- a/deps/icu-small/source/i18n/rbtz.cpp
+++ b/deps/icu-small/source/i18n/rbtz.cpp
@@ -149,7 +149,7 @@ RuleBasedTimeZone::addTransitionRule(TimeZoneRule* rule, UErrorCode& status) {
void
RuleBasedTimeZone::completeConst(UErrorCode& status) const {
- static UMutex gLock = U_MUTEX_INITIALIZER;
+ static UMutex gLock;
if (U_FAILURE(status)) {
return;
}
@@ -356,8 +356,8 @@ cleanup:
fUpToDate = FALSE;
}
-TimeZone*
-RuleBasedTimeZone::clone(void) const {
+RuleBasedTimeZone*
+RuleBasedTimeZone::clone() const {
return new RuleBasedTimeZone(*this);
}
diff --git a/deps/icu-small/source/i18n/regexcmp.cpp b/deps/icu-small/source/i18n/regexcmp.cpp
index 8d60986fd3..3a6368b07a 100644
--- a/deps/icu-small/source/i18n/regexcmp.cpp
+++ b/deps/icu-small/source/i18n/regexcmp.cpp
@@ -561,7 +561,7 @@ UBool RegexCompile::doParseActions(int32_t action)
// sequence; don't change without making updates there too.
//
// Compiles to
- // 1 START_LA dataLoc Saves SP, Input Pos
+ // 1 LA_START dataLoc Saves SP, Input Pos, Active input region.
// 2. STATE_SAVE 4 on failure of lookahead, goto 4
// 3 JMP 6 continue ...
//
@@ -575,10 +575,14 @@ UBool RegexCompile::doParseActions(int32_t action)
// 8. code for parenthesized stuff.
// 9. LA_END
//
- // Two data slots are reserved, for saving the stack ptr and the input position.
+ // Four data slots are reserved, for saving state on entry to the look-around
+ // 0: stack pointer on entry.
+ // 1: input position on entry.
+ // 2: fActiveStart, the active bounds start on entry.
+ // 3: fActiveLimit, the active bounds limit on entry.
{
fixLiterals();
- int32_t dataLoc = allocateData(2);
+ int32_t dataLoc = allocateData(4);
appendOp(URX_LA_START, dataLoc);
appendOp(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+ 2);
appendOp(URX_JMP, fRXPat->fCompiledPat->size()+ 3);
@@ -599,18 +603,23 @@ UBool RegexCompile::doParseActions(int32_t action)
case doOpenLookAheadNeg:
// Negated Lookahead. (?! stuff )
// Compiles to
- // 1. START_LA dataloc
+ // 1. LA_START dataloc
// 2. SAVE_STATE 7 // Fail within look-ahead block restores to this state,
// // which continues with the match.
// 3. NOP // Std. Open Paren sequence, for possible '|'
// 4. code for parenthesized stuff.
- // 5. END_LA // Cut back stack, remove saved state from step 2.
+ // 5. LA_END // Cut back stack, remove saved state from step 2.
// 6. BACKTRACK // code in block succeeded, so neg. lookahead fails.
// 7. END_LA // Restore match region, in case look-ahead was using
// an alternate (transparent) region.
+ // Four data slots are reserved, for saving state on entry to the look-around
+ // 0: stack pointer on entry.
+ // 1: input position on entry.
+ // 2: fActiveStart, the active bounds start on entry.
+ // 3: fActiveLimit, the active bounds limit on entry.
{
fixLiterals();
- int32_t dataLoc = allocateData(2);
+ int32_t dataLoc = allocateData(4);
appendOp(URX_LA_START, dataLoc);
appendOp(URX_STATE_SAVE, 0); // dest address will be patched later.
appendOp(URX_NOP, 0);
@@ -644,14 +653,16 @@ UBool RegexCompile::doParseActions(int32_t action)
// Allocate a block of matcher data, to contain (when running a match)
// 0: Stack ptr on entry
// 1: Input Index on entry
- // 2: Start index of match current match attempt.
- // 3: Original Input String len.
+ // 2: fActiveStart, the active bounds start on entry.
+ // 3: fActiveLimit, the active bounds limit on entry.
+ // 4: Start index of match current match attempt.
+ // The first four items must match the layout of data for LA_START / LA_END
// Generate match code for any pending literals.
fixLiterals();
// Allocate data space
- int32_t dataLoc = allocateData(4);
+ int32_t dataLoc = allocateData(5);
// Emit URX_LB_START
appendOp(URX_LB_START, dataLoc);
@@ -696,14 +707,16 @@ UBool RegexCompile::doParseActions(int32_t action)
// Allocate a block of matcher data, to contain (when running a match)
// 0: Stack ptr on entry
// 1: Input Index on entry
- // 2: Start index of match current match attempt.
- // 3: Original Input String len.
+ // 2: fActiveStart, the active bounds start on entry.
+ // 3: fActiveLimit, the active bounds limit on entry.
+ // 4: Start index of match current match attempt.
+ // The first four items must match the layout of data for LA_START / LA_END
// Generate match code for any pending literals.
fixLiterals();
// Allocate data space
- int32_t dataLoc = allocateData(4);
+ int32_t dataLoc = allocateData(5);
// Emit URX_LB_START
appendOp(URX_LB_START, dataLoc);
@@ -2285,7 +2298,7 @@ void RegexCompile::handleCloseParen() {
error(U_REGEX_LOOK_BEHIND_LIMIT);
break;
}
- if (minML == INT32_MAX && maxML == 0) {
+ if (minML == INT32_MAX) {
// This condition happens when no match is possible, such as with a
// [set] expression containing no elements.
// In principle, the generated code to evaluate the expression could be deleted,
@@ -2328,7 +2341,7 @@ void RegexCompile::handleCloseParen() {
error(U_REGEX_LOOK_BEHIND_LIMIT);
break;
}
- if (minML == INT32_MAX && maxML == 0) {
+ if (minML == INT32_MAX) {
// This condition happens when no match is possible, such as with a
// [set] expression containing no elements.
// In principle, the generated code to evaluate the expression could be deleted,
@@ -3381,7 +3394,7 @@ int32_t RegexCompile::minMatchLength(int32_t start, int32_t end) {
// it assumes that the look-ahead match might be zero-length.
// TODO: Positive lookahead could recursively do the block, then continue
// with the longer of the block or the value coming in. Ticket 6060
- int32_t depth = (opType == URX_LA_START? 2: 1);;
+ int32_t depth = (opType == URX_LA_START? 2: 1);
for (;;) {
loc++;
op = (int32_t)fRXPat->fCompiledPat->elementAti(loc);
@@ -3463,7 +3476,6 @@ int32_t RegexCompile::maxMatchLength(int32_t start, int32_t end) {
U_ASSERT(start <= end);
U_ASSERT(end < fRXPat->fCompiledPat->size());
-
int32_t loc;
int32_t op;
int32_t opType;
@@ -3672,7 +3684,7 @@ int32_t RegexCompile::maxMatchLength(int32_t start, int32_t end) {
case URX_CTR_LOOP:
case URX_CTR_LOOP_NG:
- // These opcodes will be skipped over by code for URX_CRT_INIT.
+ // These opcodes will be skipped over by code for URX_CTR_INIT.
// We shouldn't encounter them here.
UPRV_UNREACHABLE;
@@ -3700,21 +3712,15 @@ int32_t RegexCompile::maxMatchLength(int32_t start, int32_t end) {
{
// Look-behind. Scan forward until the matching look-around end,
// without processing the look-behind block.
- int32_t depth = 0;
- for (;;) {
- loc++;
+ int32_t dataLoc = URX_VAL(op);
+ for (loc = loc + 1; loc < end; ++loc) {
op = (int32_t)fRXPat->fCompiledPat->elementAti(loc);
- if (URX_TYPE(op) == URX_LA_START || URX_TYPE(op) == URX_LB_START) {
- depth++;
- }
- if (URX_TYPE(op) == URX_LA_END || URX_TYPE(op)==URX_LBN_END) {
- if (depth == 0) {
- break;
- }
- depth--;
+ int32_t opType = URX_TYPE(op);
+ if ((opType == URX_LA_END || opType == URX_LBN_END) && (URX_VAL(op) == dataLoc)) {
+ break;
}
- U_ASSERT(loc < end);
}
+ U_ASSERT(loc < end);
}
break;
diff --git a/deps/icu-small/source/i18n/regeximp.h b/deps/icu-small/source/i18n/regeximp.h
index da4a861bde..9155cd3a31 100644
--- a/deps/icu-small/source/i18n/regeximp.h
+++ b/deps/icu-small/source/i18n/regeximp.h
@@ -123,7 +123,7 @@ enum {
// saved input position, FAIL rather than taking
// the JMP
URX_LA_START = 37, // Starting a LookAround expression.
- // Save InputPos and SP in static data.
+ // Save InputPos, SP and active region in static data.
// Operand: Static data offset for the save
URX_LA_END = 38, // Ending a Lookaround expression.
// Restore InputPos and Stack to saved values.
diff --git a/deps/icu-small/source/i18n/region.cpp b/deps/icu-small/source/i18n/region.cpp
index f182f61486..198bea8f64 100644
--- a/deps/icu-small/source/i18n/region.cpp
+++ b/deps/icu-small/source/i18n/region.cpp
@@ -25,7 +25,6 @@
#include "unicode/uobject.h"
#include "unicode/unistr.h"
#include "unicode/ures.h"
-#include "unicode/decimfmt.h"
#include "ucln_in.h"
#include "cstring.h"
#include "mutex.h"
@@ -33,6 +32,7 @@
#include "umutex.h"
#include "uresimp.h"
#include "region_impl.h"
+#include "util.h"
#if !UCONFIG_NO_FORMATTING
@@ -87,7 +87,6 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) {
LocalUHashtablePointer newRegionIDMap(uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, &status));
LocalUHashtablePointer newNumericCodeMap(uhash_open(uhash_hashLong,uhash_compareLong,NULL,&status));
LocalUHashtablePointer newRegionAliases(uhash_open(uhash_hashUnicodeString,uhash_compareUnicodeString,NULL,&status));
- LocalPointer<DecimalFormat> df(new DecimalFormat(status), status);
LocalPointer<UVector> continents(new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status), status);
LocalPointer<UVector> groupings(new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status), status);
@@ -115,7 +114,6 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) {
}
// now, initialize
- df->setParseIntegerOnly(TRUE);
uhash_setValueDeleter(newRegionIDMap.getAlias(), deleteRegion); // regionIDMap owns objs
uhash_setKeyDeleter(newRegionAliases.getAlias(), uprv_deleteUObject); // regionAliases owns the string keys
@@ -192,11 +190,10 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) {
r->idStr.extract(0,r->idStr.length(),r->id,sizeof(r->id),US_INV);
r->fType = URGN_TERRITORY; // Only temporary - figure out the real type later once the aliases are known.
- Formattable result;
- UErrorCode ps = U_ZERO_ERROR;
- df->parse(r->idStr,result,ps);
- if ( U_SUCCESS(ps) ) {
- r->code = result.getLong(); // Convert string to number
+ int32_t pos = 0;
+ int32_t result = ICU_Utility::parseAsciiInteger(r->idStr, pos);
+ if (pos > 0) {
+ r->code = result; // Convert string to number
uhash_iput(newNumericCodeMap.getAlias(),r->code,(void *)(r.getAlias()),&status);
r->fType = URGN_SUBCONTINENT;
} else {
@@ -230,11 +227,10 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) {
aliasFromRegion->idStr.setTo(*aliasFromStr);
aliasFromRegion->idStr.extract(0,aliasFromRegion->idStr.length(),aliasFromRegion->id,sizeof(aliasFromRegion->id),US_INV);
uhash_put(newRegionIDMap.getAlias(),(void *)&(aliasFromRegion->idStr),(void *)aliasFromRegion,&status);
- Formattable result;
- UErrorCode ps = U_ZERO_ERROR;
- df->parse(aliasFromRegion->idStr,result,ps);
- if ( U_SUCCESS(ps) ) {
- aliasFromRegion->code = result.getLong(); // Convert string to number
+ int32_t pos = 0;
+ int32_t result = ICU_Utility::parseAsciiInteger(aliasFromRegion->idStr, pos);
+ if ( pos > 0 ) {
+ aliasFromRegion->code = result; // Convert string to number
uhash_iput(newNumericCodeMap.getAlias(),aliasFromRegion->code,(void *)aliasFromRegion,&status);
} else {
aliasFromRegion->code = -1;
@@ -279,11 +275,10 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) {
Region *r = (Region *)uhash_get(newRegionIDMap.getAlias(),(void *)&codeMappingID);
if ( r ) {
- Formattable result;
- UErrorCode ps = U_ZERO_ERROR;
- df->parse(codeMappingNumber,result,ps);
- if ( U_SUCCESS(ps) ) {
- r->code = result.getLong(); // Convert string to number
+ int32_t pos = 0;
+ int32_t result = ICU_Utility::parseAsciiInteger(codeMappingNumber, pos);
+ if ( pos > 0 ) {
+ r->code = result; // Convert string to number
uhash_iput(newNumericCodeMap.getAlias(),r->code,(void *)r,&status);
}
LocalPointer<UnicodeString> code3(new UnicodeString(codeMapping3Letter), status);
@@ -516,15 +511,8 @@ Region::getInstance (int32_t code, UErrorCode &status) {
Region *r = (Region *)uhash_iget(numericCodeMap,code);
if ( !r ) { // Just in case there's an alias that's numeric, try to find it.
- UnicodeString pat = UNICODE_STRING_SIMPLE("0");
- LocalPointer<DecimalFormat> df(new DecimalFormat(pat,status), status);
- if( U_FAILURE(status) ) {
- return NULL;
- }
UnicodeString id;
- id.remove();
- FieldPosition posIter;
- df->format(code,id, posIter, status);
+ ICU_Utility::appendNumber(id, code, 10, 1);
r = (Region *)uhash_get(regionAliases,&id);
}
diff --git a/deps/icu-small/source/i18n/reldatefmt.cpp b/deps/icu-small/source/i18n/reldatefmt.cpp
index cda2564b9a..f2568a858d 100644
--- a/deps/icu-small/source/i18n/reldatefmt.cpp
+++ b/deps/icu-small/source/i18n/reldatefmt.cpp
@@ -43,7 +43,7 @@
#include "standardplural.h"
#include "unifiedcache.h"
#include "util.h"
-#include "number_stringbuilder.h"
+#include "formatted_string_builder.h"
#include "number_utypes.h"
#include "number_modifiers.h"
#include "formattedval_impl.h"
@@ -315,6 +315,10 @@ struct RelDateTimeFmtDataSink : public ResourceSink {
return UDAT_ABSOLUTE_FRIDAY;
case SATURDAY:
return UDAT_ABSOLUTE_SATURDAY;
+ case HOUR:
+ return UDAT_ABSOLUTE_HOUR;
+ case MINUTE:
+ return UDAT_ABSOLUTE_MINUTE;
default:
return -1;
}
@@ -725,14 +729,14 @@ const RelativeDateTimeCacheData *LocaleCacheKey<RelativeDateTimeCacheData>::crea
static constexpr number::impl::Field kRDTNumericField
- = number::impl::NumFieldUtils::compress<UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_NUMERIC_FIELD>();
+ = StringBuilderFieldUtils::compress<UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_NUMERIC_FIELD>();
static constexpr number::impl::Field kRDTLiteralField
- = number::impl::NumFieldUtils::compress<UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD>();
+ = StringBuilderFieldUtils::compress<UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD>();
-class FormattedRelativeDateTimeData : public FormattedValueNumberStringBuilderImpl {
+class FormattedRelativeDateTimeData : public FormattedValueStringBuilderImpl {
public:
- FormattedRelativeDateTimeData() : FormattedValueNumberStringBuilderImpl(kRDTNumericField) {}
+ FormattedRelativeDateTimeData() : FormattedValueStringBuilderImpl(kRDTNumericField) {}
virtual ~FormattedRelativeDateTimeData();
};
@@ -1157,6 +1161,8 @@ void RelativeDateTimeFormatter::formatRelativeImpl(
case UDAT_REL_UNIT_THURSDAY: absunit = UDAT_ABSOLUTE_THURSDAY; break;
case UDAT_REL_UNIT_FRIDAY: absunit = UDAT_ABSOLUTE_FRIDAY; break;
case UDAT_REL_UNIT_SATURDAY: absunit = UDAT_ABSOLUTE_SATURDAY; break;
+ case UDAT_REL_UNIT_HOUR: absunit = UDAT_ABSOLUTE_HOUR; break;
+ case UDAT_REL_UNIT_MINUTE: absunit = UDAT_ABSOLUTE_MINUTE; break;
default: break;
}
if (direction != UDAT_DIRECTION_COUNT && absunit != UDAT_ABSOLUTE_UNIT_COUNT) {
@@ -1184,7 +1190,7 @@ UnicodeString& RelativeDateTimeFormatter::adjustForContext(UnicodeString &str) c
// Must guarantee that one thread at a time accesses the shared break
// iterator.
- static icu::UMutex gBrkIterMutex = U_MUTEX_INITIALIZER;
+ static UMutex gBrkIterMutex;
Mutex lock(&gBrkIterMutex);
str.toTitle(
fOptBreakIterator->get(),
diff --git a/deps/icu-small/source/i18n/reldtfmt.cpp b/deps/icu-small/source/i18n/reldtfmt.cpp
index 753672d905..c74c30c20c 100644
--- a/deps/icu-small/source/i18n/reldtfmt.cpp
+++ b/deps/icu-small/source/i18n/reldtfmt.cpp
@@ -51,7 +51,7 @@ RelativeDateFormat::RelativeDateFormat(const RelativeDateFormat& other) :
fCapitalizationBrkIter(NULL)
{
if(other.fDateTimeFormatter != NULL) {
- fDateTimeFormatter = (SimpleDateFormat*)other.fDateTimeFormatter->clone();
+ fDateTimeFormatter = other.fDateTimeFormatter->clone();
}
if(other.fCombinedFormat != NULL) {
fCombinedFormat = new SimpleFormatter(*other.fCombinedFormat);
@@ -131,7 +131,7 @@ RelativeDateFormat::~RelativeDateFormat() {
}
-Format* RelativeDateFormat::clone(void) const {
+RelativeDateFormat* RelativeDateFormat::clone() const {
return new RelativeDateFormat(*this);
}
diff --git a/deps/icu-small/source/i18n/reldtfmt.h b/deps/icu-small/source/i18n/reldtfmt.h
index 0403da11ef..b36171ce1c 100644
--- a/deps/icu-small/source/i18n/reldtfmt.h
+++ b/deps/icu-small/source/i18n/reldtfmt.h
@@ -71,7 +71,7 @@ public:
* @return A copy of the object.
* @internal ICU 3.8
*/
- virtual Format* clone(void) const;
+ virtual RelativeDateFormat* clone() const;
/**
* Return true if the given Format objects are semantically equal. Objects
diff --git a/deps/icu-small/source/i18n/rematch.cpp b/deps/icu-small/source/i18n/rematch.cpp
index 3b8d2333d8..d9af2b3dda 100644
--- a/deps/icu-small/source/i18n/rematch.cpp
+++ b/deps/icu-small/source/i18n/rematch.cpp
@@ -2069,7 +2069,7 @@ int32_t RegexMatcher::split(UText *input,
//
if (U_FAILURE(status)) {
return 0;
- };
+ }
if (destCapacity < 1) {
status = U_ILLEGAL_ARGUMENT_ERROR;
@@ -3805,11 +3805,13 @@ GC_Done:
case URX_LA_START:
{
- // Entering a lookahead block.
+ // Entering a look around block.
// Save Stack Ptr, Input Pos.
- U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize);
+ U_ASSERT(opValue>=0 && opValue+3<fPattern->fDataSize);
fData[opValue] = fStack->size();
fData[opValue+1] = fp->fInputIdx;
+ fData[opValue+2] = fActiveStart;
+ fData[opValue+3] = fActiveLimit;
fActiveStart = fLookStart; // Set the match region change for
fActiveLimit = fLookLimit; // transparent bounds.
}
@@ -3819,7 +3821,7 @@ GC_Done:
{
// Leaving a look-ahead block.
// restore Stack Ptr, Input Pos to positions they had on entry to block.
- U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize);
+ U_ASSERT(opValue>=0 && opValue+3<fPattern->fDataSize);
int32_t stackSize = fStack->size();
int32_t newStackSize =(int32_t)fData[opValue];
U_ASSERT(stackSize >= newStackSize);
@@ -3839,8 +3841,10 @@ GC_Done:
// Restore the active region bounds in the input string; they may have
// been changed because of transparent bounds on a Region.
- fActiveStart = fRegionStart;
- fActiveLimit = fRegionLimit;
+ fActiveStart = fData[opValue+2];
+ fActiveLimit = fData[opValue+3];
+ U_ASSERT(fActiveStart >= 0);
+ U_ASSERT(fActiveLimit <= fInputLength);
}
break;
@@ -3916,17 +3920,19 @@ GC_Done:
case URX_LB_START:
{
// Entering a look-behind block.
- // Save Stack Ptr, Input Pos.
+ // Save Stack Ptr, Input Pos and active input region.
// TODO: implement transparent bounds. Ticket #6067
- U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize);
+ U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize);
fData[opValue] = fStack->size();
fData[opValue+1] = fp->fInputIdx;
- // Init the variable containing the start index for attempted matches.
- fData[opValue+2] = -1;
// Save input string length, then reset to pin any matches to end at
// the current position.
+ fData[opValue+2] = fActiveStart;
fData[opValue+3] = fActiveLimit;
+ fActiveStart = fRegionStart;
fActiveLimit = fp->fInputIdx;
+ // Init the variable containing the start index for attempted matches.
+ fData[opValue+4] = -1;
}
break;
@@ -3949,8 +3955,8 @@ GC_Done:
U_ASSERT(minML >= 0);
// Fetch (from data) the last input index where a match was attempted.
- U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize);
- int64_t &lbStartIdx = fData[opValue+2];
+ U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize);
+ int64_t &lbStartIdx = fData[opValue+4];
if (lbStartIdx < 0) {
// First time through loop.
lbStartIdx = fp->fInputIdx - minML;
@@ -3976,10 +3982,10 @@ GC_Done:
// getting a match. Backtrack out, and out of the
// Look Behind altogether.
fp = (REStackFrame *)fStack->popFrame(fFrameSize);
- int64_t restoreInputLen = fData[opValue+3];
- U_ASSERT(restoreInputLen >= fActiveLimit);
- U_ASSERT(restoreInputLen <= fInputLength);
- fActiveLimit = restoreInputLen;
+ fActiveStart = fData[opValue+2];
+ fActiveLimit = fData[opValue+3];
+ U_ASSERT(fActiveStart >= 0);
+ U_ASSERT(fActiveLimit <= fInputLength);
break;
}
@@ -3993,7 +3999,7 @@ GC_Done:
case URX_LB_END:
// End of a look-behind block, after a successful match.
{
- U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize);
+ U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize);
if (fp->fInputIdx != fActiveLimit) {
// The look-behind expression matched, but the match did not
// extend all the way to the point that we are looking behind from.
@@ -4004,13 +4010,13 @@ GC_Done:
break;
}
- // Look-behind match is good. Restore the orignal input string length,
+ // Look-behind match is good. Restore the orignal input string region,
// which had been truncated to pin the end of the lookbehind match to the
// position being looked-behind.
- int64_t originalInputLen = fData[opValue+3];
- U_ASSERT(originalInputLen >= fActiveLimit);
- U_ASSERT(originalInputLen <= fInputLength);
- fActiveLimit = originalInputLen;
+ fActiveStart = fData[opValue+2];
+ fActiveLimit = fData[opValue+3];
+ U_ASSERT(fActiveStart >= 0);
+ U_ASSERT(fActiveLimit <= fInputLength);
}
break;
@@ -4035,8 +4041,8 @@ GC_Done:
U_ASSERT(continueLoc > fp->fPatIdx);
// Fetch (from data) the last input index where a match was attempted.
- U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize);
- int64_t &lbStartIdx = fData[opValue+2];
+ U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize);
+ int64_t &lbStartIdx = fData[opValue+4];
if (lbStartIdx < 0) {
// First time through loop.
lbStartIdx = fp->fInputIdx - minML;
@@ -4061,10 +4067,10 @@ GC_Done:
// We have tried all potential match starting points without
// getting a match, which means that the negative lookbehind as
// a whole has succeeded. Jump forward to the continue location
- int64_t restoreInputLen = fData[opValue+3];
- U_ASSERT(restoreInputLen >= fActiveLimit);
- U_ASSERT(restoreInputLen <= fInputLength);
- fActiveLimit = restoreInputLen;
+ fActiveStart = fData[opValue+2];
+ fActiveLimit = fData[opValue+3];
+ U_ASSERT(fActiveStart >= 0);
+ U_ASSERT(fActiveLimit <= fInputLength);
fp->fPatIdx = continueLoc;
break;
}
@@ -4079,7 +4085,7 @@ GC_Done:
case URX_LBN_END:
// End of a negative look-behind block, after a successful match.
{
- U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize);
+ U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize);
if (fp->fInputIdx != fActiveLimit) {
// The look-behind expression matched, but the match did not
// extend all the way to the point that we are looking behind from.
@@ -4096,10 +4102,10 @@ GC_Done:
// Restore the orignal input string length, which had been truncated
// inorder to pin the end of the lookbehind match
// to the position being looked-behind.
- int64_t originalInputLen = fData[opValue+3];
- U_ASSERT(originalInputLen >= fActiveLimit);
- U_ASSERT(originalInputLen <= fInputLength);
- fActiveLimit = originalInputLen;
+ fActiveStart = fData[opValue+2];
+ fActiveLimit = fData[opValue+3];
+ U_ASSERT(fActiveStart >= 0);
+ U_ASSERT(fActiveLimit <= fInputLength);
// Restore original stack position, discarding any state saved
// by the successful pattern match.
@@ -5336,11 +5342,13 @@ GC_Done:
case URX_LA_START:
{
- // Entering a lookahead block.
+ // Entering a look around block.
// Save Stack Ptr, Input Pos.
- U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize);
+ U_ASSERT(opValue>=0 && opValue+3<fPattern->fDataSize);
fData[opValue] = fStack->size();
fData[opValue+1] = fp->fInputIdx;
+ fData[opValue+2] = fActiveStart;
+ fData[opValue+3] = fActiveLimit;
fActiveStart = fLookStart; // Set the match region change for
fActiveLimit = fLookLimit; // transparent bounds.
}
@@ -5348,9 +5356,9 @@ GC_Done:
case URX_LA_END:
{
- // Leaving a look-ahead block.
+ // Leaving a look around block.
// restore Stack Ptr, Input Pos to positions they had on entry to block.
- U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize);
+ U_ASSERT(opValue>=0 && opValue+3<fPattern->fDataSize);
int32_t stackSize = fStack->size();
int32_t newStackSize = (int32_t)fData[opValue];
U_ASSERT(stackSize >= newStackSize);
@@ -5370,8 +5378,10 @@ GC_Done:
// Restore the active region bounds in the input string; they may have
// been changed because of transparent bounds on a Region.
- fActiveStart = fRegionStart;
- fActiveLimit = fRegionLimit;
+ fActiveStart = fData[opValue+2];
+ fActiveLimit = fData[opValue+3];
+ U_ASSERT(fActiveStart >= 0);
+ U_ASSERT(fActiveLimit <= fInputLength);
}
break;
@@ -5434,17 +5444,19 @@ GC_Done:
case URX_LB_START:
{
// Entering a look-behind block.
- // Save Stack Ptr, Input Pos.
+ // Save Stack Ptr, Input Pos and active input region.
// TODO: implement transparent bounds. Ticket #6067
- U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize);
+ U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize);
fData[opValue] = fStack->size();
fData[opValue+1] = fp->fInputIdx;
- // Init the variable containing the start index for attempted matches.
- fData[opValue+2] = -1;
// Save input string length, then reset to pin any matches to end at
// the current position.
+ fData[opValue+2] = fActiveStart;
fData[opValue+3] = fActiveLimit;
+ fActiveStart = fRegionStart;
fActiveLimit = fp->fInputIdx;
+ // Init the variable containing the start index for attempted matches.
+ fData[opValue+4] = -1;
}
break;
@@ -5462,8 +5474,8 @@ GC_Done:
U_ASSERT(minML >= 0);
// Fetch (from data) the last input index where a match was attempted.
- U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize);
- int64_t &lbStartIdx = fData[opValue+2];
+ U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize);
+ int64_t &lbStartIdx = fData[opValue+4];
if (lbStartIdx < 0) {
// First time through loop.
lbStartIdx = fp->fInputIdx - minML;
@@ -5485,10 +5497,10 @@ GC_Done:
// getting a match. Backtrack out, and out of the
// Look Behind altogether.
fp = (REStackFrame *)fStack->popFrame(fFrameSize);
- int64_t restoreInputLen = fData[opValue+3];
- U_ASSERT(restoreInputLen >= fActiveLimit);
- U_ASSERT(restoreInputLen <= fInputLength);
- fActiveLimit = restoreInputLen;
+ fActiveStart = fData[opValue+2];
+ fActiveLimit = fData[opValue+3];
+ U_ASSERT(fActiveStart >= 0);
+ U_ASSERT(fActiveLimit <= fInputLength);
break;
}
@@ -5502,7 +5514,7 @@ GC_Done:
case URX_LB_END:
// End of a look-behind block, after a successful match.
{
- U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize);
+ U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize);
if (fp->fInputIdx != fActiveLimit) {
// The look-behind expression matched, but the match did not
// extend all the way to the point that we are looking behind from.
@@ -5513,13 +5525,13 @@ GC_Done:
break;
}
- // Look-behind match is good. Restore the orignal input string length,
+ // Look-behind match is good. Restore the orignal input string region,
// which had been truncated to pin the end of the lookbehind match to the
// position being looked-behind.
- int64_t originalInputLen = fData[opValue+3];
- U_ASSERT(originalInputLen >= fActiveLimit);
- U_ASSERT(originalInputLen <= fInputLength);
- fActiveLimit = originalInputLen;
+ fActiveStart = fData[opValue+2];
+ fActiveLimit = fData[opValue+3];
+ U_ASSERT(fActiveStart >= 0);
+ U_ASSERT(fActiveLimit <= fInputLength);
}
break;
@@ -5539,8 +5551,8 @@ GC_Done:
U_ASSERT(continueLoc > fp->fPatIdx);
// Fetch (from data) the last input index where a match was attempted.
- U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize);
- int64_t &lbStartIdx = fData[opValue+2];
+ U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize);
+ int64_t &lbStartIdx = fData[opValue+4];
if (lbStartIdx < 0) {
// First time through loop.
lbStartIdx = fp->fInputIdx - minML;
@@ -5561,10 +5573,10 @@ GC_Done:
// We have tried all potential match starting points without
// getting a match, which means that the negative lookbehind as
// a whole has succeeded. Jump forward to the continue location
- int64_t restoreInputLen = fData[opValue+3];
- U_ASSERT(restoreInputLen >= fActiveLimit);
- U_ASSERT(restoreInputLen <= fInputLength);
- fActiveLimit = restoreInputLen;
+ fActiveStart = fData[opValue+2];
+ fActiveLimit = fData[opValue+3];
+ U_ASSERT(fActiveStart >= 0);
+ U_ASSERT(fActiveLimit <= fInputLength);
fp->fPatIdx = continueLoc;
break;
}
@@ -5579,7 +5591,7 @@ GC_Done:
case URX_LBN_END:
// End of a negative look-behind block, after a successful match.
{
- U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize);
+ U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize);
if (fp->fInputIdx != fActiveLimit) {
// The look-behind expression matched, but the match did not
// extend all the way to the point that we are looking behind from.
@@ -5596,10 +5608,10 @@ GC_Done:
// Restore the orignal input string length, which had been truncated
// inorder to pin the end of the lookbehind match
// to the position being looked-behind.
- int64_t originalInputLen = fData[opValue+3];
- U_ASSERT(originalInputLen >= fActiveLimit);
- U_ASSERT(originalInputLen <= fInputLength);
- fActiveLimit = originalInputLen;
+ fActiveStart = fData[opValue+2];
+ fActiveLimit = fData[opValue+3];
+ U_ASSERT(fActiveStart >= 0);
+ U_ASSERT(fActiveLimit <= fInputLength);
// Restore original stack position, discarding any state saved
// by the successful pattern match.
diff --git a/deps/icu-small/source/i18n/remtrans.cpp b/deps/icu-small/source/i18n/remtrans.cpp
index 70a6ed3935..03b878575c 100644
--- a/deps/icu-small/source/i18n/remtrans.cpp
+++ b/deps/icu-small/source/i18n/remtrans.cpp
@@ -48,10 +48,10 @@ RemoveTransliterator::RemoveTransliterator() : Transliterator(UnicodeString(TRUE
RemoveTransliterator::~RemoveTransliterator() {}
-Transliterator* RemoveTransliterator::clone(void) const {
- Transliterator* result = new RemoveTransliterator();
+RemoveTransliterator* RemoveTransliterator::clone() const {
+ RemoveTransliterator* result = new RemoveTransliterator();
if (result != NULL && getFilter() != 0) {
- result->adoptFilter((UnicodeFilter*)(getFilter()->clone()));
+ result->adoptFilter(getFilter()->clone());
}
return result;
}
diff --git a/deps/icu-small/source/i18n/remtrans.h b/deps/icu-small/source/i18n/remtrans.h
index ed038d5f2f..13de01594a 100644
--- a/deps/icu-small/source/i18n/remtrans.h
+++ b/deps/icu-small/source/i18n/remtrans.h
@@ -47,7 +47,7 @@ public:
* Transliterator API.
* @return A copy of the object.
*/
- virtual Transliterator* clone(void) const;
+ virtual RemoveTransliterator* clone() const;
/**
* Implements {@link Transliterator#handleTransliterate}.
diff --git a/deps/icu-small/source/i18n/repattrn.cpp b/deps/icu-small/source/i18n/repattrn.cpp
index b03873066c..6976056dc1 100644
--- a/deps/icu-small/source/i18n/repattrn.cpp
+++ b/deps/icu-small/source/i18n/repattrn.cpp
@@ -646,7 +646,7 @@ int32_t RegexPattern::split(const UnicodeString &input,
{
if (U_FAILURE(status)) {
return 0;
- };
+ }
RegexMatcher m(this);
int32_t r = 0;
@@ -667,7 +667,7 @@ int32_t RegexPattern::split(UText *input,
{
if (U_FAILURE(status)) {
return 0;
- };
+ }
RegexMatcher m(this);
int32_t r = 0;
diff --git a/deps/icu-small/source/i18n/rulebasedcollator.cpp b/deps/icu-small/source/i18n/rulebasedcollator.cpp
index 92fa538597..60acf17815 100644
--- a/deps/icu-small/source/i18n/rulebasedcollator.cpp
+++ b/deps/icu-small/source/i18n/rulebasedcollator.cpp
@@ -220,7 +220,7 @@ RuleBasedCollator::adoptTailoring(CollationTailoring *t, UErrorCode &errorCode)
actualLocaleIsSameAsValid = FALSE;
}
-Collator *
+RuleBasedCollator *
RuleBasedCollator::clone() const {
return new RuleBasedCollator(*this);
}
diff --git a/deps/icu-small/source/i18n/scientificnumberformatter.cpp b/deps/icu-small/source/i18n/scientificnumberformatter.cpp
index 03d98dd6e1..6c2cb3aeed 100644
--- a/deps/icu-small/source/i18n/scientificnumberformatter.cpp
+++ b/deps/icu-small/source/i18n/scientificnumberformatter.cpp
@@ -121,7 +121,7 @@ ScientificNumberFormatter *ScientificNumberFormatter::createInstance(
return result;
}
-ScientificNumberFormatter::Style *ScientificNumberFormatter::SuperscriptStyle::clone() const {
+ScientificNumberFormatter::SuperscriptStyle *ScientificNumberFormatter::SuperscriptStyle::clone() const {
return new ScientificNumberFormatter::SuperscriptStyle(*this);
}
@@ -195,7 +195,7 @@ UnicodeString &ScientificNumberFormatter::SuperscriptStyle::format(
return appendTo;
}
-ScientificNumberFormatter::Style *ScientificNumberFormatter::MarkupStyle::clone() const {
+ScientificNumberFormatter::MarkupStyle *ScientificNumberFormatter::MarkupStyle::clone() const {
return new ScientificNumberFormatter::MarkupStyle(*this);
}
diff --git a/deps/icu-small/source/i18n/selfmt.cpp b/deps/icu-small/source/i18n/selfmt.cpp
index 29aee36457..47e53d75de 100644
--- a/deps/icu-small/source/i18n/selfmt.cpp
+++ b/deps/icu-small/source/i18n/selfmt.cpp
@@ -151,7 +151,7 @@ int32_t SelectFormat::findSubMessage(const MessagePattern& pattern, int32_t part
return msgStart;
}
-Format* SelectFormat::clone() const
+SelectFormat* SelectFormat::clone() const
{
return new SelectFormat(*this);
}
diff --git a/deps/icu-small/source/i18n/simpletz.cpp b/deps/icu-small/source/i18n/simpletz.cpp
index 1af5292a82..12c220595c 100644
--- a/deps/icu-small/source/i18n/simpletz.cpp
+++ b/deps/icu-small/source/i18n/simpletz.cpp
@@ -33,6 +33,7 @@
#include "unicode/gregocal.h"
#include "unicode/smpdtfmt.h"
+#include "cmemory.h"
#include "gregoimp.h"
#include "umutex.h"
@@ -242,7 +243,7 @@ SimpleTimeZone::operator==(const TimeZone& that) const
// -------------------------------------
// Called by TimeZone::createDefault() inside a Mutex - be careful.
-TimeZone*
+SimpleTimeZone*
SimpleTimeZone::clone() const
{
return new SimpleTimeZone(*this);
@@ -1083,7 +1084,7 @@ SimpleTimeZone::checkTransitionRules(UErrorCode& status) const {
if (U_FAILURE(status)) {
return;
}
- static UMutex gLock = U_MUTEX_INITIALIZER;
+ static UMutex gLock;
umtx_lock(&gLock);
if (!transitionRulesInitialized) {
SimpleTimeZone *ncThis = const_cast<SimpleTimeZone*>(this);
diff --git a/deps/icu-small/source/i18n/smpdtfmt.cpp b/deps/icu-small/source/i18n/smpdtfmt.cpp
index e67c453828..5fcbb5875b 100644
--- a/deps/icu-small/source/i18n/smpdtfmt.cpp
+++ b/deps/icu-small/source/i18n/smpdtfmt.cpp
@@ -230,10 +230,7 @@ static const int32_t gFieldRangeBias[] = {
static const int32_t HEBREW_CAL_CUR_MILLENIUM_START_YEAR = 5000;
static const int32_t HEBREW_CAL_CUR_MILLENIUM_END_YEAR = 6000;
-static UMutex *LOCK() {
- static UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static UMutex LOCK;
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleDateFormat)
@@ -623,7 +620,7 @@ SimpleDateFormat& SimpleDateFormat::operator=(const SimpleDateFormat& other)
//----------------------------------------------------------------------
-Format*
+SimpleDateFormat*
SimpleDateFormat::clone() const
{
return new SimpleDateFormat(*this);
@@ -1223,10 +1220,14 @@ _appendSymbolWithMonthPattern(UnicodeString& dst, int32_t value, const UnicodeSt
//----------------------------------------------------------------------
static number::LocalizedNumberFormatter*
-createFastFormatter(const DecimalFormat* df, int32_t minInt, int32_t maxInt) {
- return new number::LocalizedNumberFormatter(
- df->toNumberFormatter()
- .integerWidth(number::IntegerWidth::zeroFillTo(minInt).truncateAt(maxInt)));
+createFastFormatter(const DecimalFormat* df, int32_t minInt, int32_t maxInt, UErrorCode& status) {
+ const number::LocalizedNumberFormatter* lnfBase = df->toNumberFormatter(status);
+ if (U_FAILURE(status)) {
+ return nullptr;
+ }
+ return lnfBase->integerWidth(
+ number::IntegerWidth::zeroFillTo(minInt).truncateAt(maxInt)
+ ).clone().orphan();
}
void SimpleDateFormat::initFastNumberFormatters(UErrorCode& status) {
@@ -1237,11 +1238,11 @@ void SimpleDateFormat::initFastNumberFormatters(UErrorCode& status) {
if (df == nullptr) {
return;
}
- fFastNumberFormatters[SMPDTFMT_NF_1x10] = createFastFormatter(df, 1, 10);
- fFastNumberFormatters[SMPDTFMT_NF_2x10] = createFastFormatter(df, 2, 10);
- fFastNumberFormatters[SMPDTFMT_NF_3x10] = createFastFormatter(df, 3, 10);
- fFastNumberFormatters[SMPDTFMT_NF_4x10] = createFastFormatter(df, 4, 10);
- fFastNumberFormatters[SMPDTFMT_NF_2x2] = createFastFormatter(df, 2, 2);
+ fFastNumberFormatters[SMPDTFMT_NF_1x10] = createFastFormatter(df, 1, 10, status);
+ fFastNumberFormatters[SMPDTFMT_NF_2x10] = createFastFormatter(df, 2, 10, status);
+ fFastNumberFormatters[SMPDTFMT_NF_3x10] = createFastFormatter(df, 3, 10, status);
+ fFastNumberFormatters[SMPDTFMT_NF_4x10] = createFastFormatter(df, 4, 10, status);
+ fFastNumberFormatters[SMPDTFMT_NF_2x2] = createFastFormatter(df, 2, 2, status);
}
void SimpleDateFormat::freeFastNumberFormatters() {
@@ -1266,14 +1267,14 @@ SimpleDateFormat::initNumberFormatters(const Locale &locale,UErrorCode &status)
if ( fDateOverride.isBogus() && fTimeOverride.isBogus() ) {
return;
}
- umtx_lock(LOCK());
+ umtx_lock(&LOCK);
if (fSharedNumberFormatters == NULL) {
fSharedNumberFormatters = allocSharedNumberFormatters();
if (fSharedNumberFormatters == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
}
}
- umtx_unlock(LOCK());
+ umtx_unlock(&LOCK);
if (U_FAILURE(status)) {
return;
@@ -1980,9 +1981,11 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo,
break;
}
if (titlecase) {
+ BreakIterator* const mutableCapitalizationBrkIter = fCapitalizationBrkIter->clone();
UnicodeString firstField(appendTo, beginOffset);
- firstField.toTitle(fCapitalizationBrkIter, fLocale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
+ firstField.toTitle(mutableCapitalizationBrkIter, fLocale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
appendTo.replaceBetween(beginOffset, appendTo.length(), firstField);
+ delete mutableCapitalizationBrkIter;
}
}
#endif
@@ -2107,7 +2110,7 @@ SimpleDateFormat::zeroPaddingNumber(
// Fall back to slow path (clone and mutate the NumberFormat)
if (currentNumberFormat != nullptr) {
FieldPosition pos(FieldPosition::DONT_CARE);
- LocalPointer<NumberFormat> nf(dynamic_cast<NumberFormat*>(currentNumberFormat->clone()));
+ LocalPointer<NumberFormat> nf(currentNumberFormat->clone());
nf->setMinimumIntegerDigits(minDigits);
nf->setMaximumIntegerDigits(maxDigits);
nf->format(value, appendTo, pos); // 3rd arg is there to speed up processing
@@ -3770,7 +3773,7 @@ void SimpleDateFormat::parseInt(const UnicodeString& text,
auto* fmtAsDF = dynamic_cast<const DecimalFormat*>(fmt);
LocalPointer<DecimalFormat> df;
if (!allowNegative && fmtAsDF != nullptr) {
- df.adoptInstead(dynamic_cast<DecimalFormat*>(fmtAsDF->clone()));
+ df.adoptInstead(fmtAsDF->clone());
if (df.isNull()) {
// Memory allocation error
return;
@@ -3901,11 +3904,11 @@ SimpleDateFormat::applyPattern(const UnicodeString& pattern)
} else if (fDateOverride.isBogus() && fHasHanYearChar) {
// No current override (=> no Gannen numbering) but new pattern needs it;
// use procedures from initNUmberFormatters / adoptNumberFormat
- umtx_lock(LOCK());
+ umtx_lock(&LOCK);
if (fSharedNumberFormatters == NULL) {
fSharedNumberFormatters = allocSharedNumberFormatters();
}
- umtx_unlock(LOCK());
+ umtx_unlock(&LOCK);
if (fSharedNumberFormatters != NULL) {
Locale ovrLoc(fLocale.getLanguage(),fLocale.getCountry(),fLocale.getVariant(),"numbers=jpanyear");
UErrorCode status = U_ZERO_ERROR;
@@ -3998,6 +4001,7 @@ void SimpleDateFormat::adoptCalendar(Calendar* calendarToAdopt)
DateFormatSymbols *newSymbols =
DateFormatSymbols::createForLocale(calLocale, status);
if (U_FAILURE(status)) {
+ delete calendarToAdopt;
return;
}
DateFormat::adoptCalendar(calendarToAdopt);
@@ -4237,7 +4241,7 @@ SimpleDateFormat::skipUWhiteSpace(const UnicodeString& text, int32_t pos) const
TimeZoneFormat *
SimpleDateFormat::tzFormat(UErrorCode &status) const {
if (fTimeZoneFormat == NULL) {
- umtx_lock(LOCK());
+ umtx_lock(&LOCK);
{
if (fTimeZoneFormat == NULL) {
TimeZoneFormat *tzfmt = TimeZoneFormat::createInstance(fLocale, status);
@@ -4248,7 +4252,7 @@ SimpleDateFormat::tzFormat(UErrorCode &status) const {
const_cast<SimpleDateFormat *>(this)->fTimeZoneFormat = tzfmt;
}
}
- umtx_unlock(LOCK());
+ umtx_unlock(&LOCK);
}
return fTimeZoneFormat;
}
diff --git a/deps/icu-small/source/i18n/numparse_stringsegment.cpp b/deps/icu-small/source/i18n/string_segment.cpp
index 3db4fe618a..5d19ac57f5 100644
--- a/deps/icu-small/source/i18n/numparse_stringsegment.cpp
+++ b/deps/icu-small/source/i18n/string_segment.cpp
@@ -10,14 +10,12 @@
#define UNISTR_FROM_STRING_EXPLICIT
#include "numparse_types.h"
-#include "numparse_stringsegment.h"
+#include "string_segment.h"
#include "putilimp.h"
#include "unicode/utf16.h"
#include "unicode/uniset.h"
-using namespace icu;
-using namespace icu::numparse;
-using namespace icu::numparse::impl;
+U_NAMESPACE_BEGIN
StringSegment::StringSegment(const UnicodeString& str, bool ignoreCase)
@@ -143,4 +141,5 @@ bool StringSegment::operator==(const UnicodeString& other) const {
}
+U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/deps/icu-small/source/i18n/string_segment.h b/deps/icu-small/source/i18n/string_segment.h
new file mode 100644
index 0000000000..b581f7e575
--- /dev/null
+++ b/deps/icu-small/source/i18n/string_segment.h
@@ -0,0 +1,134 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+#ifndef __NUMPARSE_STRINGSEGMENT_H__
+#define __NUMPARSE_STRINGSEGMENT_H__
+
+#include "unicode/unistr.h"
+#include "unicode/uniset.h"
+
+U_NAMESPACE_BEGIN
+
+
+/**
+ * A mutable UnicodeString wrapper with a variable offset and length and
+ * support for case folding. The charAt, length, and subSequence methods all
+ * operate relative to the fixed offset into the UnicodeString.
+ *
+ * Intended to be useful for parsing.
+ *
+ * CAUTION: Since this class is mutable, it must not be used anywhere that an
+ * immutable object is required, like in a cache or as the key of a hash map.
+ *
+ * @author sffc (Shane Carr)
+ */
+// Exported as U_I18N_API for tests
+class U_I18N_API StringSegment : public UMemory {
+ public:
+ StringSegment(const UnicodeString& str, bool ignoreCase);
+
+ int32_t getOffset() const;
+
+ void setOffset(int32_t start);
+
+ /**
+ * Equivalent to <code>setOffset(getOffset()+delta)</code>.
+ *
+ * <p>
+ * This method is usually called by a Matcher to register that a char was consumed. If the char is
+ * strong (it usually is, except for things like whitespace), follow this with a call to
+ * {@link ParsedNumber#setCharsConsumed}. For more information on strong chars, see that method.
+ */
+ void adjustOffset(int32_t delta);
+
+ /**
+ * Adjusts the offset by the width of the current code point, either 1 or 2 chars.
+ */
+ void adjustOffsetByCodePoint();
+
+ void setLength(int32_t length);
+
+ void resetLength();
+
+ int32_t length() const;
+
+ char16_t charAt(int32_t index) const;
+
+ UChar32 codePointAt(int32_t index) const;
+
+ UnicodeString toUnicodeString() const;
+
+ const UnicodeString toTempUnicodeString() const;
+
+ /**
+ * Returns the first code point in the string segment, or -1 if the string starts with an invalid
+ * code point.
+ *
+ * <p>
+ * <strong>Important:</strong> Most of the time, you should use {@link #startsWith}, which handles case
+ * folding logic, instead of this method.
+ */
+ UChar32 getCodePoint() const;
+
+ /**
+ * Returns true if the first code point of this StringSegment equals the given code point.
+ *
+ * <p>
+ * This method will perform case folding if case folding is enabled for the parser.
+ */
+ bool startsWith(UChar32 otherCp) const;
+
+ /**
+ * Returns true if the first code point of this StringSegment is in the given UnicodeSet.
+ */
+ bool startsWith(const UnicodeSet& uniset) const;
+
+ /**
+ * Returns true if there is at least one code point of overlap between this StringSegment and the
+ * given UnicodeString.
+ */
+ bool startsWith(const UnicodeString& other) const;
+
+ /**
+ * Returns the length of the prefix shared by this StringSegment and the given UnicodeString. For
+ * example, if this string segment is "aab", and the char sequence is "aac", this method returns 2,
+ * since the first 2 characters are the same.
+ *
+ * <p>
+ * This method only returns offsets along code point boundaries.
+ *
+ * <p>
+ * This method will perform case folding if case folding was enabled in the constructor.
+ *
+ * <p>
+ * IMPORTANT: The given UnicodeString must not be empty! It is the caller's responsibility to check.
+ */
+ int32_t getCommonPrefixLength(const UnicodeString& other);
+
+ /**
+ * Like {@link #getCommonPrefixLength}, but never performs case folding, even if case folding is
+ * enabled for the parser.
+ */
+ int32_t getCaseSensitivePrefixLength(const UnicodeString& other);
+
+ bool operator==(const UnicodeString& other) const;
+
+ private:
+ const UnicodeString& fStr;
+ int32_t fStart;
+ int32_t fEnd;
+ bool fFoldCase;
+
+ int32_t getPrefixLengthInternal(const UnicodeString& other, bool foldCase);
+
+ static bool codePointsEqual(UChar32 cp1, UChar32 cp2, bool foldCase);
+};
+
+
+U_NAMESPACE_END
+
+#endif //__NUMPARSE_STRINGSEGMENT_H__
+#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/deps/icu-small/source/i18n/strmatch.cpp b/deps/icu-small/source/i18n/strmatch.cpp
index d5b018aa6b..97c0fba6f1 100644
--- a/deps/icu-small/source/i18n/strmatch.cpp
+++ b/deps/icu-small/source/i18n/strmatch.cpp
@@ -58,7 +58,7 @@ StringMatcher::~StringMatcher() {
/**
* Implement UnicodeFunctor
*/
-UnicodeFunctor* StringMatcher::clone() const {
+StringMatcher* StringMatcher::clone() const {
return new StringMatcher(*this);
}
diff --git a/deps/icu-small/source/i18n/strmatch.h b/deps/icu-small/source/i18n/strmatch.h
index 7152a24a07..09d04ede13 100644
--- a/deps/icu-small/source/i18n/strmatch.h
+++ b/deps/icu-small/source/i18n/strmatch.h
@@ -78,7 +78,7 @@ class StringMatcher : public UnicodeFunctor, public UnicodeMatcher, public Unico
* Implement UnicodeFunctor
* @return a copy of the object.
*/
- virtual UnicodeFunctor* clone() const;
+ virtual StringMatcher* clone() const;
/**
* UnicodeFunctor API. Cast 'this' to a UnicodeMatcher* pointer
diff --git a/deps/icu-small/source/i18n/strrepl.cpp b/deps/icu-small/source/i18n/strrepl.cpp
index 132c844c2d..e9e71ee540 100644
--- a/deps/icu-small/source/i18n/strrepl.cpp
+++ b/deps/icu-small/source/i18n/strrepl.cpp
@@ -87,7 +87,7 @@ StringReplacer::~StringReplacer() {
/**
* Implement UnicodeFunctor
*/
-UnicodeFunctor* StringReplacer::clone() const {
+StringReplacer* StringReplacer::clone() const {
return new StringReplacer(*this);
}
diff --git a/deps/icu-small/source/i18n/strrepl.h b/deps/icu-small/source/i18n/strrepl.h
index feec058152..7f74d0d945 100644
--- a/deps/icu-small/source/i18n/strrepl.h
+++ b/deps/icu-small/source/i18n/strrepl.h
@@ -111,7 +111,7 @@ class StringReplacer : public UnicodeFunctor, public UnicodeReplacer {
/**
* Implement UnicodeFunctor
*/
- virtual UnicodeFunctor* clone() const;
+ virtual StringReplacer* clone() const;
/**
* UnicodeFunctor API. Cast 'this' to a UnicodeReplacer* pointer
diff --git a/deps/icu-small/source/i18n/stsearch.cpp b/deps/icu-small/source/i18n/stsearch.cpp
index bf4d80b6db..32481a1400 100644
--- a/deps/icu-small/source/i18n/stsearch.cpp
+++ b/deps/icu-small/source/i18n/stsearch.cpp
@@ -282,7 +282,7 @@ void StringSearch::reset()
usearch_reset(m_strsrch_);
}
-SearchIterator * StringSearch::safeClone(void) const
+StringSearch * StringSearch::safeClone() const
{
UErrorCode status = U_ZERO_ERROR;
StringSearch *result = new StringSearch(m_pattern_, m_text_,
diff --git a/deps/icu-small/source/i18n/taiwncal.cpp b/deps/icu-small/source/i18n/taiwncal.cpp
index e2757dbd55..1a6a0e2e78 100644
--- a/deps/icu-small/source/i18n/taiwncal.cpp
+++ b/deps/icu-small/source/i18n/taiwncal.cpp
@@ -53,7 +53,7 @@ TaiwanCalendar& TaiwanCalendar::operator= ( const TaiwanCalendar& right)
return *this;
}
-Calendar* TaiwanCalendar::clone(void) const
+TaiwanCalendar* TaiwanCalendar::clone() const
{
return new TaiwanCalendar(*this);
}
diff --git a/deps/icu-small/source/i18n/taiwncal.h b/deps/icu-small/source/i18n/taiwncal.h
index 99bbfb53f2..daadc124f4 100644
--- a/deps/icu-small/source/i18n/taiwncal.h
+++ b/deps/icu-small/source/i18n/taiwncal.h
@@ -91,7 +91,7 @@ public:
* @return return a polymorphic copy of this calendar.
* @internal
*/
- virtual Calendar* clone(void) const;
+ virtual TaiwanCalendar* clone() const;
public:
/**
diff --git a/deps/icu-small/source/i18n/timezone.cpp b/deps/icu-small/source/i18n/timezone.cpp
index 70169b5c1f..b90b78614a 100644
--- a/deps/icu-small/source/i18n/timezone.cpp
+++ b/deps/icu-small/source/i18n/timezone.cpp
@@ -527,6 +527,8 @@ TimeZone::detectHostTimeZone()
// -------------------------------------
+static UMutex gDefaultZoneMutex;
+
/**
* Initialize DEFAULT_ZONE from the system default time zone.
* Upon return, DEFAULT_ZONE will not be NULL, unless operator new()
@@ -536,6 +538,7 @@ static void U_CALLCONV initDefault()
{
ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);
+ Mutex lock(&gDefaultZoneMutex);
// If setDefault() has already been called we can skip getting the
// default zone information from the system.
if (DEFAULT_ZONE != NULL) {
@@ -557,9 +560,6 @@ static void U_CALLCONV initDefault()
TimeZone *default_zone = TimeZone::detectHostTimeZone();
- // The only way for DEFAULT_ZONE to be non-null at this point is if the user
- // made a thread-unsafe call to setDefault() or adoptDefault() in another
- // thread while this thread was doing something that required getting the default.
U_ASSERT(DEFAULT_ZONE == NULL);
DEFAULT_ZONE = default_zone;
@@ -571,7 +571,10 @@ TimeZone* U_EXPORT2
TimeZone::createDefault()
{
umtx_initOnce(gDefaultZoneInitOnce, initDefault);
- return (DEFAULT_ZONE != NULL) ? DEFAULT_ZONE->clone() : NULL;
+ {
+ Mutex lock(&gDefaultZoneMutex);
+ return (DEFAULT_ZONE != NULL) ? DEFAULT_ZONE->clone() : NULL;
+ }
}
// -------------------------------------
@@ -581,9 +584,12 @@ TimeZone::adoptDefault(TimeZone* zone)
{
if (zone != NULL)
{
- TimeZone *old = DEFAULT_ZONE;
- DEFAULT_ZONE = zone;
- delete old;
+ {
+ Mutex lock(&gDefaultZoneMutex);
+ TimeZone *old = DEFAULT_ZONE;
+ DEFAULT_ZONE = zone;
+ delete old;
+ }
ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);
}
}
diff --git a/deps/icu-small/source/i18n/titletrn.cpp b/deps/icu-small/source/i18n/titletrn.cpp
index 4e75c824a0..a6beac2149 100644
--- a/deps/icu-small/source/i18n/titletrn.cpp
+++ b/deps/icu-small/source/i18n/titletrn.cpp
@@ -60,7 +60,7 @@ TitlecaseTransliterator::TitlecaseTransliterator(const TitlecaseTransliterator&
/**
* Transliterator API.
*/
-Transliterator* TitlecaseTransliterator::clone(void) const {
+TitlecaseTransliterator* TitlecaseTransliterator::clone() const {
return new TitlecaseTransliterator(*this);
}
diff --git a/deps/icu-small/source/i18n/titletrn.h b/deps/icu-small/source/i18n/titletrn.h
index 166378fe9d..4e45ac6f81 100644
--- a/deps/icu-small/source/i18n/titletrn.h
+++ b/deps/icu-small/source/i18n/titletrn.h
@@ -52,7 +52,7 @@ class TitlecaseTransliterator : public CaseMapTransliterator {
* Transliterator API.
* @return a copy of the object.
*/
- virtual Transliterator* clone(void) const;
+ virtual TitlecaseTransliterator* clone() const;
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
diff --git a/deps/icu-small/source/i18n/tmunit.cpp b/deps/icu-small/source/i18n/tmunit.cpp
index 3e98010515..b96dfbb572 100644
--- a/deps/icu-small/source/i18n/tmunit.cpp
+++ b/deps/icu-small/source/i18n/tmunit.cpp
@@ -102,7 +102,7 @@ TimeUnit::TimeUnit(const TimeUnit& other)
: MeasureUnit(other), fTimeUnitField(other.fTimeUnitField) {
}
-UObject*
+TimeUnit*
TimeUnit::clone() const {
return new TimeUnit(*this);
}
diff --git a/deps/icu-small/source/i18n/tmutamt.cpp b/deps/icu-small/source/i18n/tmutamt.cpp
index 0e2b91fbb2..a143bcf8f7 100644
--- a/deps/icu-small/source/i18n/tmutamt.cpp
+++ b/deps/icu-small/source/i18n/tmutamt.cpp
@@ -50,7 +50,7 @@ TimeUnitAmount::operator==(const UObject& other) const {
return Measure::operator==(other);
}
-UObject*
+TimeUnitAmount*
TimeUnitAmount::clone() const {
return new TimeUnitAmount(*this);
}
diff --git a/deps/icu-small/source/i18n/tmutfmt.cpp b/deps/icu-small/source/i18n/tmutfmt.cpp
index dad8825e70..231ea5799c 100644
--- a/deps/icu-small/source/i18n/tmutfmt.cpp
+++ b/deps/icu-small/source/i18n/tmutfmt.cpp
@@ -136,8 +136,8 @@ TimeUnitFormat::~TimeUnitFormat() {
}
-Format*
-TimeUnitFormat::clone(void) const {
+TimeUnitFormat*
+TimeUnitFormat::clone() const {
return new TimeUnitFormat(*this);
}
@@ -685,7 +685,7 @@ TimeUnitFormat::setNumberFormat(const NumberFormat& format, UErrorCode& status){
if (U_FAILURE(status)) {
return;
}
- adoptNumberFormat((NumberFormat *)format.clone(), status);
+ adoptNumberFormat(format.clone(), status);
}
@@ -721,8 +721,8 @@ TimeUnitFormat::copyHash(const Hashtable* source, Hashtable* target, UErrorCode&
const UHashTok valueTok = element->value;
const MessageFormat** value = (const MessageFormat**)valueTok.pointer;
MessageFormat** newVal = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*));
- newVal[0] = (MessageFormat*)value[0]->clone();
- newVal[1] = (MessageFormat*)value[1]->clone();
+ newVal[0] = value[0]->clone();
+ newVal[1] = value[1]->clone();
target->put(UnicodeString(*key), newVal, status);
if ( U_FAILURE(status) ) {
delete newVal[0];
diff --git a/deps/icu-small/source/i18n/tolowtrn.cpp b/deps/icu-small/source/i18n/tolowtrn.cpp
index 063cc88d1c..02ec05cd52 100644
--- a/deps/icu-small/source/i18n/tolowtrn.cpp
+++ b/deps/icu-small/source/i18n/tolowtrn.cpp
@@ -58,7 +58,7 @@ LowercaseTransliterator::LowercaseTransliterator(const LowercaseTransliterator&
/**
* Transliterator API.
*/
-Transliterator* LowercaseTransliterator::clone(void) const {
+LowercaseTransliterator* LowercaseTransliterator::clone() const {
return new LowercaseTransliterator(*this);
}
diff --git a/deps/icu-small/source/i18n/tolowtrn.h b/deps/icu-small/source/i18n/tolowtrn.h
index e311431224..2fbfb90e1b 100644
--- a/deps/icu-small/source/i18n/tolowtrn.h
+++ b/deps/icu-small/source/i18n/tolowtrn.h
@@ -50,7 +50,7 @@ class LowercaseTransliterator : public CaseMapTransliterator {
* Transliterator API.
* @return a copy of the object.
*/
- virtual Transliterator* clone(void) const;
+ virtual LowercaseTransliterator* clone() const;
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
diff --git a/deps/icu-small/source/i18n/toupptrn.cpp b/deps/icu-small/source/i18n/toupptrn.cpp
index 098dba9a3c..2a8b78b9a6 100644
--- a/deps/icu-small/source/i18n/toupptrn.cpp
+++ b/deps/icu-small/source/i18n/toupptrn.cpp
@@ -58,7 +58,7 @@ UppercaseTransliterator::UppercaseTransliterator(const UppercaseTransliterator&
/**
* Transliterator API.
*/
-Transliterator* UppercaseTransliterator::clone(void) const {
+UppercaseTransliterator* UppercaseTransliterator::clone() const {
return new UppercaseTransliterator(*this);
}
diff --git a/deps/icu-small/source/i18n/toupptrn.h b/deps/icu-small/source/i18n/toupptrn.h
index 677a04e5c7..e96ca8f0ba 100644
--- a/deps/icu-small/source/i18n/toupptrn.h
+++ b/deps/icu-small/source/i18n/toupptrn.h
@@ -50,7 +50,7 @@ class UppercaseTransliterator : public CaseMapTransliterator {
* Transliterator API.
* @return a copy of the object.
*/
- virtual Transliterator* clone(void) const;
+ virtual UppercaseTransliterator* clone() const;
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
diff --git a/deps/icu-small/source/i18n/translit.cpp b/deps/icu-small/source/i18n/translit.cpp
index 9f5563b479..039acaf157 100644
--- a/deps/icu-small/source/i18n/translit.cpp
+++ b/deps/icu-small/source/i18n/translit.cpp
@@ -91,10 +91,7 @@ static const char RB_RULE_BASED_IDS[] = "RuleBasedTransliteratorIDs";
/**
* The mutex controlling access to registry object.
*/
-static icu::UMutex *registryMutex() {
- static icu::UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static icu::UMutex registryMutex;
/**
* System transliterator registry; non-null when initialized.
@@ -161,7 +158,7 @@ Transliterator::Transliterator(const Transliterator& other) :
if (other.filter != 0) {
// We own the filter, so we must have our own copy
- filter = (UnicodeFilter*) other.filter->clone();
+ filter = other.filter->clone();
}
}
@@ -178,7 +175,7 @@ Transliterator& Transliterator::operator=(const Transliterator& other) {
ID.getTerminatedBuffer();
maximumContextLength = other.maximumContextLength;
- adoptFilter((other.filter == 0) ? 0 : (UnicodeFilter*) other.filter->clone());
+ adoptFilter((other.filter == 0) ? 0 : other.filter->clone());
return *this;
}
@@ -926,13 +923,15 @@ Transliterator::createInstance(const UnicodeString& ID,
return NULL;
}
- UnicodeSet* globalFilter;
+ UnicodeSet* globalFilter = nullptr;
// TODO add code for parseError...currently unused, but
// later may be used by parsing code...
if (!TransliteratorIDParser::parseCompoundID(ID, dir, canonID, list, globalFilter)) {
status = U_INVALID_ID;
+ delete globalFilter;
return NULL;
}
+ LocalPointer<UnicodeSet> lpGlobalFilter(globalFilter);
TransliteratorIDParser::instantiateList(list, status);
if (U_FAILURE(status)) {
@@ -956,8 +955,8 @@ Transliterator::createInstance(const UnicodeString& ID,
// Check null pointer
if (t != NULL) {
t->setID(canonID);
- if (globalFilter != NULL) {
- t->adoptFilter(globalFilter);
+ if (lpGlobalFilter.isValid()) {
+ t->adoptFilter(lpGlobalFilter.orphan());
}
}
else if (U_SUCCESS(status)) {
@@ -981,11 +980,11 @@ Transliterator* Transliterator::createBasicInstance(const UnicodeString& id,
TransliteratorAlias* alias = 0;
Transliterator* t = 0;
- umtx_lock(registryMutex());
+ umtx_lock(&registryMutex);
if (HAVE_REGISTRY(ec)) {
t = registry->get(id, alias, ec);
}
- umtx_unlock(registryMutex());
+ umtx_unlock(&registryMutex);
if (U_FAILURE(ec)) {
delete t;
@@ -1013,11 +1012,11 @@ Transliterator* Transliterator::createBasicInstance(const UnicodeString& id,
alias = 0;
// Step 2. reget
- umtx_lock(registryMutex());
+ umtx_lock(&registryMutex);
if (HAVE_REGISTRY(ec)) {
t = registry->reget(id, parser, alias, ec);
}
- umtx_unlock(registryMutex());
+ umtx_unlock(&registryMutex);
// Step 3. Loop back around!
} else {
@@ -1104,6 +1103,10 @@ Transliterator::createFromRules(const UnicodeString& ID,
UnicodeString* idBlock = (UnicodeString*)parser.idBlockVector.elementAt(i);
if (!idBlock->isEmpty()) {
Transliterator* temp = createInstance(*idBlock, UTRANS_FORWARD, parseError, status);
+ if (U_FAILURE(status)) {
+ delete temp;
+ return nullptr;
+ }
if (temp != NULL && typeid(*temp) != typeid(NullTransliterator))
transliterators.addElement(temp, status);
else
@@ -1117,8 +1120,10 @@ Transliterator::createFromRules(const UnicodeString& ID,
data, TRUE);
// Check if NULL before adding it to transliterators to avoid future usage of NULL pointer.
if (temprbt == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- return t;
+ if (U_SUCCESS(status)) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ }
+ return t;
}
transliterators.addElement(temprbt, status);
}
@@ -1215,7 +1220,7 @@ UnicodeSet& Transliterator::getTargetSet(UnicodeSet& result) const {
void U_EXPORT2 Transliterator::registerFactory(const UnicodeString& id,
Transliterator::Factory factory,
Transliterator::Token context) {
- Mutex lock(registryMutex());
+ Mutex lock(&registryMutex);
UErrorCode ec = U_ZERO_ERROR;
if (HAVE_REGISTRY(ec)) {
_registerFactory(id, factory, context);
@@ -1254,7 +1259,7 @@ void Transliterator::_registerSpecialInverse(const UnicodeString& target,
* @see #unregister
*/
void U_EXPORT2 Transliterator::registerInstance(Transliterator* adoptedPrototype) {
- Mutex lock(registryMutex());
+ Mutex lock(&registryMutex);
UErrorCode ec = U_ZERO_ERROR;
if (HAVE_REGISTRY(ec)) {
_registerInstance(adoptedPrototype);
@@ -1268,7 +1273,7 @@ void Transliterator::_registerInstance(Transliterator* adoptedPrototype) {
void U_EXPORT2 Transliterator::registerAlias(const UnicodeString& aliasID,
const UnicodeString& realID) {
- Mutex lock(registryMutex());
+ Mutex lock(&registryMutex);
UErrorCode ec = U_ZERO_ERROR;
if (HAVE_REGISTRY(ec)) {
_registerAlias(aliasID, realID);
@@ -1290,7 +1295,7 @@ void Transliterator::_registerAlias(const UnicodeString& aliasID,
*/
void U_EXPORT2 Transliterator::unregister(const UnicodeString& ID) {
- Mutex lock(registryMutex());
+ Mutex lock(&registryMutex);
UErrorCode ec = U_ZERO_ERROR;
if (HAVE_REGISTRY(ec)) {
registry->remove(ID);
@@ -1305,7 +1310,7 @@ void U_EXPORT2 Transliterator::unregister(const UnicodeString& ID) {
*/
int32_t U_EXPORT2 Transliterator::countAvailableIDs(void) {
int32_t retVal = 0;
- Mutex lock(registryMutex());
+ Mutex lock(&registryMutex);
UErrorCode ec = U_ZERO_ERROR;
if (HAVE_REGISTRY(ec)) {
retVal = registry->countAvailableIDs();
@@ -1321,12 +1326,12 @@ int32_t U_EXPORT2 Transliterator::countAvailableIDs(void) {
*/
const UnicodeString& U_EXPORT2 Transliterator::getAvailableID(int32_t index) {
const UnicodeString* result = NULL;
- umtx_lock(registryMutex());
+ umtx_lock(&registryMutex);
UErrorCode ec = U_ZERO_ERROR;
if (HAVE_REGISTRY(ec)) {
result = &registry->getAvailableID(index);
}
- umtx_unlock(registryMutex());
+ umtx_unlock(&registryMutex);
U_ASSERT(result != NULL); // fail if no registry
return *result;
}
@@ -1334,11 +1339,11 @@ const UnicodeString& U_EXPORT2 Transliterator::getAvailableID(int32_t index) {
StringEnumeration* U_EXPORT2 Transliterator::getAvailableIDs(UErrorCode& ec) {
if (U_FAILURE(ec)) return NULL;
StringEnumeration* result = NULL;
- umtx_lock(registryMutex());
+ umtx_lock(&registryMutex);
if (HAVE_REGISTRY(ec)) {
result = registry->getAvailableIDs();
}
- umtx_unlock(registryMutex());
+ umtx_unlock(&registryMutex);
if (result == NULL) {
ec = U_INTERNAL_TRANSLITERATOR_ERROR;
}
@@ -1346,14 +1351,14 @@ StringEnumeration* U_EXPORT2 Transliterator::getAvailableIDs(UErrorCode& ec) {
}
int32_t U_EXPORT2 Transliterator::countAvailableSources(void) {
- Mutex lock(registryMutex());
+ Mutex lock(&registryMutex);
UErrorCode ec = U_ZERO_ERROR;
return HAVE_REGISTRY(ec) ? _countAvailableSources() : 0;
}
UnicodeString& U_EXPORT2 Transliterator::getAvailableSource(int32_t index,
UnicodeString& result) {
- Mutex lock(registryMutex());
+ Mutex lock(&registryMutex);
UErrorCode ec = U_ZERO_ERROR;
if (HAVE_REGISTRY(ec)) {
_getAvailableSource(index, result);
@@ -1362,7 +1367,7 @@ UnicodeString& U_EXPORT2 Transliterator::getAvailableSource(int32_t index,
}
int32_t U_EXPORT2 Transliterator::countAvailableTargets(const UnicodeString& source) {
- Mutex lock(registryMutex());
+ Mutex lock(&registryMutex);
UErrorCode ec = U_ZERO_ERROR;
return HAVE_REGISTRY(ec) ? _countAvailableTargets(source) : 0;
}
@@ -1370,7 +1375,7 @@ int32_t U_EXPORT2 Transliterator::countAvailableTargets(const UnicodeString& sou
UnicodeString& U_EXPORT2 Transliterator::getAvailableTarget(int32_t index,
const UnicodeString& source,
UnicodeString& result) {
- Mutex lock(registryMutex());
+ Mutex lock(&registryMutex);
UErrorCode ec = U_ZERO_ERROR;
if (HAVE_REGISTRY(ec)) {
_getAvailableTarget(index, source, result);
@@ -1380,7 +1385,7 @@ UnicodeString& U_EXPORT2 Transliterator::getAvailableTarget(int32_t index,
int32_t U_EXPORT2 Transliterator::countAvailableVariants(const UnicodeString& source,
const UnicodeString& target) {
- Mutex lock(registryMutex());
+ Mutex lock(&registryMutex);
UErrorCode ec = U_ZERO_ERROR;
return HAVE_REGISTRY(ec) ? _countAvailableVariants(source, target) : 0;
}
@@ -1389,7 +1394,7 @@ UnicodeString& U_EXPORT2 Transliterator::getAvailableVariant(int32_t index,
const UnicodeString& source,
const UnicodeString& target,
UnicodeString& result) {
- Mutex lock(registryMutex());
+ Mutex lock(&registryMutex);
UErrorCode ec = U_ZERO_ERROR;
if (HAVE_REGISTRY(ec)) {
_getAvailableVariant(index, source, target, result);
diff --git a/deps/icu-small/source/i18n/transreg.cpp b/deps/icu-small/source/i18n/transreg.cpp
index 032a73fd14..8c90effcc2 100644
--- a/deps/icu-small/source/i18n/transreg.cpp
+++ b/deps/icu-small/source/i18n/transreg.cpp
@@ -131,7 +131,7 @@ Transliterator* TransliteratorAlias::create(UParseError& pe,
return 0;
}
if (compoundFilter != 0)
- t->adoptFilter((UnicodeSet*)compoundFilter->clone());
+ t->adoptFilter(compoundFilter->clone());
break;
case COMPOUND:
{
@@ -173,8 +173,8 @@ Transliterator* TransliteratorAlias::create(UParseError& pe,
if (U_SUCCESS(ec)) {
t = new CompoundTransliterator(ID, transliterators,
- (compoundFilter ? (UnicodeSet*)(compoundFilter->clone()) : 0),
- anonymousRBTs, pe, ec);
+ (compoundFilter ? compoundFilter->clone() : nullptr),
+ anonymousRBTs, pe, ec);
if (t == 0) {
ec = U_MEMORY_ALLOCATION_ERROR;
return 0;
@@ -946,7 +946,7 @@ void TransliteratorRegistry::registerEntry(const UnicodeString& ID,
if (visible) {
registerSTV(source, target, variant);
if (!availableIDs.contains((void*) &ID)) {
- UnicodeString *newID = (UnicodeString *)ID.clone();
+ UnicodeString *newID = ID.clone();
// Check to make sure newID was created.
if (newID != NULL) {
// NUL-terminate the ID string
diff --git a/deps/icu-small/source/i18n/tridpars.cpp b/deps/icu-small/source/i18n/tridpars.cpp
index cbfdf03c42..eb6c6bbba3 100644
--- a/deps/icu-small/source/i18n/tridpars.cpp
+++ b/deps/icu-small/source/i18n/tridpars.cpp
@@ -50,10 +50,7 @@ static UInitOnce gSpecialInversesInitOnce = U_INITONCE_INITIALIZER;
/**
* The mutex controlling access to SPECIAL_INVERSES
*/
-static UMutex *LOCK() {
- static UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static UMutex LOCK;
TransliteratorIDParser::Specs::Specs(const UnicodeString& s, const UnicodeString& t,
const UnicodeString& v, UBool sawS,
@@ -297,6 +294,7 @@ UnicodeSet* TransliteratorIDParser::parseGlobalFilter(const UnicodeString& id, i
pos = ppos.getIndex();
if (withParens == 1 && !ICU_Utility::parseChar(id, pos, CLOSE_REV)) {
+ delete filter;
pos = start;
return NULL;
}
@@ -662,7 +660,7 @@ void TransliteratorIDParser::registerSpecialInverse(const UnicodeString& target,
bidirectional = FALSE;
}
- Mutex lock(LOCK());
+ Mutex lock(&LOCK);
UnicodeString *tempus = new UnicodeString(inverseTarget); // Used for null pointer check before usage.
if (tempus == NULL) {
@@ -866,9 +864,9 @@ TransliteratorIDParser::specsToSpecialInverse(const Specs& specs, UErrorCode &st
UnicodeString* inverseTarget;
- umtx_lock(LOCK());
+ umtx_lock(&LOCK);
inverseTarget = (UnicodeString*) SPECIAL_INVERSES->get(specs.target);
- umtx_unlock(LOCK());
+ umtx_unlock(&LOCK);
if (inverseTarget != NULL) {
// If the original ID contained "Any-" then make the
diff --git a/deps/icu-small/source/i18n/tzfmt.cpp b/deps/icu-small/source/i18n/tzfmt.cpp
index c948c5f5e7..267d507aa7 100644
--- a/deps/icu-small/source/i18n/tzfmt.cpp
+++ b/deps/icu-small/source/i18n/tzfmt.cpp
@@ -19,12 +19,15 @@
#include "unicode/udat.h"
#include "unicode/ustring.h"
#include "unicode/utf16.h"
+#include "bytesinkutil.h"
+#include "charstr.h"
#include "tzgnames.h"
#include "cmemory.h"
#include "cstring.h"
#include "putilimp.h"
#include "uassert.h"
#include "ucln_in.h"
+#include "ulocimp.h"
#include "umutex.h"
#include "uresimp.h"
#include "ureslocs.h"
@@ -147,10 +150,7 @@ static icu::UInitOnce gZoneIdTrieInitOnce = U_INITONCE_INITIALIZER;
static TextTrieMap *gShortZoneIdTrie = NULL;
static icu::UInitOnce gShortZoneIdTrieInitOnce = U_INITONCE_INITIALIZER;
-static UMutex *gLock() {
- static UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static UMutex gLock;
U_CDECL_BEGIN
/**
@@ -327,10 +327,13 @@ TimeZoneFormat::TimeZoneFormat(const Locale& locale, UErrorCode& status)
const char* region = fLocale.getCountry();
int32_t regionLen = static_cast<int32_t>(uprv_strlen(region));
if (regionLen == 0) {
- char loc[ULOC_FULLNAME_CAPACITY];
- uloc_addLikelySubtags(fLocale.getName(), loc, sizeof(loc), &status);
+ CharString loc;
+ {
+ CharStringByteSink sink(&loc);
+ ulocimp_addLikelySubtags(fLocale.getName(), sink, &status);
+ }
- regionLen = uloc_getCountry(loc, fTargetRegion, sizeof(fTargetRegion), &status);
+ regionLen = uloc_getCountry(loc.data(), fTargetRegion, sizeof(fTargetRegion), &status);
if (U_SUCCESS(status)) {
fTargetRegion[regionLen] = 0;
} else {
@@ -502,7 +505,7 @@ TimeZoneFormat::operator==(const Format& other) const {
return isEqual;
}
-Format*
+TimeZoneFormat*
TimeZoneFormat::clone() const {
return new TimeZoneFormat(*this);
}
@@ -1385,12 +1388,12 @@ TimeZoneFormat::getTimeZoneGenericNames(UErrorCode& status) const {
return NULL;
}
- umtx_lock(gLock());
+ umtx_lock(&gLock);
if (fTimeZoneGenericNames == NULL) {
TimeZoneFormat *nonConstThis = const_cast<TimeZoneFormat *>(this);
nonConstThis->fTimeZoneGenericNames = TimeZoneGenericNames::createInstance(fLocale, status);
}
- umtx_unlock(gLock());
+ umtx_unlock(&gLock);
return fTimeZoneGenericNames;
}
@@ -1401,7 +1404,7 @@ TimeZoneFormat::getTZDBTimeZoneNames(UErrorCode& status) const {
return NULL;
}
- umtx_lock(gLock());
+ umtx_lock(&gLock);
if (fTZDBTimeZoneNames == NULL) {
TZDBTimeZoneNames *tzdbNames = new TZDBTimeZoneNames(fLocale);
if (tzdbNames == NULL) {
@@ -1411,7 +1414,7 @@ TimeZoneFormat::getTZDBTimeZoneNames(UErrorCode& status) const {
nonConstThis->fTZDBTimeZoneNames = tzdbNames;
}
}
- umtx_unlock(gLock());
+ umtx_unlock(&gLock);
return fTZDBTimeZoneNames;
}
@@ -1875,7 +1878,7 @@ TimeZoneFormat::parseOffsetFieldsWithPattern(const UnicodeString& text, int32_t
while (len > 0) {
UChar32 ch;
int32_t chLen;
- U16_GET(patStr, 0, 0, len, ch)
+ U16_GET(patStr, 0, 0, len, ch);
if (PatternProps::isWhiteSpace(ch)) {
chLen = U16_LENGTH(ch);
len -= chLen;
diff --git a/deps/icu-small/source/i18n/tzgnames.cpp b/deps/icu-small/source/i18n/tzgnames.cpp
index 4e3ecb4c60..e056461dc3 100644
--- a/deps/icu-small/source/i18n/tzgnames.cpp
+++ b/deps/icu-small/source/i18n/tzgnames.cpp
@@ -21,12 +21,15 @@
#include "unicode/strenum.h"
#include "unicode/vtzone.h"
+#include "bytesinkutil.h"
+#include "charstr.h"
#include "cmemory.h"
#include "cstring.h"
#include "mutex.h"
#include "uhash.h"
#include "uassert.h"
#include "umutex.h"
+#include "ulocimp.h"
#include "uresimp.h"
#include "ureslocs.h"
#include "zonemeta.h"
@@ -269,10 +272,7 @@ GNameSearchHandler::getMatches(int32_t& maxMatchLen) {
return results;
}
-static UMutex *gLock() {
- static UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static UMutex gLock;
class TZGNCore : public UMemory {
public:
@@ -412,10 +412,13 @@ TZGNCore::initialize(const Locale& locale, UErrorCode& status) {
const char* region = fLocale.getCountry();
int32_t regionLen = static_cast<int32_t>(uprv_strlen(region));
if (regionLen == 0) {
- char loc[ULOC_FULLNAME_CAPACITY];
- uloc_addLikelySubtags(fLocale.getName(), loc, sizeof(loc), &status);
+ CharString loc;
+ {
+ CharStringByteSink sink(&loc);
+ ulocimp_addLikelySubtags(fLocale.getName(), sink, &status);
+ }
- regionLen = uloc_getCountry(loc, fTargetRegion, sizeof(fTargetRegion), &status);
+ regionLen = uloc_getCountry(loc.data(), fTargetRegion, sizeof(fTargetRegion), &status);
if (U_SUCCESS(status)) {
fTargetRegion[regionLen] = 0;
} else {
@@ -488,11 +491,11 @@ TZGNCore::getGenericLocationName(const UnicodeString& tzCanonicalID, UnicodeStri
const UChar *locname = NULL;
TZGNCore *nonConstThis = const_cast<TZGNCore *>(this);
- umtx_lock(gLock());
+ umtx_lock(&gLock);
{
locname = nonConstThis->getGenericLocationName(tzCanonicalID);
}
- umtx_unlock(gLock());
+ umtx_unlock(&gLock);
if (locname == NULL) {
name.setToBogus();
@@ -743,11 +746,11 @@ TZGNCore::getPartialLocationName(const UnicodeString& tzCanonicalID,
const UChar *uplname = NULL;
TZGNCore *nonConstThis = const_cast<TZGNCore *>(this);
- umtx_lock(gLock());
+ umtx_lock(&gLock);
{
uplname = nonConstThis->getPartialLocationName(tzCanonicalID, mzID, isLong, mzDisplayName);
}
- umtx_unlock(gLock());
+ umtx_unlock(&gLock);
if (uplname == NULL) {
name.setToBogus();
@@ -1010,11 +1013,11 @@ TZGNCore::findLocal(const UnicodeString& text, int32_t start, uint32_t types, UE
TZGNCore *nonConstThis = const_cast<TZGNCore *>(this);
- umtx_lock(gLock());
+ umtx_lock(&gLock);
{
fGNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status);
}
- umtx_unlock(gLock());
+ umtx_unlock(&gLock);
if (U_FAILURE(status)) {
return NULL;
@@ -1041,7 +1044,7 @@ TZGNCore::findLocal(const UnicodeString& text, int32_t start, uint32_t types, UE
// All names are not yet loaded into the local trie.
// Load all available names into the trie. This could be very heavy.
- umtx_lock(gLock());
+ umtx_lock(&gLock);
{
if (!fGNamesTrieFullyLoaded) {
StringEnumeration *tzIDs = TimeZone::createTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL, NULL, NULL, status);
@@ -1063,18 +1066,18 @@ TZGNCore::findLocal(const UnicodeString& text, int32_t start, uint32_t types, UE
}
}
}
- umtx_unlock(gLock());
+ umtx_unlock(&gLock);
if (U_FAILURE(status)) {
return NULL;
}
- umtx_lock(gLock());
+ umtx_lock(&gLock);
{
// now try it again
fGNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status);
}
- umtx_unlock(gLock());
+ umtx_unlock(&gLock);
results = handler.getMatches(maxLen);
if (results != NULL && maxLen > 0) {
@@ -1115,10 +1118,7 @@ typedef struct TZGNCoreRef {
} TZGNCoreRef;
// TZGNCore object cache handling
-static UMutex *gTZGNLock() {
- static UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static UMutex gTZGNLock;
static UHashtable *gTZGNCoreCache = NULL;
static UBool gTZGNCoreCacheInitialized = FALSE;
@@ -1184,13 +1184,13 @@ TimeZoneGenericNames::TimeZoneGenericNames()
}
TimeZoneGenericNames::~TimeZoneGenericNames() {
- umtx_lock(gTZGNLock());
+ umtx_lock(&gTZGNLock);
{
U_ASSERT(fRef->refCount > 0);
// Just decrement the reference count
fRef->refCount--;
}
- umtx_unlock(gTZGNLock());
+ umtx_unlock(&gTZGNLock);
}
TimeZoneGenericNames*
@@ -1206,7 +1206,7 @@ TimeZoneGenericNames::createInstance(const Locale& locale, UErrorCode& status) {
TZGNCoreRef *cacheEntry = NULL;
{
- Mutex lock(gTZGNLock());
+ Mutex lock(&gTZGNLock);
if (!gTZGNCoreCacheInitialized) {
// Create empty hashtable
@@ -1298,13 +1298,13 @@ TimeZoneGenericNames*
TimeZoneGenericNames::clone() const {
TimeZoneGenericNames* other = new TimeZoneGenericNames();
if (other) {
- umtx_lock(gTZGNLock());
+ umtx_lock(&gTZGNLock);
{
// Just increments the reference count
fRef->refCount++;
other->fRef = fRef;
}
- umtx_unlock(gTZGNLock());
+ umtx_unlock(&gTZGNLock);
}
return other;
}
diff --git a/deps/icu-small/source/i18n/tznames.cpp b/deps/icu-small/source/i18n/tznames.cpp
index acd6aecdc0..d789c12363 100644
--- a/deps/icu-small/source/i18n/tznames.cpp
+++ b/deps/icu-small/source/i18n/tznames.cpp
@@ -29,10 +29,7 @@
U_NAMESPACE_BEGIN
// TimeZoneNames object cache handling
-static UMutex *gTimeZoneNamesLock() {
- static UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static UMutex gTimeZoneNamesLock;
static UHashtable *gTimeZoneNamesCache = NULL;
static UBool gTimeZoneNamesCacheInitialized = FALSE;
@@ -109,7 +106,7 @@ public:
virtual UBool operator==(const TimeZoneNames& other) const;
virtual UBool operator!=(const TimeZoneNames& other) const {return !operator==(other);}
- virtual TimeZoneNames* clone() const;
+ virtual TimeZoneNamesDelegate* clone() const;
StringEnumeration* getAvailableMetaZoneIDs(UErrorCode& status) const;
StringEnumeration* getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const;
@@ -135,7 +132,7 @@ TimeZoneNamesDelegate::TimeZoneNamesDelegate()
}
TimeZoneNamesDelegate::TimeZoneNamesDelegate(const Locale& locale, UErrorCode& status) {
- Mutex lock(gTimeZoneNamesLock());
+ Mutex lock(&gTimeZoneNamesLock);
if (!gTimeZoneNamesCacheInitialized) {
// Create empty hashtable if it is not already initialized.
gTimeZoneNamesCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status);
@@ -211,7 +208,7 @@ TimeZoneNamesDelegate::TimeZoneNamesDelegate(const Locale& locale, UErrorCode& s
}
TimeZoneNamesDelegate::~TimeZoneNamesDelegate() {
- umtx_lock(gTimeZoneNamesLock());
+ umtx_lock(&gTimeZoneNamesLock);
{
if (fTZnamesCacheEntry) {
U_ASSERT(fTZnamesCacheEntry->refCount > 0);
@@ -219,7 +216,7 @@ TimeZoneNamesDelegate::~TimeZoneNamesDelegate() {
fTZnamesCacheEntry->refCount--;
}
}
- umtx_unlock(gTimeZoneNamesLock());
+ umtx_unlock(&gTimeZoneNamesLock);
}
UBool
@@ -236,17 +233,17 @@ TimeZoneNamesDelegate::operator==(const TimeZoneNames& other) const {
return FALSE;
}
-TimeZoneNames*
+TimeZoneNamesDelegate*
TimeZoneNamesDelegate::clone() const {
TimeZoneNamesDelegate* other = new TimeZoneNamesDelegate();
if (other != NULL) {
- umtx_lock(gTimeZoneNamesLock());
+ umtx_lock(&gTimeZoneNamesLock);
{
// Just increment the reference count
fTZnamesCacheEntry->refCount++;
other->fTZnamesCacheEntry = fTZnamesCacheEntry;
}
- umtx_unlock(gTimeZoneNamesLock());
+ umtx_unlock(&gTimeZoneNamesLock);
}
return other;
}
diff --git a/deps/icu-small/source/i18n/tznames_impl.cpp b/deps/icu-small/source/i18n/tznames_impl.cpp
index d6e0ee2fbb..180b7fefbf 100644
--- a/deps/icu-small/source/i18n/tznames_impl.cpp
+++ b/deps/icu-small/source/i18n/tznames_impl.cpp
@@ -21,11 +21,14 @@
#include "unicode/utf16.h"
#include "tznames_impl.h"
+#include "bytesinkutil.h"
+#include "charstr.h"
#include "cmemory.h"
#include "cstring.h"
#include "uassert.h"
#include "mutex.h"
#include "resource.h"
+#include "ulocimp.h"
#include "uresimp.h"
#include "ureslocs.h"
#include "zonemeta.h"
@@ -49,10 +52,7 @@ static const UChar NO_NAME[] = { 0 }; // for empty no-fallback time
static const char* TZDBNAMES_KEYS[] = {"ss", "sd"};
static const int32_t TZDBNAMES_KEYS_SIZE = UPRV_LENGTHOF(TZDBNAMES_KEYS);
-static UMutex *gDataMutex() {
- static UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static UMutex gDataMutex;
static UHashtable* gTZDBNamesMap = NULL;
static icu::UInitOnce gTZDBNamesMapInitOnce = U_INITONCE_INITIALIZER;
@@ -388,7 +388,7 @@ TextTrieMap::search(const UnicodeString &text, int32_t start,
// Don't do unless it's really required.
// Mutex for protecting the lazy creation of the Trie node structure on the first call to search().
- static UMutex TextTrieMutex = U_MUTEX_INITIALIZER;
+ static UMutex TextTrieMutex;
Mutex lock(&TextTrieMutex);
if (fLazyContents != NULL) {
@@ -1113,7 +1113,7 @@ TimeZoneNamesImpl::operator==(const TimeZoneNames& other) const {
return FALSE;
}
-TimeZoneNames*
+TimeZoneNamesImpl*
TimeZoneNamesImpl::clone() const {
UErrorCode status = U_ZERO_ERROR;
return new TimeZoneNamesImpl(fLocale, status);
@@ -1214,7 +1214,7 @@ TimeZoneNamesImpl::getMetaZoneDisplayName(const UnicodeString& mzID,
TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this);
{
- Mutex lock(gDataMutex());
+ Mutex lock(&gDataMutex);
UErrorCode status = U_ZERO_ERROR;
znames = nonConstThis->loadMetaZoneNames(mzID, status);
if (U_FAILURE(status)) { return name; }
@@ -1240,7 +1240,7 @@ TimeZoneNamesImpl::getTimeZoneDisplayName(const UnicodeString& tzID, UTimeZoneNa
TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this);
{
- Mutex lock(gDataMutex());
+ Mutex lock(&gDataMutex);
UErrorCode status = U_ZERO_ERROR;
tznames = nonConstThis->loadTimeZoneNames(tzID, status);
if (U_FAILURE(status)) { return name; }
@@ -1263,7 +1263,7 @@ TimeZoneNamesImpl::getExemplarLocationName(const UnicodeString& tzID, UnicodeStr
TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this);
{
- Mutex lock(gDataMutex());
+ Mutex lock(&gDataMutex);
UErrorCode status = U_ZERO_ERROR;
tznames = nonConstThis->loadTimeZoneNames(tzID, status);
if (U_FAILURE(status)) { return name; }
@@ -1358,7 +1358,7 @@ TimeZoneNamesImpl::find(const UnicodeString& text, int32_t start, uint32_t types
// Synchronize so that data is not loaded multiple times.
// TODO: Consider more fine-grained synchronization.
{
- Mutex lock(gDataMutex());
+ Mutex lock(&gDataMutex);
// First try of lookup.
matches = doFind(handler, text, start, status);
@@ -1585,7 +1585,7 @@ void TimeZoneNamesImpl::loadAllDisplayNames(UErrorCode& status) {
if (U_FAILURE(status)) return;
{
- Mutex lock(gDataMutex());
+ Mutex lock(&gDataMutex);
internalLoadAllDisplayNames(status);
}
}
@@ -1602,7 +1602,7 @@ void TimeZoneNamesImpl::getDisplayNames(const UnicodeString& tzID,
// Load the time zone strings
{
- Mutex lock(gDataMutex());
+ Mutex lock(&gDataMutex);
tznames = (void*) nonConstThis->loadTimeZoneNames(tzID, status);
if (U_FAILURE(status)) { return; }
}
@@ -1622,7 +1622,7 @@ void TimeZoneNamesImpl::getDisplayNames(const UnicodeString& tzID,
} else {
// Load the meta zone strings
// Mutex is scoped to the "else" statement
- Mutex lock(gDataMutex());
+ Mutex lock(&gDataMutex);
mznames = (void*) nonConstThis->loadMetaZoneNames(mzID, status);
if (U_FAILURE(status)) { return; }
// Note: when the metazone doesn't exist, in Java, loadMetaZoneNames returns
@@ -2135,9 +2135,12 @@ TZDBTimeZoneNames::TZDBTimeZoneNames(const Locale& locale)
int32_t regionLen = static_cast<int32_t>(uprv_strlen(region));
if (regionLen == 0) {
UErrorCode status = U_ZERO_ERROR;
- char loc[ULOC_FULLNAME_CAPACITY];
- uloc_addLikelySubtags(fLocale.getName(), loc, sizeof(loc), &status);
- regionLen = uloc_getCountry(loc, fRegion, sizeof(fRegion), &status);
+ CharString loc;
+ {
+ CharStringByteSink sink(&loc);
+ ulocimp_addLikelySubtags(fLocale.getName(), sink, &status);
+ }
+ regionLen = uloc_getCountry(loc.data(), fRegion, sizeof(fRegion), &status);
if (U_SUCCESS(status) && regionLen < (int32_t)sizeof(fRegion)) {
useWorld = FALSE;
}
@@ -2162,7 +2165,7 @@ TZDBTimeZoneNames::operator==(const TimeZoneNames& other) const {
return FALSE;
}
-TimeZoneNames*
+TZDBTimeZoneNames*
TZDBTimeZoneNames::clone() const {
return new TZDBTimeZoneNames(fLocale);
}
@@ -2247,7 +2250,7 @@ TZDBTimeZoneNames::getMetaZoneNames(const UnicodeString& mzID, UErrorCode& statu
U_ASSERT(status == U_ZERO_ERROR); // already checked length above
mzIDKey[mzID.length()] = 0;
- static UMutex gTZDBNamesMapLock = U_MUTEX_INITIALIZER;
+ static UMutex gTZDBNamesMapLock;
umtx_lock(&gTZDBNamesMapLock);
{
void *cacheVal = uhash_get(gTZDBNamesMap, mzIDKey);
diff --git a/deps/icu-small/source/i18n/tznames_impl.h b/deps/icu-small/source/i18n/tznames_impl.h
index 4db036e747..1286eeb80d 100644
--- a/deps/icu-small/source/i18n/tznames_impl.h
+++ b/deps/icu-small/source/i18n/tznames_impl.h
@@ -174,7 +174,7 @@ public:
virtual ~TimeZoneNamesImpl();
virtual UBool operator==(const TimeZoneNames& other) const;
- virtual TimeZoneNames* clone() const;
+ virtual TimeZoneNamesImpl* clone() const;
StringEnumeration* getAvailableMetaZoneIDs(UErrorCode& status) const;
StringEnumeration* getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const;
@@ -236,7 +236,7 @@ public:
virtual ~TZDBTimeZoneNames();
virtual UBool operator==(const TimeZoneNames& other) const;
- virtual TimeZoneNames* clone() const;
+ virtual TZDBTimeZoneNames* clone() const;
StringEnumeration* getAvailableMetaZoneIDs(UErrorCode& status) const;
StringEnumeration* getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const;
diff --git a/deps/icu-small/source/i18n/tzrule.cpp b/deps/icu-small/source/i18n/tzrule.cpp
index f60a5e0dd5..c4bf386fd4 100644
--- a/deps/icu-small/source/i18n/tzrule.cpp
+++ b/deps/icu-small/source/i18n/tzrule.cpp
@@ -108,7 +108,7 @@ InitialTimeZoneRule::~InitialTimeZoneRule() {
}
InitialTimeZoneRule*
-InitialTimeZoneRule::clone(void) const {
+InitialTimeZoneRule::clone() const {
return new InitialTimeZoneRule(*this);
}
diff --git a/deps/icu-small/source/i18n/ucal.cpp b/deps/icu-small/source/i18n/ucal.cpp
index 4154eea83f..cca1f70cf5 100644
--- a/deps/icu-small/source/i18n/ucal.cpp
+++ b/deps/icu-small/source/i18n/ucal.cpp
@@ -34,7 +34,7 @@ U_NAMESPACE_USE
static TimeZone*
_createTimeZone(const UChar* zoneID, int32_t len, UErrorCode* ec) {
TimeZone* zone = NULL;
- if (ec!=NULL && U_SUCCESS(*ec)) {
+ if (ec != NULL && U_SUCCESS(*ec)) {
// Note that if zoneID is invalid, we get back GMT. This odd
// behavior is by design and goes back to the JDK. The only
// failure we will see is a memory allocation failure.
@@ -69,7 +69,7 @@ ucal_openCountryTimeZones(const char* country, UErrorCode* ec) {
U_CAPI int32_t U_EXPORT2
ucal_getDefaultTimeZone(UChar* result, int32_t resultCapacity, UErrorCode* ec) {
int32_t len = 0;
- if (ec!=NULL && U_SUCCESS(*ec)) {
+ if (ec != NULL && U_SUCCESS(*ec)) {
TimeZone* zone = TimeZone::createDefault();
if (zone == NULL) {
*ec = U_MEMORY_ALLOCATION_ERROR;
@@ -91,6 +91,23 @@ ucal_setDefaultTimeZone(const UChar* zoneID, UErrorCode* ec) {
}
}
+U_DRAFT int32_t U_EXPORT2
+ucal_getHostTimeZone(UChar* result, int32_t resultCapacity, UErrorCode* ec) {
+ int32_t len = 0;
+ if (ec != NULL && U_SUCCESS(*ec)) {
+ TimeZone *zone = TimeZone::detectHostTimeZone();
+ if (zone == NULL) {
+ *ec = U_MEMORY_ALLOCATION_ERROR;
+ } else {
+ UnicodeString id;
+ zone->getID(id);
+ delete zone;
+ len = id.extract(result, resultCapacity, *ec);
+ }
+ }
+ return len;
+}
+
U_CAPI int32_t U_EXPORT2
ucal_getDSTSavings(const UChar* zoneID, UErrorCode* ec) {
int32_t result = 0;
@@ -140,8 +157,8 @@ ucal_open( const UChar* zoneID,
if(U_FAILURE(*status)) return 0;
- TimeZone* zone = (zoneID==NULL) ? TimeZone::createDefault()
- : _createTimeZone(zoneID, len, status);
+ LocalPointer<TimeZone> zone( (zoneID==NULL) ? TimeZone::createDefault()
+ : _createTimeZone(zoneID, len, status), *status);
if (U_FAILURE(*status)) {
return NULL;
@@ -157,9 +174,9 @@ ucal_open( const UChar* zoneID,
if (U_FAILURE(*status)) {
return NULL;
}
- return (UCalendar*)Calendar::createInstance(zone, Locale(localeBuf), *status);
+ return (UCalendar*)Calendar::createInstance(zone.orphan(), Locale(localeBuf), *status);
}
- return (UCalendar*)Calendar::createInstance(zone, Locale(locale), *status);
+ return (UCalendar*)Calendar::createInstance(zone.orphan(), Locale(locale), *status);
}
U_CAPI void U_EXPORT2
diff --git a/deps/icu-small/source/i18n/udat.cpp b/deps/icu-small/source/i18n/udat.cpp
index b7d85cc179..da8befc9e3 100644
--- a/deps/icu-small/source/i18n/udat.cpp
+++ b/deps/icu-small/source/i18n/udat.cpp
@@ -167,9 +167,13 @@ udat_open(UDateFormatStyle timeStyle,
}
}
- if(fmt == 0) {
+ if(fmt == nullptr) {
*status = U_MEMORY_ALLOCATION_ERROR;
- return 0;
+ return nullptr;
+ }
+ if (U_FAILURE(*status)) {
+ delete fmt;
+ return nullptr;
}
if(tzID != 0) {
diff --git a/deps/icu-small/source/i18n/unesctrn.cpp b/deps/icu-small/source/i18n/unesctrn.cpp
index fcce9528e2..604cb0a4ba 100644
--- a/deps/icu-small/source/i18n/unesctrn.cpp
+++ b/deps/icu-small/source/i18n/unesctrn.cpp
@@ -164,7 +164,7 @@ UnescapeTransliterator::~UnescapeTransliterator() {
/**
* Transliterator API.
*/
-Transliterator* UnescapeTransliterator::clone() const {
+UnescapeTransliterator* UnescapeTransliterator::clone() const {
return new UnescapeTransliterator(*this);
}
diff --git a/deps/icu-small/source/i18n/unesctrn.h b/deps/icu-small/source/i18n/unesctrn.h
index e8e171f2bc..57dd8d32cf 100644
--- a/deps/icu-small/source/i18n/unesctrn.h
+++ b/deps/icu-small/source/i18n/unesctrn.h
@@ -77,7 +77,7 @@ class UnescapeTransliterator : public Transliterator {
/**
* Transliterator API.
*/
- virtual Transliterator* clone() const;
+ virtual UnescapeTransliterator* clone() const;
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
diff --git a/deps/icu-small/source/i18n/uni2name.cpp b/deps/icu-small/source/i18n/uni2name.cpp
index 86d7a4904a..9df3924ae5 100644
--- a/deps/icu-small/source/i18n/uni2name.cpp
+++ b/deps/icu-small/source/i18n/uni2name.cpp
@@ -60,7 +60,7 @@ UnicodeNameTransliterator::UnicodeNameTransliterator(const UnicodeNameTransliter
/**
* Transliterator API.
*/
-Transliterator* UnicodeNameTransliterator::clone(void) const {
+UnicodeNameTransliterator* UnicodeNameTransliterator::clone() const {
return new UnicodeNameTransliterator(*this);
}
diff --git a/deps/icu-small/source/i18n/uni2name.h b/deps/icu-small/source/i18n/uni2name.h
index 4d6eaa0a9a..99309c8e0f 100644
--- a/deps/icu-small/source/i18n/uni2name.h
+++ b/deps/icu-small/source/i18n/uni2name.h
@@ -48,7 +48,7 @@ class UnicodeNameTransliterator : public Transliterator {
/**
* Transliterator API.
*/
- virtual Transliterator* clone(void) const;
+ virtual UnicodeNameTransliterator* clone() const;
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
diff --git a/deps/icu-small/source/i18n/unicode/alphaindex.h b/deps/icu-small/source/i18n/unicode/alphaindex.h
index dfb6110a36..fe43995fe8 100644
--- a/deps/icu-small/source/i18n/unicode/alphaindex.h
+++ b/deps/icu-small/source/i18n/unicode/alphaindex.h
@@ -13,6 +13,9 @@
#define INDEXCHARS_H
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/uobject.h"
#include "unicode/locid.h"
#include "unicode/unistr.h"
@@ -757,4 +760,7 @@ private:
U_NAMESPACE_END
#endif // !UCONFIG_NO_COLLATION
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/i18n/unicode/basictz.h b/deps/icu-small/source/i18n/unicode/basictz.h
index eb62abaf0a..e1db2a8223 100644
--- a/deps/icu-small/source/i18n/unicode/basictz.h
+++ b/deps/icu-small/source/i18n/unicode/basictz.h
@@ -16,6 +16,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
#include "unicode/timezone.h"
@@ -42,6 +44,14 @@ public:
virtual ~BasicTimeZone();
/**
+ * Clones this object polymorphically.
+ * The caller owns the result and should delete it when done.
+ * @return clone, or nullptr if an error occurred
+ * @stable ICU 3.8
+ */
+ virtual BasicTimeZone* clone() const = 0;
+
+ /**
* Gets the first time zone transition after the base time.
* @param base The base time.
* @param inclusive Whether the base time is inclusive or not.
@@ -211,6 +221,8 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // BASICTZ_H
//eof
diff --git a/deps/icu-small/source/i18n/unicode/calendar.h b/deps/icu-small/source/i18n/unicode/calendar.h
index 023cf053f2..2a8c2935ca 100644
--- a/deps/icu-small/source/i18n/unicode/calendar.h
+++ b/deps/icu-small/source/i18n/unicode/calendar.h
@@ -29,6 +29,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Calendar object
@@ -184,7 +186,7 @@ class BasicTimeZone;
*/
class U_I18N_API Calendar : public UObject {
public:
-
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Field IDs for date and time. Used to specify date/time fields. ERA is calendar
* specific. Example ranges given are for illustration only; see specific Calendar
@@ -227,6 +229,7 @@ public:
FIELD_COUNT = UCAL_FIELD_COUNT // See ucal.h for other fields.
#endif /* U_HIDE_DEPRECATED_API */
};
+#endif // U_FORCE_HIDE_DEPRECATED_API
#ifndef U_HIDE_DEPRECATED_API
/**
@@ -287,7 +290,7 @@ public:
* @return a polymorphic copy of this calendar.
* @stable ICU 2.0
*/
- virtual Calendar* clone(void) const = 0;
+ virtual Calendar* clone() const = 0;
/**
* Creates a Calendar using the default timezone and locale. Clients are responsible
@@ -518,6 +521,7 @@ public:
*/
UBool after(const Calendar& when, UErrorCode& status) const;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* UDate Arithmetic function. Adds the specified (signed) amount of time to the given
* time field, based on the calendar's rules. For example, to subtract 5 days from
@@ -539,6 +543,7 @@ public:
* @deprecated ICU 2.6. use add(UCalendarDateFields field, int32_t amount, UErrorCode& status) instead.
*/
virtual void add(EDateFields field, int32_t amount, UErrorCode& status);
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* UDate Arithmetic function. Adds the specified (signed) amount of time to the given
@@ -632,6 +637,7 @@ public:
*/
inline void roll(UCalendarDateFields field, UBool up, UErrorCode& status);
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Time Field Rolling function. Rolls by the given amount on the given
* time field. For example, to roll the current date up by one day, call
@@ -664,6 +670,7 @@ public:
* @deprecated ICU 2.6. Use roll(UCalendarDateFields field, int32_t amount, UErrorCode& status) instead.
*/
virtual void roll(EDateFields field, int32_t amount, UErrorCode& status);
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Time Field Rolling function. Rolls by the given amount on the given
@@ -698,6 +705,7 @@ public:
*/
virtual void roll(UCalendarDateFields field, int32_t amount, UErrorCode& status);
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Return the difference between the given time and the time this
* calendar object is set to. If this calendar is set
@@ -754,6 +762,7 @@ public:
* @deprecated ICU 2.6. Use fieldDifference(UDate when, UCalendarDateFields field, UErrorCode& status).
*/
virtual int32_t fieldDifference(UDate when, EDateFields field, UErrorCode& status);
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Return the difference between the given time and the time this
@@ -1010,6 +1019,7 @@ public:
*/
uint8_t getMinimalDaysInFirstWeek(void) const;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Gets the minimum value for the given time field. e.g., for Gregorian
* DAY_OF_MONTH, 1.
@@ -1019,6 +1029,7 @@ public:
* @deprecated ICU 2.6. Use getMinimum(UCalendarDateFields field) instead.
*/
virtual int32_t getMinimum(EDateFields field) const;
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Gets the minimum value for the given time field. e.g., for Gregorian
@@ -1030,6 +1041,7 @@ public:
*/
virtual int32_t getMinimum(UCalendarDateFields field) const;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Gets the maximum value for the given time field. e.g. for Gregorian DAY_OF_MONTH,
* 31.
@@ -1039,6 +1051,7 @@ public:
* @deprecated ICU 2.6. Use getMaximum(UCalendarDateFields field) instead.
*/
virtual int32_t getMaximum(EDateFields field) const;
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Gets the maximum value for the given time field. e.g. for Gregorian DAY_OF_MONTH,
@@ -1050,6 +1063,7 @@ public:
*/
virtual int32_t getMaximum(UCalendarDateFields field) const;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Gets the highest minimum value for the given field if varies. Otherwise same as
* getMinimum(). For Gregorian, no difference.
@@ -1059,6 +1073,7 @@ public:
* @deprecated ICU 2.6. Use getGreatestMinimum(UCalendarDateFields field) instead.
*/
virtual int32_t getGreatestMinimum(EDateFields field) const;
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Gets the highest minimum value for the given field if varies. Otherwise same as
@@ -1070,6 +1085,7 @@ public:
*/
virtual int32_t getGreatestMinimum(UCalendarDateFields field) const;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Gets the lowest maximum value for the given field if varies. Otherwise same as
* getMaximum(). e.g., for Gregorian DAY_OF_MONTH, 28.
@@ -1079,6 +1095,7 @@ public:
* @deprecated ICU 2.6. Use getLeastMaximum(UCalendarDateFields field) instead.
*/
virtual int32_t getLeastMaximum(EDateFields field) const;
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Gets the lowest maximum value for the given field if varies. Otherwise same as
@@ -1895,11 +1912,13 @@ protected:
*/
int32_t fFields[UCAL_FIELD_COUNT];
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* The flags which tell if a specified time field for the calendar is set.
* @deprecated ICU 2.8 use (fStamp[n]!=kUnset)
*/
UBool fIsSet[UCAL_FIELD_COUNT];
+#endif // U_FORCE_HIDE_DEPRECATED_API
/** Special values of stamp[]
* @stable ICU 2.0
@@ -2281,7 +2300,6 @@ private:
* should only be called if this calendar is not lenient.
* @see #isLenient
* @see #validateField(int, int&)
- * @internal
*/
void validateFields(UErrorCode &status);
@@ -2291,7 +2309,6 @@ private:
* <code>U_ILLEGAL_ARGUMENT_ERROR</code> will be set. Subclasses may
* use this method in their implementation of {@link
* #validateField(int, int&)}.
- * @internal
*/
void validateField(UCalendarDateFields field, int32_t min, int32_t max, UErrorCode& status);
@@ -2529,4 +2546,6 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _CALENDAR
diff --git a/deps/icu-small/source/i18n/unicode/choicfmt.h b/deps/icu-small/source/i18n/unicode/choicfmt.h
index c9f0f1114f..3b2f48cb1f 100644
--- a/deps/icu-small/source/i18n/unicode/choicfmt.h
+++ b/deps/icu-small/source/i18n/unicode/choicfmt.h
@@ -26,13 +26,14 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Choice Format.
*/
#if !UCONFIG_NO_FORMATTING
-#ifndef U_HIDE_DEPRECATED_API
#include "unicode/fieldpos.h"
#include "unicode/format.h"
@@ -40,6 +41,8 @@
#include "unicode/numfmt.h"
#include "unicode/unistr.h"
+#ifndef U_HIDE_DEPRECATED_API
+
U_NAMESPACE_BEGIN
class MessageFormat;
@@ -248,7 +251,7 @@ public:
* @return a copy of this object
* @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments.
*/
- virtual Format* clone(void) const;
+ virtual ChoiceFormat* clone() const;
/**
* Returns true if the given Format objects are semantically equal.
@@ -592,5 +595,7 @@ U_NAMESPACE_END
#endif // U_HIDE_DEPRECATED_API
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // CHOICFMT_H
//eof
diff --git a/deps/icu-small/source/i18n/unicode/coleitr.h b/deps/icu-small/source/i18n/unicode/coleitr.h
index bf0e1d51a4..809d435e50 100644
--- a/deps/icu-small/source/i18n/unicode/coleitr.h
+++ b/deps/icu-small/source/i18n/unicode/coleitr.h
@@ -35,6 +35,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_COLLATION
#include "unicode/unistr.h"
@@ -404,4 +406,6 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_COLLATION */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/i18n/unicode/coll.h b/deps/icu-small/source/i18n/unicode/coll.h
index 653434f54c..f5564c7394 100644
--- a/deps/icu-small/source/i18n/unicode/coll.h
+++ b/deps/icu-small/source/i18n/unicode/coll.h
@@ -54,6 +54,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_COLLATION
#include "unicode/uobject.h"
@@ -204,6 +206,7 @@ public:
// Cannot use #ifndef U_HIDE_DEPRECATED_API for the following, it is
// used by virtual methods that cannot have that conditional.
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* LESS is returned if source string is compared to be less than target
* string in the compare() method.
@@ -220,6 +223,7 @@ public:
EQUAL = UCOL_EQUAL, // 0
GREATER = UCOL_GREATER // 1
};
+#endif // U_FORCE_HIDE_DEPRECATED_API
// Collator public destructor -----------------------------------------
@@ -265,7 +269,7 @@ public:
* @return a copy of this object, owned by the caller
* @stable ICU 2.0
*/
- virtual Collator* clone(void) const = 0;
+ virtual Collator* clone() const = 0;
/**
* Creates the Collator object for the current default locale.
@@ -323,6 +327,7 @@ public:
*/
static Collator* U_EXPORT2 createInstance(const Locale& loc, UErrorCode& err);
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* The comparison function compares the character data stored in two
* different strings. Returns information about whether a string is less
@@ -336,6 +341,7 @@ public:
*/
virtual EComparisonResult compare(const UnicodeString& source,
const UnicodeString& target) const;
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* The comparison function compares the character data stored in two
@@ -353,6 +359,7 @@ public:
const UnicodeString& target,
UErrorCode &status) const = 0;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Does the same thing as compare but limits the comparison to a specified
* length
@@ -368,6 +375,7 @@ public:
virtual EComparisonResult compare(const UnicodeString& source,
const UnicodeString& target,
int32_t length) const;
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Does the same thing as compare but limits the comparison to a specified
@@ -387,6 +395,7 @@ public:
int32_t length,
UErrorCode &status) const = 0;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* The comparison function compares the character data stored in two
* different string arrays. Returns information about whether a string array
@@ -423,6 +432,7 @@ public:
virtual EComparisonResult compare(const char16_t* source, int32_t sourceLength,
const char16_t* target, int32_t targetLength)
const;
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* The comparison function compares the character data stored in two
@@ -527,6 +537,7 @@ public:
*/
virtual int32_t hashCode(void) const = 0;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Gets the locale of the Collator
*
@@ -540,6 +551,7 @@ public:
* in ICU 3.0.
*/
virtual Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const = 0;
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Convenience method for comparing two strings based on the collation rules.
@@ -576,6 +588,7 @@ public:
*/
UBool equals(const UnicodeString& source, const UnicodeString& target) const;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Determines the minimum strength that will be used in comparison or
* transformation.
@@ -607,6 +620,7 @@ public:
* @deprecated ICU 2.6 Use setAttribute(UCOL_STRENGTH...) instead
*/
virtual void setStrength(ECollationStrength newStrength);
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Retrieves the reordering codes for this collator.
@@ -904,6 +918,7 @@ public:
*/
virtual UColReorderCode getMaxVariable() const;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Sets the variable top to the primary weight of the specified string.
*
@@ -951,6 +966,7 @@ public:
* @deprecated ICU 53 Call setMaxVariable() instead.
*/
virtual void setVariableTop(uint32_t varTop, UErrorCode &status) = 0;
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Gets the variable top value of a Collator.
@@ -972,6 +988,7 @@ public:
*/
virtual UnicodeSet *getTailoredSet(UErrorCode &status) const;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Same as clone().
* The base class implementation simply calls clone().
@@ -979,7 +996,8 @@ public:
* @see clone()
* @deprecated ICU 50 no need to have two methods for cloning
*/
- virtual Collator* safeClone(void) const;
+ virtual Collator* safeClone() const;
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Get the sort key as an array of bytes from a UnicodeString.
@@ -1271,4 +1289,6 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_COLLATION */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/i18n/unicode/compactdecimalformat.h b/deps/icu-small/source/i18n/unicode/compactdecimalformat.h
index 9c1e9183f4..9c1e200996 100644
--- a/deps/icu-small/source/i18n/unicode/compactdecimalformat.h
+++ b/deps/icu-small/source/i18n/unicode/compactdecimalformat.h
@@ -14,6 +14,9 @@
#define __COMPACT_DECIMAL_FORMAT_H__
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Compatibility APIs for compact decimal number formatting.
@@ -102,7 +105,7 @@ public:
* @return a polymorphic copy of this CompactDecimalFormat.
* @stable ICU 51
*/
- Format* clone() const U_OVERRIDE;
+ CompactDecimalFormat* clone() const U_OVERRIDE;
using DecimalFormat::format;
@@ -187,5 +190,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __COMPACT_DECIMAL_FORMAT_H__
//eof
diff --git a/deps/icu-small/source/i18n/unicode/curramt.h b/deps/icu-small/source/i18n/unicode/curramt.h
index 03ec856e3b..65e6619db3 100644
--- a/deps/icu-small/source/i18n/unicode/curramt.h
+++ b/deps/icu-small/source/i18n/unicode/curramt.h
@@ -15,6 +15,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
#include "unicode/measure.h"
@@ -79,7 +81,7 @@ class U_I18N_API CurrencyAmount: public Measure {
* have the same class as returned by getDynamicClassID().
* @stable ICU 3.0
*/
- virtual UObject* clone() const;
+ virtual CurrencyAmount* clone() const;
/**
* Destructor
@@ -129,4 +131,7 @@ inline const char16_t* CurrencyAmount::getISOCurrency() const {
U_NAMESPACE_END
#endif // !UCONFIG_NO_FORMATTING
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __CURRENCYAMOUNT_H__
diff --git a/deps/icu-small/source/i18n/unicode/currpinf.h b/deps/icu-small/source/i18n/unicode/currpinf.h
index 80b0462513..1b93be0831 100644
--- a/deps/icu-small/source/i18n/unicode/currpinf.h
+++ b/deps/icu-small/source/i18n/unicode/currpinf.h
@@ -11,6 +11,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Currency Plural Information used by Decimal Format
@@ -266,5 +268,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _CURRPINFO
//eof
diff --git a/deps/icu-small/source/i18n/unicode/currunit.h b/deps/icu-small/source/i18n/unicode/currunit.h
index 63739c37fd..0446154e32 100644
--- a/deps/icu-small/source/i18n/unicode/currunit.h
+++ b/deps/icu-small/source/i18n/unicode/currunit.h
@@ -15,6 +15,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
#include "unicode/measunit.h"
@@ -94,7 +96,7 @@ class U_I18N_API CurrencyUnit: public MeasureUnit {
* have the same class as returned by getDynamicClassID().
* @stable ICU 3.0
*/
- virtual UObject* clone() const;
+ virtual CurrencyUnit* clone() const;
/**
* Destructor
@@ -140,4 +142,7 @@ inline const char16_t* CurrencyUnit::getISOCurrency() const {
U_NAMESPACE_END
#endif // !UCONFIG_NO_FORMATTING
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __CURRENCYUNIT_H__
diff --git a/deps/icu-small/source/i18n/unicode/datefmt.h b/deps/icu-small/source/i18n/unicode/datefmt.h
index 13c63d9376..21217e567a 100644
--- a/deps/icu-small/source/i18n/unicode/datefmt.h
+++ b/deps/icu-small/source/i18n/unicode/datefmt.h
@@ -23,6 +23,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
#include "unicode/udat.h"
@@ -222,6 +224,14 @@ public:
virtual ~DateFormat();
/**
+ * Clones this object polymorphically.
+ * The caller owns the result and should delete it when done.
+ * @return clone, or nullptr if an error occurred
+ * @stable ICU 2.0
+ */
+ virtual DateFormat* clone() const = 0;
+
+ /**
* Equality operator. Returns true if the two formats have the same behavior.
* @stable ICU 2.0
*/
@@ -953,5 +963,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _DATEFMT
//eof
diff --git a/deps/icu-small/source/i18n/unicode/dcfmtsym.h b/deps/icu-small/source/i18n/unicode/dcfmtsym.h
index 55e3d8a6b3..e1e0ab6b08 100644
--- a/deps/icu-small/source/i18n/unicode/dcfmtsym.h
+++ b/deps/icu-small/source/i18n/unicode/dcfmtsym.h
@@ -28,10 +28,12 @@
#define DCFMTSYM_H
#include "unicode/utypes.h"
-#include "unicode/uchar.h"
+
+#if U_SHOW_CPLUSPLUS_API
#if !UCONFIG_NO_FORMATTING
+#include "unicode/uchar.h"
#include "unicode/uobject.h"
#include "unicode/locid.h"
#include "unicode/numsys.h"
@@ -455,13 +457,11 @@ private:
* to non-resource bundle strings,
* then regular UnicodeString copies must be used instead of fastCopyFrom().
*
- * @internal
*/
UnicodeString fSymbols[kFormatSymbolCount];
/**
* Non-symbol variable for getConstSymbol(). Always empty.
- * @internal
*/
UnicodeString fNoSymbol;
@@ -582,5 +582,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _DCFMTSYM
//eof
diff --git a/deps/icu-small/source/i18n/unicode/decimfmt.h b/deps/icu-small/source/i18n/unicode/decimfmt.h
index 097a38fb88..e539b9af23 100644
--- a/deps/icu-small/source/i18n/unicode/decimfmt.h
+++ b/deps/icu-small/source/i18n/unicode/decimfmt.h
@@ -28,6 +28,9 @@
#define DECIMFMT_H
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Compatibility APIs for decimal formatting.
@@ -896,7 +899,7 @@ class U_I18N_API DecimalFormat : public NumberFormat {
* @return a polymorphic copy of this DecimalFormat.
* @stable ICU 2.0
*/
- Format* clone(void) const U_OVERRIDE;
+ DecimalFormat* clone() const U_OVERRIDE;
/**
* Return true if the given Format objects are semantically equal.
@@ -1331,7 +1334,6 @@ class U_I18N_API DecimalFormat : public NumberFormat {
*/
virtual void setMultiplier(int32_t newValue);
-#ifndef U_HIDE_DRAFT_API
/**
* Gets the power of ten by which number should be multiplied before formatting, which
* can be combined with setMultiplier() to multiply by any arbitrary decimal value.
@@ -1342,7 +1344,7 @@ class U_I18N_API DecimalFormat : public NumberFormat {
* This method is analogous to UNUM_SCALE in getAttribute.
*
* @return the current value of the power-of-ten multiplier.
- * @draft ICU 62
+ * @stable ICU 62
*/
int32_t getMultiplierScale(void) const;
@@ -1363,10 +1365,9 @@ class U_I18N_API DecimalFormat : public NumberFormat {
* This method is analogous to UNUM_SCALE in setAttribute.
*
* @param newValue the new value of the power-of-ten multiplier.
- * @draft ICU 62
+ * @stable ICU 62
*/
void setMultiplierScale(int32_t newValue);
-#endif /* U_HIDE_DRAFT_API */
/**
* Get the rounding increment.
@@ -2020,12 +2021,14 @@ class U_I18N_API DecimalFormat : public NumberFormat {
*/
void setCurrency(const char16_t* theCurrency, UErrorCode& ec) U_OVERRIDE;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Sets the currency used to display currency amounts. See
* setCurrency(const char16_t*, UErrorCode&).
* @deprecated ICU 3.0. Use setCurrency(const char16_t*, UErrorCode&).
*/
virtual void setCurrency(const char16_t* theCurrency);
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Sets the `Currency Usage` object used to display currency.
@@ -2113,22 +2116,6 @@ class U_I18N_API DecimalFormat : public NumberFormat {
const number::LocalizedNumberFormatter* toNumberFormatter(UErrorCode& status) const;
#endif /* U_HIDE_DRAFT_API */
-#ifndef U_HIDE_DEPRECATED_API
- /**
- * Deprecated: Like {@link #toNumberFormatter(UErrorCode&) const},
- * but does not take an error code.
- *
- * The new signature should be used in case an error occurs while returning the
- * LocalizedNumberFormatter.
- *
- * This old signature will be removed in ICU 65.
- *
- * @return A reference to an internal object.
- * @deprecated ICU 64
- */
- const number::LocalizedNumberFormatter& toNumberFormatter() const;
-#endif /* U_HIDE_DEPRECATED_API */
-
/**
* Return the class ID for this class. This is useful only for
* comparing to a return value from getDynamicClassID(). For example:
@@ -2216,5 +2203,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _DECIMFMT
//eof
diff --git a/deps/icu-small/source/i18n/unicode/dtfmtsym.h b/deps/icu-small/source/i18n/unicode/dtfmtsym.h
index ed7c189846..f9ec88272b 100644
--- a/deps/icu-small/source/i18n/unicode/dtfmtsym.h
+++ b/deps/icu-small/source/i18n/unicode/dtfmtsym.h
@@ -22,6 +22,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
#include "unicode/calendar.h"
@@ -1011,5 +1013,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _DTFMTSYM
//eof
diff --git a/deps/icu-small/source/i18n/unicode/dtitvfmt.h b/deps/icu-small/source/i18n/unicode/dtitvfmt.h
index 42d77d041f..23fc02e2a7 100644
--- a/deps/icu-small/source/i18n/unicode/dtitvfmt.h
+++ b/deps/icu-small/source/i18n/unicode/dtitvfmt.h
@@ -16,6 +16,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Format and parse date interval in a language-independent manner.
@@ -432,7 +434,7 @@ public:
* @return A copy of the object.
* @stable ICU 4.0
*/
- virtual Format* clone(void) const;
+ virtual DateIntervalFormat* clone() const;
/**
* Return true if the given Format objects are semantically equal. Objects
@@ -1151,5 +1153,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _DTITVFMT_H__
//eof
diff --git a/deps/icu-small/source/i18n/unicode/dtitvinf.h b/deps/icu-small/source/i18n/unicode/dtitvinf.h
index 65f568c070..3c666231ab 100644
--- a/deps/icu-small/source/i18n/unicode/dtitvinf.h
+++ b/deps/icu-small/source/i18n/unicode/dtitvinf.h
@@ -16,6 +16,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Date/Time interval patterns for formatting date/time interval
@@ -195,7 +197,7 @@ public:
* @return a copy of the object
* @stable ICU 4.0
*/
- virtual DateIntervalInfo* clone(void) const;
+ virtual DateIntervalInfo* clone() const;
/**
* Destructor.
@@ -515,4 +517,6 @@ U_NAMESPACE_END
#endif
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/i18n/unicode/dtptngen.h b/deps/icu-small/source/i18n/unicode/dtptngen.h
index e50c01b4e3..a71938b31c 100644
--- a/deps/icu-small/source/i18n/unicode/dtptngen.h
+++ b/deps/icu-small/source/i18n/unicode/dtptngen.h
@@ -14,6 +14,10 @@
#ifndef __DTPTNGEN_H__
#define __DTPTNGEN_H__
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/datefmt.h"
#include "unicode/locid.h"
#include "unicode/udat.h"
@@ -279,7 +283,7 @@ public:
*
* @param field The desired UDateTimePatternField, such as UDATPG_ERA_FIELD.
* @param width The desired UDateTimePGDisplayWidth, such as UDATPG_ABBREVIATED.
- * @return. The display name for field
+ * @return The display name for field
* @stable ICU 61
*/
UnicodeString getFieldDisplayName(UDateTimePatternField field, UDateTimePGDisplayWidth width) const;
@@ -561,12 +565,10 @@ private:
void setDateTimeFromCalendar(const Locale& locale, UErrorCode& status);
void setDecimalSymbols(const Locale& locale, UErrorCode& status);
UDateTimePatternField getAppendFormatNumber(const char* field) const;
-#ifndef U_HIDE_DRAFT_API
- // The following three have to be U_HIDE_DRAFT_API (though private) because UDateTimePGDisplayWidth is
+ // Note for the next 3: UDateTimePGDisplayWidth is now stable ICU 61
UDateTimePatternField getFieldAndWidthIndices(const char* key, UDateTimePGDisplayWidth* widthP) const;
void setFieldDisplayName(UDateTimePatternField field, UDateTimePGDisplayWidth width, const UnicodeString& value);
UnicodeString& getMutableFieldDisplayName(UDateTimePatternField field, UDateTimePGDisplayWidth width);
-#endif // U_HIDE_DRAFT_API
void getAppendName(UDateTimePatternField field, UnicodeString& value);
UnicodeString mapSkeletonMetacharacters(const UnicodeString& patternForm, int32_t* flags, UErrorCode& status);
const UnicodeString* getBestRaw(DateTimeMatcher& source, int32_t includeMask, DistanceInfo* missingFields, UErrorCode& status, const PtnSkeleton** specifiedSkeletonPtr = 0);
@@ -587,4 +589,6 @@ private:
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/i18n/unicode/dtrule.h b/deps/icu-small/source/i18n/unicode/dtrule.h
index 24dfc69de1..dba28bf2dc 100644
--- a/deps/icu-small/source/i18n/unicode/dtrule.h
+++ b/deps/icu-small/source/i18n/unicode/dtrule.h
@@ -11,6 +11,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Rule for specifying date and time in an year
@@ -126,7 +128,7 @@ public:
* @return A copy of the object.
* @stable ICU 3.8
*/
- DateTimeRule* clone(void) const;
+ DateTimeRule* clone() const;
/**
* Assignment operator.
@@ -248,5 +250,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // DTRULE_H
//eof
diff --git a/deps/icu-small/source/i18n/unicode/fieldpos.h b/deps/icu-small/source/i18n/unicode/fieldpos.h
index 78561a4de7..c9849d67a3 100644
--- a/deps/icu-small/source/i18n/unicode/fieldpos.h
+++ b/deps/icu-small/source/i18n/unicode/fieldpos.h
@@ -26,6 +26,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: FieldPosition identifies the fields in a formatted output.
@@ -290,5 +292,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _FIELDPOS
//eof
diff --git a/deps/icu-small/source/i18n/unicode/fmtable.h b/deps/icu-small/source/i18n/unicode/fmtable.h
index a06c23dc3b..7bec4f6906 100644
--- a/deps/icu-small/source/i18n/unicode/fmtable.h
+++ b/deps/icu-small/source/i18n/unicode/fmtable.h
@@ -19,6 +19,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Formattable is a thin wrapper for primitive types used for formatting and parsing
@@ -751,5 +753,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif //_FMTABLE
//eof
diff --git a/deps/icu-small/source/i18n/unicode/format.h b/deps/icu-small/source/i18n/unicode/format.h
index e64cc1c6eb..28a09159bd 100644
--- a/deps/icu-small/source/i18n/unicode/format.h
+++ b/deps/icu-small/source/i18n/unicode/format.h
@@ -26,6 +26,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Base class for all formats.
@@ -303,5 +305,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _FORMAT
//eof
diff --git a/deps/icu-small/source/i18n/unicode/formattedvalue.h b/deps/icu-small/source/i18n/unicode/formattedvalue.h
index 2e24c8d99e..1b130bbdd9 100644
--- a/deps/icu-small/source/i18n/unicode/formattedvalue.h
+++ b/deps/icu-small/source/i18n/unicode/formattedvalue.h
@@ -5,8 +5,10 @@
#define __FORMATTEDVALUE_H__
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
-#ifndef U_HIDE_DRAFT_API
#include "unicode/appendable.h"
#include "unicode/fpositer.h"
@@ -24,6 +26,10 @@ U_NAMESPACE_BEGIN
*/
+// The following cannot have #ifndef U_HIDE_DRAFT_API because
+// class FormattedValue depends on it, and FormattedValue cannot be
+// hidden becauseclass FormattedNumber (stable ICU 60) depends on it.
+#ifndef U_FORCE_HIDE_DRAFT_API
/**
* Represents a span of a string containing a given field.
*
@@ -52,6 +58,7 @@ class U_I18N_API ConstrainedFieldPosition : public UMemory {
/** @draft ICU 64 */
~ConstrainedFieldPosition();
+#ifndef U_HIDE_DRAFT_API
/**
* Resets this ConstrainedFieldPosition to its initial state, as if it were newly created:
*
@@ -221,17 +228,23 @@ class U_I18N_API ConstrainedFieldPosition : public UMemory {
int32_t field,
int32_t start,
int32_t limit);
+#endif /* U_HIDE_DRAFT_API */
private:
int64_t fContext = 0LL;
int32_t fField = 0;
int32_t fStart = 0;
int32_t fLimit = 0;
+#ifndef U_HIDE_DRAFT_API
int32_t fCategory = UFIELD_CATEGORY_UNDEFINED;
+#else /* U_HIDE_DRAFT_API */
+ int32_t fCategory = 0;
+#endif /* U_HIDE_DRAFT_API */
int8_t fConstraint = 0;
};
-
+// The following cannot have #ifndef U_HIDE_DRAFT_API because
+// class FormattedNumber (stable ICU 60) depends on it.
/**
* An abstract formatted value: a string with associated field attributes.
* Many formatters format to classes implementing FormattedValue.
@@ -308,10 +321,12 @@ class U_I18N_API FormattedValue /* not : public UObject because this is an inter
*/
virtual UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const = 0;
};
-
+#endif // U_FORCE_HIDE_DRAFT_API
U_NAMESPACE_END
-#endif /* U_HIDE_DRAFT_API */
#endif /* #if !UCONFIG_NO_FORMATTING */
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __FORMATTEDVALUE_H__
diff --git a/deps/icu-small/source/i18n/unicode/fpositer.h b/deps/icu-small/source/i18n/unicode/fpositer.h
index 81091f0ffa..ba2a838315 100644
--- a/deps/icu-small/source/i18n/unicode/fpositer.h
+++ b/deps/icu-small/source/i18n/unicode/fpositer.h
@@ -19,6 +19,9 @@
#define FPOSITER_H
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/uobject.h"
/**
@@ -116,4 +119,6 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // FPOSITER_H
diff --git a/deps/icu-small/source/i18n/unicode/gender.h b/deps/icu-small/source/i18n/unicode/gender.h
index b7c31cb554..5ae111a3aa 100644
--- a/deps/icu-small/source/i18n/unicode/gender.h
+++ b/deps/icu-small/source/i18n/unicode/gender.h
@@ -25,6 +25,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
#include "unicode/locid.h"
@@ -114,5 +116,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _GENDER
//eof
diff --git a/deps/icu-small/source/i18n/unicode/gregocal.h b/deps/icu-small/source/i18n/unicode/gregocal.h
index 1d881e0be7..236bd003c1 100644
--- a/deps/icu-small/source/i18n/unicode/gregocal.h
+++ b/deps/icu-small/source/i18n/unicode/gregocal.h
@@ -28,6 +28,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
#include "unicode/calendar.h"
@@ -301,7 +303,7 @@ public:
* @return return a polymorphic copy of this calendar.
* @stable ICU 2.0
*/
- virtual Calendar* clone(void) const;
+ virtual GregorianCalendar* clone() const;
/**
* Sets the GregorianCalendar change date. This is the point when the switch from
@@ -350,6 +352,7 @@ public:
*/
virtual UBool isEquivalentTo(const Calendar& other) const;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* (Overrides Calendar) Rolls up or down by the given amount in the specified field.
* For more information, see the documentation for Calendar::roll().
@@ -362,6 +365,7 @@ public:
* @deprecated ICU 2.6. Use roll(UCalendarDateFields field, int32_t amount, UErrorCode& status) instead.
*/
virtual void roll(EDateFields field, int32_t amount, UErrorCode& status);
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* (Overrides Calendar) Rolls up or down by the given amount in the specified field.
@@ -774,5 +778,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _GREGOCAL
//eof
diff --git a/deps/icu-small/source/i18n/unicode/listformatter.h b/deps/icu-small/source/i18n/unicode/listformatter.h
index 9ce8ec8617..88fc46cf37 100644
--- a/deps/icu-small/source/i18n/unicode/listformatter.h
+++ b/deps/icu-small/source/i18n/unicode/listformatter.h
@@ -21,6 +21,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/unistr.h"
#include "unicode/locid.h"
#include "unicode/formattedvalue.h"
@@ -237,7 +239,7 @@ class U_I18N_API ListFormatter : public UObject{
UnicodeString& format(const UnicodeString items[], int32_t n_items,
UnicodeString & appendTo, FieldPositionIterator* posIter,
UErrorCode& errorCode) const;
-#endif /* U_HIDE_DRAFT_API */
+#endif // U_HIDE_DRAFT_API
#if !UCONFIG_NO_FORMATTING
#ifndef U_HIDE_DRAFT_API
@@ -298,4 +300,6 @@ class U_I18N_API ListFormatter : public UObject{
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __LISTFORMATTER_H__
diff --git a/deps/icu-small/source/i18n/unicode/measfmt.h b/deps/icu-small/source/i18n/unicode/measfmt.h
index d518665e14..8f73de87fa 100644
--- a/deps/icu-small/source/i18n/unicode/measfmt.h
+++ b/deps/icu-small/source/i18n/unicode/measfmt.h
@@ -15,6 +15,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
#include "unicode/format.h"
@@ -151,7 +153,7 @@ class U_I18N_API MeasureFormat : public Format {
* Clones this object polymorphically.
* @stable ICU 53
*/
- virtual Format *clone() const;
+ virtual MeasureFormat *clone() const;
/**
* Formats object to produce a string.
@@ -163,6 +165,7 @@ class U_I18N_API MeasureFormat : public Format {
FieldPosition &pos,
UErrorCode &status) const;
+#ifndef U_FORCE_HIDE_DRAFT_API
/**
* Parse a string to produce an object. This implementation sets
* status to U_UNSUPPORTED_ERROR.
@@ -173,6 +176,7 @@ class U_I18N_API MeasureFormat : public Format {
const UnicodeString &source,
Formattable &reslt,
ParsePosition &pos) const;
+#endif // U_FORCE_HIDE_DRAFT_API
/**
* Formats measure objects to produce a string. An example of such a
@@ -382,17 +386,12 @@ class U_I18N_API MeasureFormat : public Format {
int32_t bitMap, // 1=hour set, 2=minute set, 4=second set
UnicodeString &appendTo,
UErrorCode &status) const;
-
- UnicodeString &formatNumeric(
- UDate date,
- const DateFormat &dateFmt,
- UDateFormatField smallestField,
- const Formattable &smallestAmount,
- UnicodeString &appendTo,
- UErrorCode &status) const;
};
U_NAMESPACE_END
#endif // #if !UCONFIG_NO_FORMATTING
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // #ifndef MEASUREFORMAT_H
diff --git a/deps/icu-small/source/i18n/unicode/measunit.h b/deps/icu-small/source/i18n/unicode/measunit.h
index d8e3c73956..08f337cb5b 100644
--- a/deps/icu-small/source/i18n/unicode/measunit.h
+++ b/deps/icu-small/source/i18n/unicode/measunit.h
@@ -15,6 +15,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
#include "unicode/unistr.h"
@@ -62,7 +64,7 @@ class U_I18N_API MeasureUnit: public UObject {
* have the same class as returned by getDynamicClassID().
* @stable ICU 3.0
*/
- virtual UObject* clone() const;
+ virtual MeasureUnit* clone() const;
/**
* Destructor
@@ -604,16 +606,14 @@ class U_I18N_API MeasureUnit: public UObject {
static MeasureUnit getPartPerMillion();
#endif /* U_HIDE_DRAFT_API */
-#ifndef U_HIDE_DRAFT_API
/**
* Returns by pointer, unit of concentr: percent.
* Caller owns returned value and must free it.
* Also see {@link #getPercent()}.
* @param status ICU error code.
- * @draft ICU 63
+ * @stable ICU 63
*/
static MeasureUnit *createPercent(UErrorCode &status);
-#endif /* U_HIDE_DRAFT_API */
#ifndef U_HIDE_DRAFT_API
/**
@@ -624,16 +624,14 @@ class U_I18N_API MeasureUnit: public UObject {
static MeasureUnit getPercent();
#endif /* U_HIDE_DRAFT_API */
-#ifndef U_HIDE_DRAFT_API
/**
* Returns by pointer, unit of concentr: permille.
* Caller owns returned value and must free it.
* Also see {@link #getPermille()}.
* @param status ICU error code.
- * @draft ICU 63
+ * @stable ICU 63
*/
static MeasureUnit *createPermille(UErrorCode &status);
-#endif /* U_HIDE_DRAFT_API */
#ifndef U_HIDE_DRAFT_API
/**
@@ -878,16 +876,14 @@ class U_I18N_API MeasureUnit: public UObject {
static MeasureUnit getMegabyte();
#endif /* U_HIDE_DRAFT_API */
-#ifndef U_HIDE_DRAFT_API
/**
* Returns by pointer, unit of digital: petabyte.
* Caller owns returned value and must free it.
* Also see {@link #getPetabyte()}.
* @param status ICU error code.
- * @draft ICU 63
+ * @stable ICU 63
*/
static MeasureUnit *createPetabyte(UErrorCode &status);
-#endif /* U_HIDE_DRAFT_API */
#ifndef U_HIDE_DRAFT_API
/**
@@ -979,9 +975,7 @@ class U_I18N_API MeasureUnit: public UObject {
* @draft ICU 64
*/
static MeasureUnit *createDayPerson(UErrorCode &status);
-#endif /* U_HIDE_DRAFT_API */
-#ifndef U_HIDE_DRAFT_API
/**
* Returns by value, unit of duration: day-person.
* Also see {@link #createDayPerson()}.
@@ -990,6 +984,24 @@ class U_I18N_API MeasureUnit: public UObject {
static MeasureUnit getDayPerson();
#endif /* U_HIDE_DRAFT_API */
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Returns by pointer, unit of duration: decade.
+ * Caller owns returned value and must free it.
+ * Also see {@link #getDecade()}.
+ * @param status ICU error code.
+ * @draft ICU 65
+ */
+ static MeasureUnit *createDecade(UErrorCode &status);
+
+ /**
+ * Returns by value, unit of duration: decade.
+ * Also see {@link #createDecade()}.
+ * @draft ICU 65
+ */
+ static MeasureUnit getDecade();
+#endif /* U_HIDE_DRAFT_API */
+
/**
* Returns by pointer, unit of duration: hour.
* Caller owns returned value and must free it.
@@ -1089,9 +1101,7 @@ class U_I18N_API MeasureUnit: public UObject {
* @draft ICU 64
*/
static MeasureUnit *createMonthPerson(UErrorCode &status);
-#endif /* U_HIDE_DRAFT_API */
-#ifndef U_HIDE_DRAFT_API
/**
* Returns by value, unit of duration: month-person.
* Also see {@link #createMonthPerson()}.
@@ -1163,9 +1173,7 @@ class U_I18N_API MeasureUnit: public UObject {
* @draft ICU 64
*/
static MeasureUnit *createWeekPerson(UErrorCode &status);
-#endif /* U_HIDE_DRAFT_API */
-#ifndef U_HIDE_DRAFT_API
/**
* Returns by value, unit of duration: week-person.
* Also see {@link #createWeekPerson()}.
@@ -1201,9 +1209,7 @@ class U_I18N_API MeasureUnit: public UObject {
* @draft ICU 64
*/
static MeasureUnit *createYearPerson(UErrorCode &status);
-#endif /* U_HIDE_DRAFT_API */
-#ifndef U_HIDE_DRAFT_API
/**
* Returns by value, unit of duration: year-person.
* Also see {@link #createYearPerson()}.
@@ -1430,6 +1436,24 @@ class U_I18N_API MeasureUnit: public UObject {
#ifndef U_HIDE_DRAFT_API
/**
+ * Returns by pointer, unit of energy: therm-us.
+ * Caller owns returned value and must free it.
+ * Also see {@link #getThermUs()}.
+ * @param status ICU error code.
+ * @draft ICU 65
+ */
+ static MeasureUnit *createThermUs(UErrorCode &status);
+
+ /**
+ * Returns by value, unit of energy: therm-us.
+ * Also see {@link #createThermUs()}.
+ * @draft ICU 65
+ */
+ static MeasureUnit getThermUs();
+#endif /* U_HIDE_DRAFT_API */
+
+#ifndef U_HIDE_DRAFT_API
+ /**
* Returns by pointer, unit of force: newton.
* Caller owns returned value and must free it.
* Also see {@link #getNewton()}.
@@ -1536,6 +1560,132 @@ class U_I18N_API MeasureUnit: public UObject {
static MeasureUnit getMegahertz();
#endif /* U_HIDE_DRAFT_API */
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Returns by pointer, unit of graphics: dot-per-centimeter.
+ * Caller owns returned value and must free it.
+ * Also see {@link #getDotPerCentimeter()}.
+ * @param status ICU error code.
+ * @draft ICU 65
+ */
+ static MeasureUnit *createDotPerCentimeter(UErrorCode &status);
+
+ /**
+ * Returns by value, unit of graphics: dot-per-centimeter.
+ * Also see {@link #createDotPerCentimeter()}.
+ * @draft ICU 65
+ */
+ static MeasureUnit getDotPerCentimeter();
+#endif /* U_HIDE_DRAFT_API */
+
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Returns by pointer, unit of graphics: dot-per-inch.
+ * Caller owns returned value and must free it.
+ * Also see {@link #getDotPerInch()}.
+ * @param status ICU error code.
+ * @draft ICU 65
+ */
+ static MeasureUnit *createDotPerInch(UErrorCode &status);
+
+ /**
+ * Returns by value, unit of graphics: dot-per-inch.
+ * Also see {@link #createDotPerInch()}.
+ * @draft ICU 65
+ */
+ static MeasureUnit getDotPerInch();
+#endif /* U_HIDE_DRAFT_API */
+
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Returns by pointer, unit of graphics: em.
+ * Caller owns returned value and must free it.
+ * Also see {@link #getEm()}.
+ * @param status ICU error code.
+ * @draft ICU 65
+ */
+ static MeasureUnit *createEm(UErrorCode &status);
+
+ /**
+ * Returns by value, unit of graphics: em.
+ * Also see {@link #createEm()}.
+ * @draft ICU 65
+ */
+ static MeasureUnit getEm();
+#endif /* U_HIDE_DRAFT_API */
+
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Returns by pointer, unit of graphics: megapixel.
+ * Caller owns returned value and must free it.
+ * Also see {@link #getMegapixel()}.
+ * @param status ICU error code.
+ * @draft ICU 65
+ */
+ static MeasureUnit *createMegapixel(UErrorCode &status);
+
+ /**
+ * Returns by value, unit of graphics: megapixel.
+ * Also see {@link #createMegapixel()}.
+ * @draft ICU 65
+ */
+ static MeasureUnit getMegapixel();
+#endif /* U_HIDE_DRAFT_API */
+
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Returns by pointer, unit of graphics: pixel.
+ * Caller owns returned value and must free it.
+ * Also see {@link #getPixel()}.
+ * @param status ICU error code.
+ * @draft ICU 65
+ */
+ static MeasureUnit *createPixel(UErrorCode &status);
+
+ /**
+ * Returns by value, unit of graphics: pixel.
+ * Also see {@link #createPixel()}.
+ * @draft ICU 65
+ */
+ static MeasureUnit getPixel();
+#endif /* U_HIDE_DRAFT_API */
+
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Returns by pointer, unit of graphics: pixel-per-centimeter.
+ * Caller owns returned value and must free it.
+ * Also see {@link #getPixelPerCentimeter()}.
+ * @param status ICU error code.
+ * @draft ICU 65
+ */
+ static MeasureUnit *createPixelPerCentimeter(UErrorCode &status);
+
+ /**
+ * Returns by value, unit of graphics: pixel-per-centimeter.
+ * Also see {@link #createPixelPerCentimeter()}.
+ * @draft ICU 65
+ */
+ static MeasureUnit getPixelPerCentimeter();
+#endif /* U_HIDE_DRAFT_API */
+
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Returns by pointer, unit of graphics: pixel-per-inch.
+ * Caller owns returned value and must free it.
+ * Also see {@link #getPixelPerInch()}.
+ * @param status ICU error code.
+ * @draft ICU 65
+ */
+ static MeasureUnit *createPixelPerInch(UErrorCode &status);
+
+ /**
+ * Returns by value, unit of graphics: pixel-per-inch.
+ * Also see {@link #createPixelPerInch()}.
+ * @draft ICU 65
+ */
+ static MeasureUnit getPixelPerInch();
+#endif /* U_HIDE_DRAFT_API */
+
/**
* Returns by pointer, unit of length: astronomical-unit.
* Caller owns returned value and must free it.
@@ -2310,16 +2460,14 @@ class U_I18N_API MeasureUnit: public UObject {
static MeasureUnit getWatt();
#endif /* U_HIDE_DRAFT_API */
-#ifndef U_HIDE_DRAFT_API
/**
* Returns by pointer, unit of pressure: atmosphere.
* Caller owns returned value and must free it.
* Also see {@link #getAtmosphere()}.
* @param status ICU error code.
- * @draft ICU 63
+ * @stable ICU 63
*/
static MeasureUnit *createAtmosphere(UErrorCode &status);
-#endif /* U_HIDE_DRAFT_API */
#ifndef U_HIDE_DRAFT_API
/**
@@ -2330,6 +2478,24 @@ class U_I18N_API MeasureUnit: public UObject {
static MeasureUnit getAtmosphere();
#endif /* U_HIDE_DRAFT_API */
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Returns by pointer, unit of pressure: bar.
+ * Caller owns returned value and must free it.
+ * Also see {@link #getBar()}.
+ * @param status ICU error code.
+ * @draft ICU 65
+ */
+ static MeasureUnit *createBar(UErrorCode &status);
+
+ /**
+ * Returns by value, unit of pressure: bar.
+ * Also see {@link #createBar()}.
+ * @draft ICU 65
+ */
+ static MeasureUnit getBar();
+#endif /* U_HIDE_DRAFT_API */
+
/**
* Returns by pointer, unit of pressure: hectopascal.
* Caller owns returned value and must free it.
@@ -2438,6 +2604,24 @@ class U_I18N_API MeasureUnit: public UObject {
static MeasureUnit getMillimeterOfMercury();
#endif /* U_HIDE_DRAFT_API */
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Returns by pointer, unit of pressure: pascal.
+ * Caller owns returned value and must free it.
+ * Also see {@link #getPascal()}.
+ * @param status ICU error code.
+ * @draft ICU 65
+ */
+ static MeasureUnit *createPascal(UErrorCode &status);
+
+ /**
+ * Returns by value, unit of pressure: pascal.
+ * Also see {@link #createPascal()}.
+ * @draft ICU 65
+ */
+ static MeasureUnit getPascal();
+#endif /* U_HIDE_DRAFT_API */
+
/**
* Returns by pointer, unit of pressure: pound-per-square-inch.
* Caller owns returned value and must free it.
@@ -3164,4 +3348,7 @@ private:
U_NAMESPACE_END
#endif // !UNCONFIG_NO_FORMATTING
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __MEASUREUNIT_H__
diff --git a/deps/icu-small/source/i18n/unicode/measure.h b/deps/icu-small/source/i18n/unicode/measure.h
index 71438d5c85..a15173d739 100644
--- a/deps/icu-small/source/i18n/unicode/measure.h
+++ b/deps/icu-small/source/i18n/unicode/measure.h
@@ -15,6 +15,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: MeasureUnit object.
@@ -72,7 +74,7 @@ class U_I18N_API Measure: public UObject {
* have the same class as returned by getDynamicClassID().
* @stable ICU 3.0
*/
- virtual UObject* clone() const;
+ virtual Measure* clone() const;
/**
* Destructor
@@ -158,4 +160,7 @@ inline const MeasureUnit& Measure::getUnit() const {
U_NAMESPACE_END
#endif // !UCONFIG_NO_FORMATTING
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __MEASURE_H__
diff --git a/deps/icu-small/source/i18n/unicode/msgfmt.h b/deps/icu-small/source/i18n/unicode/msgfmt.h
index 8e1bf9b45f..99b0eaeec1 100644
--- a/deps/icu-small/source/i18n/unicode/msgfmt.h
+++ b/deps/icu-small/source/i18n/unicode/msgfmt.h
@@ -21,6 +21,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Formats messages in a language-neutral way.
@@ -184,7 +186,7 @@ class NumberFormat;
* <td><i>argSkeletonText</i>
* <td><code>NumberFormatter::forSkeleton(argSkeletonText, status).locale(getLocale()).toFormat(status)</code>
* <tr>
- * <td rowspan=6><code>date</code>
+ * <td rowspan=7><code>date</code>
* <td><i>(none)</i>
* <td><code>DateFormat.createDateInstance(kDefault, getLocale(), status)</code>
* <tr>
@@ -418,7 +420,7 @@ public:
* result and should delete it when done.
* @stable ICU 2.0
*/
- virtual Format* clone(void) const;
+ virtual MessageFormat* clone() const;
/**
* Returns true if the given Format objects are semantically equal.
@@ -1087,7 +1089,7 @@ private:
class U_I18N_API DummyFormat : public Format {
public:
virtual UBool operator==(const Format&) const;
- virtual Format* clone() const;
+ virtual DummyFormat* clone() const;
virtual UnicodeString& format(const Formattable& obj,
UnicodeString& appendTo,
UErrorCode& status) const;
@@ -1111,5 +1113,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _MSGFMT
//eof
diff --git a/deps/icu-small/source/i18n/unicode/nounit.h b/deps/icu-small/source/i18n/unicode/nounit.h
index 879849b16b..61b5c16ee3 100644
--- a/deps/icu-small/source/i18n/unicode/nounit.h
+++ b/deps/icu-small/source/i18n/unicode/nounit.h
@@ -12,11 +12,14 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
-#ifndef U_HIDE_DRAFT_API
#include "unicode/measunit.h"
+#ifndef U_HIDE_DRAFT_API
+
/**
* \file
* \brief C++ API: units for percent and permille
@@ -72,7 +75,7 @@ public:
* have the same class as returned by getDynamicClassID().
* @draft ICU 60
*/
- virtual UObject* clone() const;
+ virtual NoUnit* clone() const;
/**
* Returns a unique class ID for this object POLYMORPHICALLY.
@@ -106,6 +109,8 @@ U_NAMESPACE_END
#endif /* U_HIDE_DRAFT_API */
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __NOUNIT_H__
//eof
//
diff --git a/deps/icu-small/source/i18n/unicode/numberformatter.h b/deps/icu-small/source/i18n/unicode/numberformatter.h
index e9fe39a931..6d48f18ab5 100644
--- a/deps/icu-small/source/i18n/unicode/numberformatter.h
+++ b/deps/icu-small/source/i18n/unicode/numberformatter.h
@@ -1,15 +1,19 @@
// © 2017 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
+#ifndef __NUMBERFORMATTER_H__
+#define __NUMBERFORMATTER_H__
+
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
-#ifndef __NUMBERFORMATTER_H__
-#define __NUMBERFORMATTER_H__
#include "unicode/appendable.h"
-#include "unicode/dcfmtsym.h"
+#include "unicode/bytestream.h"
#include "unicode/currunit.h"
+#include "unicode/dcfmtsym.h"
#include "unicode/fieldpos.h"
#include "unicode/formattedvalue.h"
#include "unicode/fpositer.h"
@@ -22,8 +26,6 @@
#include "unicode/unumberformatter.h"
#include "unicode/uobject.h"
-#ifndef U_HIDE_DRAFT_API
-
/**
* \file
* \brief C++ API: Library for localized number formatting introduced in ICU 60.
@@ -85,6 +87,7 @@ U_NAMESPACE_BEGIN
// Forward declarations:
class IFixedDecimal;
class FieldPositionIteratorHandler;
+class FormattedStringBuilder;
namespace numparse {
namespace impl {
@@ -142,7 +145,6 @@ class MultiplierProducer;
class RoundingImpl;
class ScientificHandler;
class Modifier;
-class NumberStringBuilder;
class AffixPatternProvider;
class NumberPropertyMapper;
struct DecimalFormatProperties;
@@ -167,21 +169,21 @@ void touchRangeLocales(impl::RangeMacroProps& macros);
/**
* Extra name reserved in case it is needed in the future.
*
- * @draft ICU 63
+ * @stable ICU 63
*/
typedef Notation CompactNotation;
/**
* Extra name reserved in case it is needed in the future.
*
- * @draft ICU 63
+ * @stable ICU 63
*/
typedef Notation SimpleNotation;
/**
* A class that defines the notation style to be used when formatting numbers in NumberFormatter.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
class U_I18N_API Notation : public UMemory {
public:
@@ -207,7 +209,7 @@ class U_I18N_API Notation : public UMemory {
* </pre>
*
* @return A ScientificNotation for chaining or passing to the NumberFormatter notation() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
static ScientificNotation scientific();
@@ -231,7 +233,7 @@ class U_I18N_API Notation : public UMemory {
* </pre>
*
* @return A ScientificNotation for chaining or passing to the NumberFormatter notation() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
static ScientificNotation engineering();
@@ -274,7 +276,7 @@ class U_I18N_API Notation : public UMemory {
* </pre>
*
* @return A CompactNotation for passing to the NumberFormatter notation() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
static CompactNotation compactShort();
@@ -298,7 +300,7 @@ class U_I18N_API Notation : public UMemory {
* </pre>
*
* @return A CompactNotation for passing to the NumberFormatter notation() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
static CompactNotation compactLong();
@@ -324,7 +326,7 @@ class U_I18N_API Notation : public UMemory {
* </pre>
*
* @return A SimpleNotation for passing to the NumberFormatter notation() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
static SimpleNotation simple();
@@ -391,7 +393,7 @@ class U_I18N_API Notation : public UMemory {
* <p>
* To create a ScientificNotation, use one of the factory methods in {@link Notation}.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
class U_I18N_API ScientificNotation : public Notation {
public:
@@ -406,7 +408,7 @@ class U_I18N_API ScientificNotation : public Notation {
* @param minExponentDigits
* The minimum number of digits to show in the exponent.
* @return A ScientificNotation, for chaining.
- * @draft ICU 60
+ * @stable ICU 60
*/
ScientificNotation withMinExponentDigits(int32_t minExponentDigits) const;
@@ -421,7 +423,7 @@ class U_I18N_API ScientificNotation : public Notation {
* @param exponentSignDisplay
* The strategy for displaying the sign in the exponent.
* @return A ScientificNotation, for chaining.
- * @draft ICU 60
+ * @stable ICU 60
*/
ScientificNotation withExponentSignDisplay(UNumberSignDisplay exponentSignDisplay) const;
@@ -442,7 +444,7 @@ class U_I18N_API ScientificNotation : public Notation {
/**
* Extra name reserved in case it is needed in the future.
*
- * @draft ICU 63
+ * @stable ICU 63
*/
typedef Precision SignificantDigitsPrecision;
@@ -452,7 +454,7 @@ typedef Precision SignificantDigitsPrecision;
* <p>
* To create a Precision, use one of the factory methods.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
class U_I18N_API Precision : public UMemory {
@@ -472,7 +474,7 @@ class U_I18N_API Precision : public UMemory {
* http://www.serpentine.com/blog/2011/06/29/here-be-dragons-advances-in-problems-you-didnt-even-know-you-had/
*
* @return A Precision for chaining or passing to the NumberFormatter precision() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
static Precision unlimited();
@@ -480,7 +482,7 @@ class U_I18N_API Precision : public UMemory {
* Show numbers rounded if necessary to the nearest integer.
*
* @return A FractionPrecision for chaining or passing to the NumberFormatter precision() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
static FractionPrecision integer();
@@ -509,7 +511,7 @@ class U_I18N_API Precision : public UMemory {
* The minimum and maximum number of numerals to display after the decimal separator (rounding if too
* long or padding with zeros if too short).
* @return A FractionPrecision for chaining or passing to the NumberFormatter precision() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
static FractionPrecision fixedFraction(int32_t minMaxFractionPlaces);
@@ -524,7 +526,7 @@ class U_I18N_API Precision : public UMemory {
* The minimum number of numerals to display after the decimal separator (padding with zeros if
* necessary).
* @return A FractionPrecision for chaining or passing to the NumberFormatter precision() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
static FractionPrecision minFraction(int32_t minFractionPlaces);
@@ -536,7 +538,7 @@ class U_I18N_API Precision : public UMemory {
* @param maxFractionPlaces
* The maximum number of numerals to display after the decimal mark (rounding if necessary).
* @return A FractionPrecision for chaining or passing to the NumberFormatter precision() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
static FractionPrecision maxFraction(int32_t maxFractionPlaces);
@@ -551,7 +553,7 @@ class U_I18N_API Precision : public UMemory {
* @param maxFractionPlaces
* The maximum number of numerals to display after the decimal separator (rounding if necessary).
* @return A FractionPrecision for chaining or passing to the NumberFormatter precision() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
static FractionPrecision minMaxFraction(int32_t minFractionPlaces, int32_t maxFractionPlaces);
@@ -566,7 +568,7 @@ class U_I18N_API Precision : public UMemory {
* The minimum and maximum number of significant digits to display (rounding if too long or padding with
* zeros if too short).
* @return A precision for chaining or passing to the NumberFormatter precision() setter.
- * @draft ICU 62
+ * @stable ICU 62
*/
static SignificantDigitsPrecision fixedSignificantDigits(int32_t minMaxSignificantDigits);
@@ -580,7 +582,7 @@ class U_I18N_API Precision : public UMemory {
* @param minSignificantDigits
* The minimum number of significant digits to display (padding with zeros if too short).
* @return A precision for chaining or passing to the NumberFormatter precision() setter.
- * @draft ICU 62
+ * @stable ICU 62
*/
static SignificantDigitsPrecision minSignificantDigits(int32_t minSignificantDigits);
@@ -590,7 +592,7 @@ class U_I18N_API Precision : public UMemory {
* @param maxSignificantDigits
* The maximum number of significant digits to display (rounding if too long).
* @return A precision for chaining or passing to the NumberFormatter precision() setter.
- * @draft ICU 62
+ * @stable ICU 62
*/
static SignificantDigitsPrecision maxSignificantDigits(int32_t maxSignificantDigits);
@@ -603,7 +605,7 @@ class U_I18N_API Precision : public UMemory {
* @param maxSignificantDigits
* The maximum number of significant digits to display (rounding if necessary).
* @return A precision for chaining or passing to the NumberFormatter precision() setter.
- * @draft ICU 62
+ * @stable ICU 62
*/
static SignificantDigitsPrecision minMaxSignificantDigits(int32_t minSignificantDigits,
int32_t maxSignificantDigits);
@@ -625,7 +627,7 @@ class U_I18N_API Precision : public UMemory {
* @param roundingIncrement
* The increment to which to round numbers.
* @return A precision for chaining or passing to the NumberFormatter precision() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
static IncrementPrecision increment(double roundingIncrement);
@@ -644,7 +646,7 @@ class U_I18N_API Precision : public UMemory {
* Either STANDARD (for digital transactions) or CASH (for transactions where the rounding increment may
* be limited by the available denominations of cash or coins).
* @return A CurrencyPrecision for chaining or passing to the NumberFormatter precision() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
static CurrencyPrecision currency(UCurrencyUsage currencyUsage);
@@ -771,7 +773,7 @@ class U_I18N_API Precision : public UMemory {
* <p>
* To create a FractionPrecision, use one of the factory methods on Precision.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
class U_I18N_API FractionPrecision : public Precision {
public:
@@ -789,7 +791,7 @@ class U_I18N_API FractionPrecision : public Precision {
* @param minSignificantDigits
* The number of significant figures to guarantee.
* @return A precision for chaining or passing to the NumberFormatter precision() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
Precision withMinDigits(int32_t minSignificantDigits) const;
@@ -808,7 +810,7 @@ class U_I18N_API FractionPrecision : public Precision {
* @param maxSignificantDigits
* Round the number to no more than this number of significant figures.
* @return A precision for chaining or passing to the NumberFormatter precision() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
Precision withMaxDigits(int32_t maxSignificantDigits) const;
@@ -827,7 +829,7 @@ class U_I18N_API FractionPrecision : public Precision {
* <p>
* To create a CurrencyPrecision, use one of the factory methods on Precision.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
class U_I18N_API CurrencyPrecision : public Precision {
public:
@@ -846,7 +848,7 @@ class U_I18N_API CurrencyPrecision : public Precision {
* @param currency
* The currency to associate with this rounding precision.
* @return A precision for chaining or passing to the NumberFormatter precision() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
Precision withCurrency(const CurrencyUnit &currency) const;
@@ -865,7 +867,7 @@ class U_I18N_API CurrencyPrecision : public Precision {
* <p>
* To create an IncrementPrecision, use one of the factory methods on Precision.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
class U_I18N_API IncrementPrecision : public Precision {
public:
@@ -882,7 +884,7 @@ class U_I18N_API IncrementPrecision : public Precision {
*
* @param minFrac The minimum number of digits after the decimal separator.
* @return A precision for chaining or passing to the NumberFormatter precision() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
Precision withMinFraction(int32_t minFrac) const;
@@ -900,7 +902,7 @@ class U_I18N_API IncrementPrecision : public Precision {
* <p>
* To create an IntegerWidth, use one of the factory methods.
*
- * @draft ICU 60
+ * @stable ICU 60
* @see NumberFormatter
*/
class U_I18N_API IntegerWidth : public UMemory {
@@ -914,7 +916,7 @@ class U_I18N_API IntegerWidth : public UMemory {
* @param minInt
* The minimum number of places before the decimal separator.
* @return An IntegerWidth for chaining or passing to the NumberFormatter integerWidth() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
static IntegerWidth zeroFillTo(int32_t minInt);
@@ -927,7 +929,7 @@ class U_I18N_API IntegerWidth : public UMemory {
* The maximum number of places before the decimal separator. maxInt == -1 means no
* truncation.
* @return An IntegerWidth for passing to the NumberFormatter integerWidth() setter.
- * @draft ICU 60
+ * @stable ICU 60
*/
IntegerWidth truncateAt(int32_t maxInt);
@@ -994,7 +996,7 @@ class U_I18N_API IntegerWidth : public UMemory {
* <p>
* To create a Scale, use one of the factory methods.
*
- * @draft ICU 62
+ * @stable ICU 62
*/
class U_I18N_API Scale : public UMemory {
public:
@@ -1002,7 +1004,7 @@ class U_I18N_API Scale : public UMemory {
* Do not change the value of numbers when formatting or parsing.
*
* @return A Scale to prevent any multiplication.
- * @draft ICU 62
+ * @stable ICU 62
*/
static Scale none();
@@ -1014,7 +1016,7 @@ class U_I18N_API Scale : public UMemory {
* </pre>
*
* @return A Scale for passing to the setter in NumberFormatter.
- * @draft ICU 62
+ * @stable ICU 62
*/
static Scale powerOfTen(int32_t power);
@@ -1028,7 +1030,7 @@ class U_I18N_API Scale : public UMemory {
* Also see the version of this method that takes a double.
*
* @return A Scale for passing to the setter in NumberFormatter.
- * @draft ICU 62
+ * @stable ICU 62
*/
static Scale byDecimal(StringPiece multiplicand);
@@ -1038,7 +1040,7 @@ class U_I18N_API Scale : public UMemory {
* This method takes a double; also see the version of this method that takes an exact decimal.
*
* @return A Scale for passing to the setter in NumberFormatter.
- * @draft ICU 62
+ * @stable ICU 62
*/
static Scale byDouble(double multiplicand);
@@ -1046,26 +1048,26 @@ class U_I18N_API Scale : public UMemory {
* Multiply a number by both a power of ten and by an arbitrary double value.
*
* @return A Scale for passing to the setter in NumberFormatter.
- * @draft ICU 62
+ * @stable ICU 62
*/
static Scale byDoubleAndPowerOfTen(double multiplicand, int32_t power);
// We need a custom destructor for the DecNum, which means we need to declare
// the copy/move constructor/assignment quartet.
- /** @draft ICU 62 */
+ /** @stable ICU 62 */
Scale(const Scale& other);
- /** @draft ICU 62 */
+ /** @stable ICU 62 */
Scale& operator=(const Scale& other);
- /** @draft ICU 62 */
+ /** @stable ICU 62 */
Scale(Scale&& src) U_NOEXCEPT;
- /** @draft ICU 62 */
+ /** @stable ICU 62 */
Scale& operator=(Scale&& src) U_NOEXCEPT;
- /** @draft ICU 62 */
+ /** @stable ICU 62 */
~Scale();
#ifndef U_HIDE_INTERNAL_API
@@ -1343,7 +1345,7 @@ class U_I18N_API Padder : public UMemory {
}
int32_t padAndApply(const impl::Modifier &mod1, const impl::Modifier &mod2,
- impl::NumberStringBuilder &string, int32_t leftIndex, int32_t rightIndex,
+ FormattedStringBuilder &string, int32_t leftIndex, int32_t rightIndex,
UErrorCode &status) const;
// To allow MacroProps/MicroProps to initialize empty instances:
@@ -1465,7 +1467,7 @@ class U_I18N_API NumberFormatterSettings {
* The notation strategy to use.
* @return The fluent chain.
* @see Notation
- * @draft ICU 60
+ * @stable ICU 60
*/
Derived notation(const Notation &notation) const &;
@@ -1476,7 +1478,7 @@ class U_I18N_API NumberFormatterSettings {
* The notation strategy to use.
* @return The fluent chain.
* @see #notation
- * @draft ICU 62
+ * @stable ICU 62
*/
Derived notation(const Notation &notation) &&;
@@ -1521,7 +1523,7 @@ class U_I18N_API NumberFormatterSettings {
* @see Currency
* @see NoUnit
* @see #perUnit
- * @draft ICU 60
+ * @stable ICU 60
*/
Derived unit(const icu::MeasureUnit &unit) const &;
@@ -1532,7 +1534,7 @@ class U_I18N_API NumberFormatterSettings {
* The unit to render.
* @return The fluent chain.
* @see #unit
- * @draft ICU 62
+ * @stable ICU 62
*/
Derived unit(const icu::MeasureUnit &unit) &&;
@@ -1547,7 +1549,7 @@ class U_I18N_API NumberFormatterSettings {
* @return The fluent chain.
* @see #unit
* @see MeasureUnit
- * @draft ICU 60
+ * @stable ICU 60
*/
Derived adoptUnit(icu::MeasureUnit *unit) const &;
@@ -1558,7 +1560,7 @@ class U_I18N_API NumberFormatterSettings {
* The unit to render.
* @return The fluent chain.
* @see #adoptUnit
- * @draft ICU 62
+ * @stable ICU 62
*/
Derived adoptUnit(icu::MeasureUnit *unit) &&;
@@ -1582,7 +1584,7 @@ class U_I18N_API NumberFormatterSettings {
* The unit to render in the denominator.
* @return The fluent chain
* @see #unit
- * @draft ICU 61
+ * @stable ICU 61
*/
Derived perUnit(const icu::MeasureUnit &perUnit) const &;
@@ -1593,7 +1595,7 @@ class U_I18N_API NumberFormatterSettings {
* The unit to render in the denominator.
* @return The fluent chain.
* @see #perUnit
- * @draft ICU 62
+ * @stable ICU 62
*/
Derived perUnit(const icu::MeasureUnit &perUnit) &&;
@@ -1608,7 +1610,7 @@ class U_I18N_API NumberFormatterSettings {
* @return The fluent chain.
* @see #perUnit
* @see MeasureUnit
- * @draft ICU 61
+ * @stable ICU 61
*/
Derived adoptPerUnit(icu::MeasureUnit *perUnit) const &;
@@ -1619,7 +1621,7 @@ class U_I18N_API NumberFormatterSettings {
* The unit to render in the denominator.
* @return The fluent chain.
* @see #adoptPerUnit
- * @draft ICU 62
+ * @stable ICU 62
*/
Derived adoptPerUnit(icu::MeasureUnit *perUnit) &&;
@@ -1651,7 +1653,7 @@ class U_I18N_API NumberFormatterSettings {
* The rounding precision to use.
* @return The fluent chain.
* @see Precision
- * @draft ICU 62
+ * @stable ICU 62
*/
Derived precision(const Precision& precision) const &;
@@ -1662,7 +1664,7 @@ class U_I18N_API NumberFormatterSettings {
* The rounding precision to use.
* @return The fluent chain.
* @see #precision
- * @draft ICU 62
+ * @stable ICU 62
*/
Derived precision(const Precision& precision) &&;
@@ -1682,7 +1684,7 @@ class U_I18N_API NumberFormatterSettings {
*
* @param roundingMode The rounding mode to use.
* @return The fluent chain.
- * @draft ICU 62
+ * @stable ICU 62
*/
Derived roundingMode(UNumberFormatRoundingMode roundingMode) const &;
@@ -1692,7 +1694,7 @@ class U_I18N_API NumberFormatterSettings {
* @param roundingMode The rounding mode to use.
* @return The fluent chain.
* @see #roundingMode
- * @draft ICU 62
+ * @stable ICU 62
*/
Derived roundingMode(UNumberFormatRoundingMode roundingMode) &&;
@@ -1721,7 +1723,7 @@ class U_I18N_API NumberFormatterSettings {
* @param strategy
* The grouping strategy to use.
* @return The fluent chain.
- * @draft ICU 61
+ * @stable ICU 61
*/
Derived grouping(UNumberGroupingStrategy strategy) const &;
@@ -1732,7 +1734,7 @@ class U_I18N_API NumberFormatterSettings {
* The grouping strategy to use.
* @return The fluent chain.
* @see #grouping
- * @draft ICU 62
+ * @stable ICU 62
*/
Derived grouping(UNumberGroupingStrategy strategy) &&;
@@ -1758,7 +1760,7 @@ class U_I18N_API NumberFormatterSettings {
* The integer width to use.
* @return The fluent chain.
* @see IntegerWidth
- * @draft ICU 60
+ * @stable ICU 60
*/
Derived integerWidth(const IntegerWidth &style) const &;
@@ -1769,7 +1771,7 @@ class U_I18N_API NumberFormatterSettings {
* The integer width to use.
* @return The fluent chain.
* @see #integerWidth
- * @draft ICU 62
+ * @stable ICU 62
*/
Derived integerWidth(const IntegerWidth &style) &&;
@@ -1811,7 +1813,7 @@ class U_I18N_API NumberFormatterSettings {
* The DecimalFormatSymbols to use.
* @return The fluent chain.
* @see DecimalFormatSymbols
- * @draft ICU 60
+ * @stable ICU 60
*/
Derived symbols(const DecimalFormatSymbols &symbols) const &;
@@ -1822,7 +1824,7 @@ class U_I18N_API NumberFormatterSettings {
* The DecimalFormatSymbols to use.
* @return The fluent chain.
* @see #symbols
- * @draft ICU 62
+ * @stable ICU 62
*/
Derived symbols(const DecimalFormatSymbols &symbols) &&;
@@ -1857,7 +1859,7 @@ class U_I18N_API NumberFormatterSettings {
* The NumberingSystem to use.
* @return The fluent chain.
* @see NumberingSystem
- * @draft ICU 60
+ * @stable ICU 60
*/
Derived adoptSymbols(NumberingSystem *symbols) const &;
@@ -1868,7 +1870,7 @@ class U_I18N_API NumberFormatterSettings {
* The NumberingSystem to use.
* @return The fluent chain.
* @see #adoptSymbols
- * @draft ICU 62
+ * @stable ICU 62
*/
Derived adoptSymbols(NumberingSystem *symbols) &&;
@@ -1895,7 +1897,7 @@ class U_I18N_API NumberFormatterSettings {
* The width to use when rendering numbers.
* @return The fluent chain
* @see UNumberUnitWidth
- * @draft ICU 60
+ * @stable ICU 60
*/
Derived unitWidth(UNumberUnitWidth width) const &;
@@ -1906,7 +1908,7 @@ class U_I18N_API NumberFormatterSettings {
* The width to use when rendering numbers.
* @return The fluent chain.
* @see #unitWidth
- * @draft ICU 62
+ * @stable ICU 62
*/
Derived unitWidth(UNumberUnitWidth width) &&;
@@ -1933,7 +1935,7 @@ class U_I18N_API NumberFormatterSettings {
* The sign display strategy to use when rendering numbers.
* @return The fluent chain
* @see UNumberSignDisplay
- * @draft ICU 60
+ * @stable ICU 60
*/
Derived sign(UNumberSignDisplay style) const &;
@@ -1944,7 +1946,7 @@ class U_I18N_API NumberFormatterSettings {
* The sign display strategy to use when rendering numbers.
* @return The fluent chain.
* @see #sign
- * @draft ICU 62
+ * @stable ICU 62
*/
Derived sign(UNumberSignDisplay style) &&;
@@ -1971,7 +1973,7 @@ class U_I18N_API NumberFormatterSettings {
* The decimal separator display strategy to use when rendering numbers.
* @return The fluent chain
* @see UNumberDecimalSeparatorDisplay
- * @draft ICU 60
+ * @stable ICU 60
*/
Derived decimal(UNumberDecimalSeparatorDisplay style) const &;
@@ -1982,7 +1984,7 @@ class U_I18N_API NumberFormatterSettings {
* The decimal separator display strategy to use when rendering numbers.
* @return The fluent chain.
* @see #decimal
- * @draft ICU 62
+ * @stable ICU 62
*/
Derived decimal(UNumberDecimalSeparatorDisplay style) &&;
@@ -2008,7 +2010,7 @@ class U_I18N_API NumberFormatterSettings {
* @param scale
* The scale to apply when rendering numbers.
* @return The fluent chain
- * @draft ICU 62
+ * @stable ICU 62
*/
Derived scale(const Scale &scale) const &;
@@ -2019,7 +2021,7 @@ class U_I18N_API NumberFormatterSettings {
* The scale to apply when rendering numbers.
* @return The fluent chain.
* @see #scale
- * @draft ICU 62
+ * @stable ICU 62
*/
Derived scale(const Scale &scale) &&;
@@ -2076,10 +2078,11 @@ class U_I18N_API NumberFormatterSettings {
* behavior should produce the same skeleton.
*
* @return A number skeleton string with behavior corresponding to this number formatter.
- * @draft ICU 62
+ * @stable ICU 62
*/
UnicodeString toSkeleton(UErrorCode& status) const;
+#ifndef U_HIDE_DRAFT_API
/**
* Returns the current (Un)LocalizedNumberFormatter as a LocalPointer
* wrapping a heap-allocated copy of the current object.
@@ -2101,12 +2104,13 @@ class U_I18N_API NumberFormatterSettings {
* @draft ICU 64
*/
LocalPointer<Derived> clone() &&;
+#endif /* U_HIDE_DRAFT_API */
/**
* Sets the UErrorCode if an error occurred in the fluent chain.
* Preserves older error codes in the outErrorCode.
* @return TRUE if U_FAILURE(outErrorCode)
- * @draft ICU 60
+ * @stable ICU 60
*/
UBool copyErrorTo(UErrorCode &outErrorCode) const {
if (U_FAILURE(outErrorCode)) {
@@ -2139,7 +2143,7 @@ class U_I18N_API NumberFormatterSettings {
* Instances of this class are immutable and thread-safe.
*
* @see NumberFormatter
- * @draft ICU 60
+ * @stable ICU 60
*/
class U_I18N_API UnlocalizedNumberFormatter
: public NumberFormatterSettings<UnlocalizedNumberFormatter>, public UMemory {
@@ -2152,7 +2156,7 @@ class U_I18N_API UnlocalizedNumberFormatter
* @param locale
* The locale to use when loading data for number formatting.
* @return The fluent chain.
- * @draft ICU 60
+ * @stable ICU 60
*/
LocalizedNumberFormatter locale(const icu::Locale &locale) const &;
@@ -2163,40 +2167,40 @@ class U_I18N_API UnlocalizedNumberFormatter
* The locale to use when loading data for number formatting.
* @return The fluent chain.
* @see #locale
- * @draft ICU 62
+ * @stable ICU 62
*/
LocalizedNumberFormatter locale(const icu::Locale &locale) &&;
/**
* Default constructor: puts the formatter into a valid but undefined state.
*
- * @draft ICU 62
+ * @stable ICU 62
*/
UnlocalizedNumberFormatter() = default;
/**
* Returns a copy of this UnlocalizedNumberFormatter.
- * @draft ICU 60
+ * @stable ICU 60
*/
UnlocalizedNumberFormatter(const UnlocalizedNumberFormatter &other);
/**
* Move constructor:
* The source UnlocalizedNumberFormatter will be left in a valid but undefined state.
- * @draft ICU 62
+ * @stable ICU 62
*/
UnlocalizedNumberFormatter(UnlocalizedNumberFormatter&& src) U_NOEXCEPT;
/**
* Copy assignment operator.
- * @draft ICU 62
+ * @stable ICU 62
*/
UnlocalizedNumberFormatter& operator=(const UnlocalizedNumberFormatter& other);
/**
* Move assignment operator:
* The source UnlocalizedNumberFormatter will be left in a valid but undefined state.
- * @draft ICU 62
+ * @stable ICU 62
*/
UnlocalizedNumberFormatter& operator=(UnlocalizedNumberFormatter&& src) U_NOEXCEPT;
@@ -2219,7 +2223,7 @@ class U_I18N_API UnlocalizedNumberFormatter
* Instances of this class are immutable and thread-safe.
*
* @see NumberFormatter
- * @draft ICU 60
+ * @stable ICU 60
*/
class U_I18N_API LocalizedNumberFormatter
: public NumberFormatterSettings<LocalizedNumberFormatter>, public UMemory {
@@ -2233,7 +2237,7 @@ class U_I18N_API LocalizedNumberFormatter
* @param status
* Set to an ErrorCode if one occurred in the setter chain or during formatting.
* @return A FormattedNumber object; call .toString() to get the string.
- * @draft ICU 60
+ * @stable ICU 60
*/
FormattedNumber formatInt(int64_t value, UErrorCode &status) const;
@@ -2246,7 +2250,7 @@ class U_I18N_API LocalizedNumberFormatter
* @param status
* Set to an ErrorCode if one occurred in the setter chain or during formatting.
* @return A FormattedNumber object; call .toString() to get the string.
- * @draft ICU 60
+ * @stable ICU 60
*/
FormattedNumber formatDouble(double value, UErrorCode &status) const;
@@ -2262,7 +2266,7 @@ class U_I18N_API LocalizedNumberFormatter
* @param status
* Set to an ErrorCode if one occurred in the setter chain or during formatting.
* @return A FormattedNumber object; call .toString() to get the string.
- * @draft ICU 60
+ * @stable ICU 60
*/
FormattedNumber formatDecimal(StringPiece value, UErrorCode& status) const;
@@ -2303,40 +2307,40 @@ class U_I18N_API LocalizedNumberFormatter
* The caller owns the returned object and must delete it when finished.
*
* @return A Format wrapping this LocalizedNumberFormatter.
- * @draft ICU 62
+ * @stable ICU 62
*/
Format* toFormat(UErrorCode& status) const;
/**
* Default constructor: puts the formatter into a valid but undefined state.
*
- * @draft ICU 62
+ * @stable ICU 62
*/
LocalizedNumberFormatter() = default;
/**
* Returns a copy of this LocalizedNumberFormatter.
- * @draft ICU 60
+ * @stable ICU 60
*/
LocalizedNumberFormatter(const LocalizedNumberFormatter &other);
/**
* Move constructor:
* The source LocalizedNumberFormatter will be left in a valid but undefined state.
- * @draft ICU 62
+ * @stable ICU 62
*/
LocalizedNumberFormatter(LocalizedNumberFormatter&& src) U_NOEXCEPT;
/**
* Copy assignment operator.
- * @draft ICU 62
+ * @stable ICU 62
*/
LocalizedNumberFormatter& operator=(const LocalizedNumberFormatter& other);
/**
* Move assignment operator:
* The source LocalizedNumberFormatter will be left in a valid but undefined state.
- * @draft ICU 62
+ * @stable ICU 62
*/
LocalizedNumberFormatter& operator=(LocalizedNumberFormatter&& src) U_NOEXCEPT;
@@ -2360,7 +2364,7 @@ class U_I18N_API LocalizedNumberFormatter
/**
* Destruct this LocalizedNumberFormatter, cleaning up any memory it might own.
- * @draft ICU 60
+ * @stable ICU 60
*/
~LocalizedNumberFormatter();
@@ -2401,27 +2405,30 @@ class U_I18N_API LocalizedNumberFormatter
*
* Instances of this class are immutable and thread-safe.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
class U_I18N_API FormattedNumber : public UMemory, public FormattedValue {
public:
+ // Default constructor cannot have #ifndef U_HIDE_DRAFT_API
+#ifndef U_FORCE_HIDE_DRAFT_API
/**
* Default constructor; makes an empty FormattedNumber.
* @draft ICU 64
*/
FormattedNumber()
: fData(nullptr), fErrorCode(U_INVALID_STATE_ERROR) {}
+#endif // U_FORCE_HIDE_DRAFT_API
/**
* Move constructor: Leaves the source FormattedNumber in an undefined state.
- * @draft ICU 62
+ * @stable ICU 62
*/
FormattedNumber(FormattedNumber&& src) U_NOEXCEPT;
/**
* Destruct an instance of FormattedNumber.
- * @draft ICU 60
+ * @stable ICU 60
*/
virtual ~FormattedNumber() U_OVERRIDE;
@@ -2433,7 +2440,7 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue {
/**
* Move assignment: Leaves the source FormattedNumber in an undefined state.
- * @draft ICU 62
+ * @stable ICU 62
*/
FormattedNumber& operator=(FormattedNumber&& src) U_NOEXCEPT;
@@ -2443,7 +2450,7 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue {
*
* For more information, see FormattedValue::toString()
*
- * @draft ICU 62
+ * @stable ICU 62
*/
UnicodeString toString(UErrorCode& status) const U_OVERRIDE;
@@ -2457,7 +2464,7 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue {
*
* For more information, see FormattedValue::appendTo()
*
- * @draft ICU 62
+ * @stable ICU 62
*/
Appendable &appendTo(Appendable& appendable, UErrorCode& status) const U_OVERRIDE;
@@ -2465,6 +2472,7 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue {
/** @copydoc FormattedValue::nextPosition() */
UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const U_OVERRIDE;
+#ifndef U_HIDE_DRAFT_API
/**
* Determines the start (inclusive) and end (exclusive) indices of the next occurrence of the given
* <em>field</em> in the output string. This allows you to determine the locations of, for example,
@@ -2516,6 +2524,30 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue {
* @see UNumberFormatFields
*/
void getAllFieldPositions(FieldPositionIterator &iterator, UErrorCode &status) const;
+#endif /* U_HIDE_DRAFT_API */
+
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Export the formatted number as a "numeric string" conforming to the
+ * syntax defined in the Decimal Arithmetic Specification, available at
+ * http://speleotrove.com/decimal
+ *
+ * This endpoint is useful for obtaining the exact number being printed
+ * after scaling and rounding have been applied by the number formatter.
+ *
+ * Example call site:
+ *
+ * auto decimalNumber = fn.toDecimalNumber<std::string>(status);
+ *
+ * @tparam StringClass A string class compatible with StringByteSink;
+ * for example, std::string.
+ * @param status Set if an error occurs.
+ * @return A StringClass containing the numeric string.
+ * @draft ICU 65
+ */
+ template<typename StringClass>
+ inline StringClass toDecimalNumber(UErrorCode& status) const;
+#endif // U_HIDE_DRAFT_API
#ifndef U_HIDE_INTERNAL_API
@@ -2550,6 +2582,9 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue {
explicit FormattedNumber(UErrorCode errorCode)
: fData(nullptr), fErrorCode(errorCode) {}
+ // TODO(ICU-20775): Propose this as API.
+ void toDecimalNumber(ByteSink& sink, UErrorCode& status) const;
+
// To give LocalizedNumberFormatter format methods access to this class's constructor:
friend class LocalizedNumberFormatter;
@@ -2557,10 +2592,21 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue {
friend struct impl::UFormattedNumberImpl;
};
+#ifndef U_HIDE_DRAFT_API
+// Note: This is draft ICU 65
+template<typename StringClass>
+StringClass FormattedNumber::toDecimalNumber(UErrorCode& status) const {
+ StringClass result;
+ StringByteSink<StringClass> sink(&result);
+ toDecimalNumber(sink, status);
+ return result;
+};
+#endif // U_HIDE_DRAFT_API
+
/**
* See the main description in numberformatter.h for documentation and examples.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
class U_I18N_API NumberFormatter final {
public:
@@ -2569,7 +2615,7 @@ class U_I18N_API NumberFormatter final {
* the call site.
*
* @return An {@link UnlocalizedNumberFormatter}, to be used for chaining.
- * @draft ICU 60
+ * @stable ICU 60
*/
static UnlocalizedNumberFormatter with();
@@ -2580,7 +2626,7 @@ class U_I18N_API NumberFormatter final {
* @param locale
* The locale from which to load formats and symbols for number formatting.
* @return A {@link LocalizedNumberFormatter}, to be used for chaining.
- * @draft ICU 60
+ * @stable ICU 60
*/
static LocalizedNumberFormatter withLocale(const Locale &locale);
@@ -2596,10 +2642,11 @@ class U_I18N_API NumberFormatter final {
* @param status
* Set to U_NUMBER_SKELETON_SYNTAX_ERROR if the skeleton was invalid.
* @return An UnlocalizedNumberFormatter, to be used for chaining.
- * @draft ICU 62
+ * @stable ICU 62
*/
static UnlocalizedNumberFormatter forSkeleton(const UnicodeString& skeleton, UErrorCode& status);
+#ifndef U_HIDE_DRAFT_API
/**
* Call this method at the beginning of a NumberFormatter fluent chain to create an instance based
* on a given number skeleton string.
@@ -2619,6 +2666,7 @@ class U_I18N_API NumberFormatter final {
*/
static UnlocalizedNumberFormatter forSkeleton(const UnicodeString& skeleton,
UParseError& perror, UErrorCode& status);
+#endif
/**
* Use factory methods instead of the constructor to create a NumberFormatter.
@@ -2629,8 +2677,9 @@ class U_I18N_API NumberFormatter final {
} // namespace number
U_NAMESPACE_END
-#endif // U_HIDE_DRAFT_API
+#endif /* #if !UCONFIG_NO_FORMATTING */
+
+#endif /* U_SHOW_CPLUSPLUS_API */
#endif // __NUMBERFORMATTER_H__
-#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/deps/icu-small/source/i18n/unicode/numberrangeformatter.h b/deps/icu-small/source/i18n/unicode/numberrangeformatter.h
index 47c4bfe3f5..e3a72aa8b2 100644
--- a/deps/icu-small/source/i18n/unicode/numberrangeformatter.h
+++ b/deps/icu-small/source/i18n/unicode/numberrangeformatter.h
@@ -1,10 +1,15 @@
// © 2018 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
-#if !UCONFIG_NO_FORMATTING
#ifndef __NUMBERRANGEFORMATTER_H__
#define __NUMBERRANGEFORMATTER_H__
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
+#if !UCONFIG_NO_FORMATTING
+
#include <atomic>
#include "unicode/appendable.h"
#include "unicode/fieldpos.h"
@@ -12,8 +17,6 @@
#include "unicode/fpositer.h"
#include "unicode/numberformatter.h"
-#ifndef U_HIDE_DRAFT_API
-
/**
* \file
* \brief C++ API: Library for localized formatting of number, currency, and unit ranges.
@@ -44,7 +47,7 @@
/**
* Defines how to merge fields that are identical across the range sign.
*
- * @draft ICU 63
+ * @stable ICU 63
*/
typedef enum UNumberRangeCollapse {
/**
@@ -53,14 +56,14 @@ typedef enum UNumberRangeCollapse {
*
* The heuristics used for this option are subject to change over time.
*
- * @draft ICU 63
+ * @stable ICU 63
*/
UNUM_RANGE_COLLAPSE_AUTO,
/**
* Do not collapse any part of the number. Example: "3.2 thousand kilograms – 5.3 thousand kilograms"
*
- * @draft ICU 63
+ * @stable ICU 63
*/
UNUM_RANGE_COLLAPSE_NONE,
@@ -68,7 +71,7 @@ typedef enum UNumberRangeCollapse {
* Collapse the unit part of the number, but not the notation, if present. Example: "3.2 thousand – 5.3 thousand
* kilograms"
*
- * @draft ICU 63
+ * @stable ICU 63
*/
UNUM_RANGE_COLLAPSE_UNIT,
@@ -76,7 +79,7 @@ typedef enum UNumberRangeCollapse {
* Collapse any field that is equal across the range sign. May introduce ambiguity on the magnitude of the
* number. Example: "3.2 – 5.3 thousand kilograms"
*
- * @draft ICU 63
+ * @stable ICU 63
*/
UNUM_RANGE_COLLAPSE_ALL
} UNumberRangeCollapse;
@@ -85,14 +88,14 @@ typedef enum UNumberRangeCollapse {
* Defines the behavior when the two numbers in the range are identical after rounding. To programmatically detect
* when the identity fallback is used, compare the lower and upper BigDecimals via FormattedNumber.
*
- * @draft ICU 63
+ * @stable ICU 63
* @see NumberRangeFormatter
*/
typedef enum UNumberRangeIdentityFallback {
/**
* Show the number as a single value rather than a range. Example: "$5"
*
- * @draft ICU 63
+ * @stable ICU 63
*/
UNUM_IDENTITY_FALLBACK_SINGLE_VALUE,
@@ -100,7 +103,7 @@ typedef enum UNumberRangeIdentityFallback {
* Show the number using a locale-sensitive approximation pattern. If the numbers were the same before rounding,
* show the single value. Example: "~$5" or "$5"
*
- * @draft ICU 63
+ * @stable ICU 63
*/
UNUM_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE,
@@ -108,7 +111,7 @@ typedef enum UNumberRangeIdentityFallback {
* Show the number using a locale-sensitive approximation pattern. Use the range pattern always, even if the
* inputs are the same. Example: "~$5"
*
- * @draft ICU 63
+ * @stable ICU 63
*/
UNUM_IDENTITY_FALLBACK_APPROXIMATELY,
@@ -116,7 +119,7 @@ typedef enum UNumberRangeIdentityFallback {
* Show the number as the range of two equal values. Use the range pattern always, even if the inputs are the
* same. Example (with RangeCollapse.NONE): "$5 – $5"
*
- * @draft ICU 63
+ * @stable ICU 63
*/
UNUM_IDENTITY_FALLBACK_RANGE
} UNumberRangeIdentityFallback;
@@ -125,14 +128,14 @@ typedef enum UNumberRangeIdentityFallback {
* Used in the result class FormattedNumberRange to indicate to the user whether the numbers formatted in the range
* were equal or not, and whether or not the identity fallback was applied.
*
- * @draft ICU 63
+ * @stable ICU 63
* @see NumberRangeFormatter
*/
typedef enum UNumberRangeIdentityResult {
/**
* Used to indicate that the two numbers in the range were equal, even before any rounding rules were applied.
*
- * @draft ICU 63
+ * @stable ICU 63
* @see NumberRangeFormatter
*/
UNUM_IDENTITY_RESULT_EQUAL_BEFORE_ROUNDING,
@@ -140,7 +143,7 @@ typedef enum UNumberRangeIdentityResult {
/**
* Used to indicate that the two numbers in the range were equal, but only after rounding rules were applied.
*
- * @draft ICU 63
+ * @stable ICU 63
* @see NumberRangeFormatter
*/
UNUM_IDENTITY_RESULT_EQUAL_AFTER_ROUNDING,
@@ -148,7 +151,7 @@ typedef enum UNumberRangeIdentityResult {
/**
* Used to indicate that the two numbers in the range were not equal, even after rounding rules were applied.
*
- * @draft ICU 63
+ * @stable ICU 63
* @see NumberRangeFormatter
*/
UNUM_IDENTITY_RESULT_NOT_EQUAL,
@@ -254,7 +257,7 @@ class U_I18N_API NumberRangeFormatterSettings {
* @param formatter
* The formatter to use for both numbers in the range.
* @return The fluent chain.
- * @draft ICU 63
+ * @stable ICU 63
*/
Derived numberFormatterBoth(const UnlocalizedNumberFormatter &formatter) const &;
@@ -265,7 +268,7 @@ class U_I18N_API NumberRangeFormatterSettings {
* The formatter to use for both numbers in the range.
* @return The fluent chain.
* @see #numberFormatterBoth
- * @draft ICU 63
+ * @stable ICU 63
*/
Derived numberFormatterBoth(const UnlocalizedNumberFormatter &formatter) &&;
@@ -276,7 +279,7 @@ class U_I18N_API NumberRangeFormatterSettings {
* The formatter to use for both numbers in the range.
* @return The fluent chain.
* @see #numberFormatterBoth
- * @draft ICU 63
+ * @stable ICU 63
*/
Derived numberFormatterBoth(UnlocalizedNumberFormatter &&formatter) const &;
@@ -287,7 +290,7 @@ class U_I18N_API NumberRangeFormatterSettings {
* The formatter to use for both numbers in the range.
* @return The fluent chain.
* @see #numberFormatterBoth
- * @draft ICU 63
+ * @stable ICU 63
*/
Derived numberFormatterBoth(UnlocalizedNumberFormatter &&formatter) &&;
@@ -300,7 +303,7 @@ class U_I18N_API NumberRangeFormatterSettings {
* @param formatterFirst
* The formatter to use for the first number in the range.
* @return The fluent chain.
- * @draft ICU 63
+ * @stable ICU 63
*/
Derived numberFormatterFirst(const UnlocalizedNumberFormatter &formatterFirst) const &;
@@ -311,7 +314,7 @@ class U_I18N_API NumberRangeFormatterSettings {
* The formatter to use for the first number in the range.
* @return The fluent chain.
* @see #numberFormatterFirst
- * @draft ICU 63
+ * @stable ICU 63
*/
Derived numberFormatterFirst(const UnlocalizedNumberFormatter &formatterFirst) &&;
@@ -322,7 +325,7 @@ class U_I18N_API NumberRangeFormatterSettings {
* The formatter to use for the first number in the range.
* @return The fluent chain.
* @see #numberFormatterFirst
- * @draft ICU 63
+ * @stable ICU 63
*/
Derived numberFormatterFirst(UnlocalizedNumberFormatter &&formatterFirst) const &;
@@ -333,7 +336,7 @@ class U_I18N_API NumberRangeFormatterSettings {
* The formatter to use for the first number in the range.
* @return The fluent chain.
* @see #numberFormatterFirst
- * @draft ICU 63
+ * @stable ICU 63
*/
Derived numberFormatterFirst(UnlocalizedNumberFormatter &&formatterFirst) &&;
@@ -346,7 +349,7 @@ class U_I18N_API NumberRangeFormatterSettings {
* @param formatterSecond
* The formatter to use for the second number in the range.
* @return The fluent chain.
- * @draft ICU 63
+ * @stable ICU 63
*/
Derived numberFormatterSecond(const UnlocalizedNumberFormatter &formatterSecond) const &;
@@ -357,7 +360,7 @@ class U_I18N_API NumberRangeFormatterSettings {
* The formatter to use for the second number in the range.
* @return The fluent chain.
* @see #numberFormatterSecond
- * @draft ICU 63
+ * @stable ICU 63
*/
Derived numberFormatterSecond(const UnlocalizedNumberFormatter &formatterSecond) &&;
@@ -368,7 +371,7 @@ class U_I18N_API NumberRangeFormatterSettings {
* The formatter to use for the second number in the range.
* @return The fluent chain.
* @see #numberFormatterSecond
- * @draft ICU 63
+ * @stable ICU 63
*/
Derived numberFormatterSecond(UnlocalizedNumberFormatter &&formatterSecond) const &;
@@ -379,7 +382,7 @@ class U_I18N_API NumberRangeFormatterSettings {
* The formatter to use for the second number in the range.
* @return The fluent chain.
* @see #numberFormatterSecond
- * @draft ICU 63
+ * @stable ICU 63
*/
Derived numberFormatterSecond(UnlocalizedNumberFormatter &&formatterSecond) &&;
@@ -398,7 +401,7 @@ class U_I18N_API NumberRangeFormatterSettings {
* @param collapse
* The collapsing strategy to use for this range.
* @return The fluent chain.
- * @draft ICU 63
+ * @stable ICU 63
*/
Derived collapse(UNumberRangeCollapse collapse) const &;
@@ -409,7 +412,7 @@ class U_I18N_API NumberRangeFormatterSettings {
* The collapsing strategy to use for this range.
* @return The fluent chain.
* @see #collapse
- * @draft ICU 63
+ * @stable ICU 63
*/
Derived collapse(UNumberRangeCollapse collapse) &&;
@@ -431,7 +434,7 @@ class U_I18N_API NumberRangeFormatterSettings {
* @param identityFallback
* The strategy to use when formatting two numbers that end up being the same.
* @return The fluent chain.
- * @draft ICU 63
+ * @stable ICU 63
*/
Derived identityFallback(UNumberRangeIdentityFallback identityFallback) const &;
@@ -442,10 +445,11 @@ class U_I18N_API NumberRangeFormatterSettings {
* The strategy to use when formatting two numbers that end up being the same.
* @return The fluent chain.
* @see #identityFallback
- * @draft ICU 63
+ * @stable ICU 63
*/
Derived identityFallback(UNumberRangeIdentityFallback identityFallback) &&;
+#ifndef U_HIDE_DRAFT_API
/**
* Returns the current (Un)LocalizedNumberRangeFormatter as a LocalPointer
* wrapping a heap-allocated copy of the current object.
@@ -467,12 +471,13 @@ class U_I18N_API NumberRangeFormatterSettings {
* @draft ICU 64
*/
LocalPointer<Derived> clone() &&;
+#endif /* U_HIDE_DRAFT_API */
/**
* Sets the UErrorCode if an error occurred in the fluent chain.
* Preserves older error codes in the outErrorCode.
* @return TRUE if U_FAILURE(outErrorCode)
- * @draft ICU 63
+ * @stable ICU 63
*/
UBool copyErrorTo(UErrorCode &outErrorCode) const {
if (U_FAILURE(outErrorCode)) {
@@ -501,7 +506,7 @@ class U_I18N_API NumberRangeFormatterSettings {
* Instances of this class are immutable and thread-safe.
*
* @see NumberRangeFormatter
- * @draft ICU 63
+ * @stable ICU 63
*/
class U_I18N_API UnlocalizedNumberRangeFormatter
: public NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>, public UMemory {
@@ -514,7 +519,7 @@ class U_I18N_API UnlocalizedNumberRangeFormatter
* @param locale
* The locale to use when loading data for number formatting.
* @return The fluent chain.
- * @draft ICU 63
+ * @stable ICU 63
*/
LocalizedNumberRangeFormatter locale(const icu::Locale &locale) const &;
@@ -525,40 +530,40 @@ class U_I18N_API UnlocalizedNumberRangeFormatter
* The locale to use when loading data for number formatting.
* @return The fluent chain.
* @see #locale
- * @draft ICU 63
+ * @stable ICU 63
*/
LocalizedNumberRangeFormatter locale(const icu::Locale &locale) &&;
/**
* Default constructor: puts the formatter into a valid but undefined state.
*
- * @draft ICU 63
+ * @stable ICU 63
*/
UnlocalizedNumberRangeFormatter() = default;
/**
* Returns a copy of this UnlocalizedNumberRangeFormatter.
- * @draft ICU 63
+ * @stable ICU 63
*/
UnlocalizedNumberRangeFormatter(const UnlocalizedNumberRangeFormatter &other);
/**
* Move constructor:
* The source UnlocalizedNumberRangeFormatter will be left in a valid but undefined state.
- * @draft ICU 63
+ * @stable ICU 63
*/
UnlocalizedNumberRangeFormatter(UnlocalizedNumberRangeFormatter&& src) U_NOEXCEPT;
/**
* Copy assignment operator.
- * @draft ICU 63
+ * @stable ICU 63
*/
UnlocalizedNumberRangeFormatter& operator=(const UnlocalizedNumberRangeFormatter& other);
/**
* Move assignment operator:
* The source UnlocalizedNumberRangeFormatter will be left in a valid but undefined state.
- * @draft ICU 63
+ * @stable ICU 63
*/
UnlocalizedNumberRangeFormatter& operator=(UnlocalizedNumberRangeFormatter&& src) U_NOEXCEPT;
@@ -582,7 +587,7 @@ class U_I18N_API UnlocalizedNumberRangeFormatter
* Instances of this class are immutable and thread-safe.
*
* @see NumberFormatter
- * @draft ICU 63
+ * @stable ICU 63
*/
class U_I18N_API LocalizedNumberRangeFormatter
: public NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>, public UMemory {
@@ -598,7 +603,7 @@ class U_I18N_API LocalizedNumberRangeFormatter
* @param status
* Set if an error occurs while formatting.
* @return A FormattedNumberRange object; call .toString() to get the string.
- * @draft ICU 63
+ * @stable ICU 63
*/
FormattedNumberRange formatFormattableRange(
const Formattable& first, const Formattable& second, UErrorCode& status) const;
@@ -606,33 +611,33 @@ class U_I18N_API LocalizedNumberRangeFormatter
/**
* Default constructor: puts the formatter into a valid but undefined state.
*
- * @draft ICU 63
+ * @stable ICU 63
*/
LocalizedNumberRangeFormatter() = default;
/**
* Returns a copy of this LocalizedNumberRangeFormatter.
- * @draft ICU 63
+ * @stable ICU 63
*/
LocalizedNumberRangeFormatter(const LocalizedNumberRangeFormatter &other);
/**
* Move constructor:
* The source LocalizedNumberRangeFormatter will be left in a valid but undefined state.
- * @draft ICU 63
+ * @stable ICU 63
*/
LocalizedNumberRangeFormatter(LocalizedNumberRangeFormatter&& src) U_NOEXCEPT;
/**
* Copy assignment operator.
- * @draft ICU 63
+ * @stable ICU 63
*/
LocalizedNumberRangeFormatter& operator=(const LocalizedNumberRangeFormatter& other);
/**
* Move assignment operator:
* The source LocalizedNumberRangeFormatter will be left in a valid but undefined state.
- * @draft ICU 63
+ * @stable ICU 63
*/
LocalizedNumberRangeFormatter& operator=(LocalizedNumberRangeFormatter&& src) U_NOEXCEPT;
@@ -651,11 +656,11 @@ class U_I18N_API LocalizedNumberRangeFormatter
void formatImpl(impl::UFormattedNumberRangeData& results, bool equalBeforeRounding,
UErrorCode& status) const;
-#endif
+#endif /* U_HIDE_INTERNAL_API */
/**
* Destruct this LocalizedNumberRangeFormatter, cleaning up any memory it might own.
- * @draft ICU 63
+ * @stable ICU 63
*/
~LocalizedNumberRangeFormatter();
@@ -690,7 +695,7 @@ class U_I18N_API LocalizedNumberRangeFormatter
*
* Instances of this class are immutable and thread-safe.
*
- * @draft ICU 63
+ * @stable ICU 63
*/
class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue {
public:
@@ -700,7 +705,7 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue {
*
* For more information, see FormattedValue::toString()
*
- * @draft ICU 63
+ * @stable ICU 63
*/
UnicodeString toString(UErrorCode& status) const U_OVERRIDE;
@@ -714,7 +719,7 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue {
*
* For more information, see FormattedValue::appendTo()
*
- * @draft ICU 63
+ * @stable ICU 63
*/
Appendable &appendTo(Appendable &appendable, UErrorCode& status) const U_OVERRIDE;
@@ -722,6 +727,7 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue {
/** @copydoc FormattedValue::nextPosition() */
UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const U_OVERRIDE;
+#ifndef U_HIDE_DRAFT_API
/**
* Determines the start (inclusive) and end (exclusive) indices of the next occurrence of the given
* <em>field</em> in the output string. This allows you to determine the locations of, for example,
@@ -799,6 +805,7 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue {
* @see #getFirstDecimal
*/
UnicodeString getSecondDecimal(UErrorCode& status) const;
+#endif // U_HIDE_DRAFT_API
/**
* Returns whether the pair of numbers was successfully formatted as a range or whether an identity fallback was
@@ -806,7 +813,7 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue {
* identity fallback was used.
*
* @return An indication the resulting identity situation in the formatted number range.
- * @draft ICU 63
+ * @stable ICU 63
* @see UNumberRangeIdentityFallback
*/
UNumberRangeIdentityResult getIdentityResult(UErrorCode& status) const;
@@ -824,20 +831,20 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue {
/**
* Move constructor:
* Leaves the source FormattedNumberRange in an undefined state.
- * @draft ICU 63
+ * @stable ICU 63
*/
FormattedNumberRange(FormattedNumberRange&& src) U_NOEXCEPT;
/**
* Move assignment:
* Leaves the source FormattedNumberRange in an undefined state.
- * @draft ICU 63
+ * @stable ICU 63
*/
FormattedNumberRange& operator=(FormattedNumberRange&& src) U_NOEXCEPT;
/**
* Destruct an instance of FormattedNumberRange, cleaning up any memory it might own.
- * @draft ICU 63
+ * @stable ICU 63
*/
~FormattedNumberRange();
@@ -850,7 +857,6 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue {
/**
* Internal constructor from data type. Adopts the data pointer.
- * @internal
*/
explicit FormattedNumberRange(impl::UFormattedNumberRangeData *results)
: fData(results), fErrorCode(U_ZERO_ERROR) {}
@@ -867,7 +873,7 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue {
/**
* See the main description in numberrangeformatter.h for documentation and examples.
*
- * @draft ICU 63
+ * @stable ICU 63
*/
class U_I18N_API NumberRangeFormatter final {
public:
@@ -876,7 +882,7 @@ class U_I18N_API NumberRangeFormatter final {
* known at the call site.
*
* @return An {@link UnlocalizedNumberRangeFormatter}, to be used for chaining.
- * @draft ICU 63
+ * @stable ICU 63
*/
static UnlocalizedNumberRangeFormatter with();
@@ -887,7 +893,7 @@ class U_I18N_API NumberRangeFormatter final {
* @param locale
* The locale from which to load formats and symbols for number range formatting.
* @return A {@link LocalizedNumberRangeFormatter}, to be used for chaining.
- * @draft ICU 63
+ * @stable ICU 63
*/
static LocalizedNumberRangeFormatter withLocale(const Locale &locale);
@@ -900,8 +906,9 @@ class U_I18N_API NumberRangeFormatter final {
} // namespace number
U_NAMESPACE_END
-#endif // U_HIDE_DRAFT_API
+#endif /* #if !UCONFIG_NO_FORMATTING */
+
+#endif /* U_SHOW_CPLUSPLUS_API */
#endif // __NUMBERRANGEFORMATTER_H__
-#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/deps/icu-small/source/i18n/unicode/numfmt.h b/deps/icu-small/source/i18n/unicode/numfmt.h
index d8704754dc..fbd4fb4e56 100644
--- a/deps/icu-small/source/i18n/unicode/numfmt.h
+++ b/deps/icu-small/source/i18n/unicode/numfmt.h
@@ -26,6 +26,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Compatibility APIs for number formatting.
@@ -261,6 +263,14 @@ public:
virtual ~NumberFormat();
/**
+ * Clones this object polymorphically.
+ * The caller owns the result and should delete it when done.
+ * @return clone, or nullptr if an error occurred
+ * @stable ICU 2.0
+ */
+ virtual NumberFormat* clone() const = 0;
+
+ /**
* Return true if the given Format objects are semantically equal.
* Objects of different subclasses are considered unequal.
* @return true if the given Format objects are semantically equal.
@@ -639,7 +649,9 @@ public:
* @param result Formattable to be set to the parse result.
* If parse fails, return contents are undefined.
* @param status Output parameter set to a failure error code
- * when a failure occurs.
+ * when a failure occurs. The error code when the
+ * string fails to parse is U_INVALID_FORMAT_ERROR,
+ * unless overridden by a subclass.
* @see NumberFormat::isParseIntegerOnly
* @stable ICU 2.0
*/
@@ -1255,5 +1267,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _NUMFMT
//eof
diff --git a/deps/icu-small/source/i18n/unicode/numsys.h b/deps/icu-small/source/i18n/unicode/numsys.h
index 9e32478cf8..4fb7f044ed 100644
--- a/deps/icu-small/source/i18n/unicode/numsys.h
+++ b/deps/icu-small/source/i18n/unicode/numsys.h
@@ -20,6 +20,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: NumberingSystem object
@@ -210,5 +212,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _NUMSYS
//eof
diff --git a/deps/icu-small/source/i18n/unicode/plurfmt.h b/deps/icu-small/source/i18n/unicode/plurfmt.h
index 6b757c8841..7373476dca 100644
--- a/deps/icu-small/source/i18n/unicode/plurfmt.h
+++ b/deps/icu-small/source/i18n/unicode/plurfmt.h
@@ -16,6 +16,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: PluralFormat object
@@ -448,7 +450,7 @@ public:
* result and should delete it when done.
* @stable ICU 4.0
*/
- virtual Format* clone(void) const;
+ virtual PluralFormat* clone() const;
/**
* Formats a plural message for a number taken from a Formattable object.
@@ -522,7 +524,7 @@ public:
private:
/**
- * @internal
+ * @internal (private)
*/
class U_I18N_API PluralSelector : public UMemory {
public:
@@ -534,14 +536,11 @@ private:
* @param number The number to be plural-formatted.
* @param ec Error code.
* @return The selected PluralFormat keyword.
- * @internal
+ * @internal (private)
*/
virtual UnicodeString select(void *context, double number, UErrorCode& ec) const = 0;
};
- /**
- * @internal
- */
class U_I18N_API PluralSelectorAdapter : public PluralSelector {
public:
PluralSelectorAdapter() : pluralRules(NULL) {
@@ -549,7 +548,7 @@ private:
virtual ~PluralSelectorAdapter();
- virtual UnicodeString select(void *context, double number, UErrorCode& /*ec*/) const; /**< @internal */
+ virtual UnicodeString select(void *context, double number, UErrorCode& /*ec*/) const;
void reset();
@@ -573,7 +572,7 @@ private:
UnicodeString& format(const Formattable& numberObject, double number,
UnicodeString& appendTo,
FieldPosition& pos,
- UErrorCode& status) const; /**< @internal */
+ UErrorCode& status) const;
/**
* Finds the PluralFormat sub-message for the given number, or the "other" sub-message.
@@ -601,5 +600,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _PLURFMT
//eof
diff --git a/deps/icu-small/source/i18n/unicode/plurrule.h b/deps/icu-small/source/i18n/unicode/plurrule.h
index 04bf3970ba..a1553567ca 100644
--- a/deps/icu-small/source/i18n/unicode/plurrule.h
+++ b/deps/icu-small/source/i18n/unicode/plurrule.h
@@ -20,6 +20,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: PluralRules object
@@ -533,5 +535,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _PLURRULE
//eof
diff --git a/deps/icu-small/source/i18n/unicode/rbnf.h b/deps/icu-small/source/i18n/unicode/rbnf.h
index f7cd85a322..1144bd2fb8 100644
--- a/deps/icu-small/source/i18n/unicode/rbnf.h
+++ b/deps/icu-small/source/i18n/unicode/rbnf.h
@@ -12,6 +12,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Rule Based Number Format
@@ -696,7 +698,7 @@ public:
* @return A copy of the object.
* @stable ICU 2.6
*/
- virtual Format* clone(void) const;
+ virtual RuleBasedNumberFormat* clone() const;
/**
* Return true if the given Format objects are semantically equal.
@@ -877,28 +879,6 @@ protected:
* @param number The number, a DigitList format Decimal Floating Point.
* @param appendTo Output parameter to receive result.
* Result is appended to existing contents.
- * @param posIter On return, can be used to iterate over positions
- * of fields generated by this format call.
- * @param status Output param filled with success/failure status.
- * @return Reference to 'appendTo' parameter.
- * @internal
- */
- virtual UnicodeString& format(const number::impl::DecimalQuantity &number,
- UnicodeString& appendTo,
- FieldPositionIterator* posIter,
- UErrorCode& status) const;
-
- /**
- * Format a decimal number.
- * The number is a DigitList wrapper onto a floating point decimal number.
- * The default implementation in NumberFormat converts the decimal number
- * to a double and formats that. Subclasses of NumberFormat that want
- * to specifically handle big decimal numbers must override this method.
- * class DecimalFormat does so.
- *
- * @param number The number, a DigitList format Decimal Floating Point.
- * @param appendTo Output parameter to receive result.
- * Result is appended to existing contents.
* @param pos On input: an alignment field, if desired.
* On output: the offsets of the alignment field.
* @param status Output param filled with success/failure status.
@@ -1135,5 +1115,7 @@ U_NAMESPACE_END
/* U_HAVE_RBNF */
#endif
+#endif /* U_SHOW_CPLUSPLUS_API */
+
/* RBNF_H */
#endif
diff --git a/deps/icu-small/source/i18n/unicode/rbtz.h b/deps/icu-small/source/i18n/unicode/rbtz.h
index 542a7c140c..95fd7ab85d 100644
--- a/deps/icu-small/source/i18n/unicode/rbtz.h
+++ b/deps/icu-small/source/i18n/unicode/rbtz.h
@@ -11,6 +11,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Rule based customizable time zone
@@ -121,7 +123,7 @@ public:
* @return A new copy of this TimeZone object.
* @stable ICU 3.8
*/
- virtual TimeZone* clone(void) const;
+ virtual RuleBasedTimeZone* clone() const;
/**
* Returns the TimeZone's adjusted GMT offset (i.e., the number of milliseconds to add
@@ -224,6 +226,7 @@ public:
*/
virtual UBool useDaylightTime(void) const;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Queries if the given date is in daylight savings time in
* this time zone.
@@ -238,6 +241,7 @@ public:
* @deprecated ICU 2.4. Use Calendar::inDaylightTime() instead.
*/
virtual UBool inDaylightTime(UDate date, UErrorCode& status) const;
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Returns true if this zone has the same rule and offset as another zone.
@@ -359,6 +363,8 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // RBTZ_H
//eof
diff --git a/deps/icu-small/source/i18n/unicode/regex.h b/deps/icu-small/source/i18n/unicode/regex.h
index a0f9839fe7..75048af06c 100644
--- a/deps/icu-small/source/i18n/unicode/regex.h
+++ b/deps/icu-small/source/i18n/unicode/regex.h
@@ -44,6 +44,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_REGULAR_EXPRESSIONS
#include "unicode/uobject.h"
@@ -1876,4 +1878,7 @@ private:
U_NAMESPACE_END
#endif // UCONFIG_NO_REGULAR_EXPRESSIONS
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/i18n/unicode/region.h b/deps/icu-small/source/i18n/unicode/region.h
index ccd63901a5..66f5f92075 100644
--- a/deps/icu-small/source/i18n/unicode/region.h
+++ b/deps/icu-small/source/i18n/unicode/region.h
@@ -16,10 +16,12 @@
*/
#include "unicode/utypes.h"
-#include "unicode/uregion.h"
+
+#if U_SHOW_CPLUSPLUS_API
#if !UCONFIG_NO_FORMATTING
+#include "unicode/uregion.h"
#include "unicode/uobject.h"
#include "unicode/uniset.h"
#include "unicode/unistr.h"
@@ -219,6 +221,9 @@ private:
U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // REGION_H
//eof
diff --git a/deps/icu-small/source/i18n/unicode/reldatefmt.h b/deps/icu-small/source/i18n/unicode/reldatefmt.h
index cfcba09026..fb691a5451 100644
--- a/deps/icu-small/source/i18n/unicode/reldatefmt.h
+++ b/deps/icu-small/source/i18n/unicode/reldatefmt.h
@@ -15,6 +15,9 @@
#define __RELDATEFMT_H
#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/uobject.h"
#include "unicode/udisplaycontext.h"
#include "unicode/ureldatefmt.h"
@@ -166,12 +169,24 @@ typedef enum UDateAbsoluteUnit {
*/
UDAT_ABSOLUTE_NOW,
-#ifndef U_HIDE_DRAFT_API
/**
* Quarter
- * @draft ICU 63
+ * @stable ICU 63
*/
UDAT_ABSOLUTE_QUARTER,
+
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Hour
+ * @draft ICU 65
+ */
+ UDAT_ABSOLUTE_HOUR,
+
+ /**
+ * Minute
+ * @draft ICU 65
+ */
+ UDAT_ABSOLUTE_MINUTE,
#endif // U_HIDE_DRAFT_API
#ifndef U_HIDE_DEPRECATED_API
@@ -179,7 +194,7 @@ typedef enum UDateAbsoluteUnit {
* One more than the highest normal UDateAbsoluteUnit value.
* @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
*/
- UDAT_ABSOLUTE_UNIT_COUNT = UDAT_ABSOLUTE_NOW + 2
+ UDAT_ABSOLUTE_UNIT_COUNT = UDAT_ABSOLUTE_NOW + 4
#endif // U_HIDE_DEPRECATED_API
} UDateAbsoluteUnit;
@@ -246,6 +261,7 @@ class SharedPluralRules;
class SharedBreakIterator;
class NumberFormat;
class UnicodeString;
+class FormattedRelativeDateTime;
class FormattedRelativeDateTimeData;
#ifndef U_HIDE_DRAFT_API
@@ -743,4 +759,7 @@ U_NAMESPACE_END
#endif /* !UCONFIG_NO_BREAK_ITERATION */
#endif /* !UCONFIG_NO_FORMATTING */
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif /* __RELDATEFMT_H */
diff --git a/deps/icu-small/source/i18n/unicode/scientificnumberformatter.h b/deps/icu-small/source/i18n/unicode/scientificnumberformatter.h
index 6c99a24662..a56b8ca268 100644
--- a/deps/icu-small/source/i18n/unicode/scientificnumberformatter.h
+++ b/deps/icu-small/source/i18n/unicode/scientificnumberformatter.h
@@ -11,6 +11,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
@@ -157,7 +159,7 @@ public:
class U_I18N_API SuperscriptStyle : public Style {
public:
- virtual Style *clone() const;
+ virtual SuperscriptStyle *clone() const;
protected:
virtual UnicodeString &format(
const UnicodeString &original,
@@ -175,7 +177,7 @@ public:
: Style(),
fBeginMarkup(beginMarkup),
fEndMarkup(endMarkup) { }
- virtual Style *clone() const;
+ virtual MarkupStyle *clone() const;
protected:
virtual UnicodeString &format(
const UnicodeString &original,
@@ -214,4 +216,7 @@ U_NAMESPACE_END
#endif /* !UCONFIG_NO_FORMATTING */
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/i18n/unicode/search.h b/deps/icu-small/source/i18n/unicode/search.h
index 12dd5c7727..986205c62f 100644
--- a/deps/icu-small/source/i18n/unicode/search.h
+++ b/deps/icu-small/source/i18n/unicode/search.h
@@ -14,6 +14,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: SearchIterator object.
@@ -70,8 +72,7 @@ U_NAMESPACE_BEGIN
* UErrorCode error = U_ZERO_ERROR;
* for (int pos = iter->first(error); pos != USEARCH_DONE;
* pos = iter->next(error)) {
- * printf("Found match at %d pos, length is %d\n", pos,
- * iter.getMatchLength());
+ * printf("Found match at %d pos, length is %d\n", pos, iter.getMatchedLength());
* }
* </code></pre>
*
@@ -573,4 +574,6 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_COLLATION */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/i18n/unicode/selfmt.h b/deps/icu-small/source/i18n/unicode/selfmt.h
index 08e9d444ee..9b98f6db7a 100755
--- a/deps/icu-small/source/i18n/unicode/selfmt.h
+++ b/deps/icu-small/source/i18n/unicode/selfmt.h
@@ -18,9 +18,12 @@
#ifndef SELFMT
#define SELFMT
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
#include "unicode/messagepattern.h"
#include "unicode/numfmt.h"
-#include "unicode/utypes.h"
/**
* \file
@@ -272,7 +275,7 @@ public:
* result and should delete it when done.
* @stable ICU 4.4
*/
- virtual Format* clone(void) const;
+ virtual SelectFormat* clone() const;
/**
* Format an object to produce a string.
@@ -365,5 +368,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _SELFMT
//eof
diff --git a/deps/icu-small/source/i18n/unicode/simpletz.h b/deps/icu-small/source/i18n/unicode/simpletz.h
index 7f5f1664cc..d7d4123187 100644
--- a/deps/icu-small/source/i18n/unicode/simpletz.h
+++ b/deps/icu-small/source/i18n/unicode/simpletz.h
@@ -28,6 +28,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: SimpleTimeZone is a concrete subclass of TimeZone.
@@ -672,6 +674,7 @@ public:
*/
virtual UBool useDaylightTime(void) const;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Returns true if the given date is within the period when daylight savings time
* is in effect; false otherwise. If the TimeZone doesn't observe daylight savings
@@ -687,6 +690,7 @@ public:
* @deprecated ICU 2.4. Use Calendar::inDaylightTime() instead.
*/
virtual UBool inDaylightTime(UDate date, UErrorCode& status) const;
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Return true if this zone has the same rules and offset as another zone.
@@ -703,7 +707,7 @@ public:
* @return A new copy of this TimeZone object.
* @stable ICU 2.0
*/
- virtual TimeZone* clone(void) const;
+ virtual SimpleTimeZone* clone() const;
/**
* Gets the first time zone transition after the base time.
@@ -929,4 +933,6 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _SIMPLETZ
diff --git a/deps/icu-small/source/i18n/unicode/smpdtfmt.h b/deps/icu-small/source/i18n/unicode/smpdtfmt.h
index a015c5be5c..79fa817d5a 100644
--- a/deps/icu-small/source/i18n/unicode/smpdtfmt.h
+++ b/deps/icu-small/source/i18n/unicode/smpdtfmt.h
@@ -28,6 +28,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Format and parse dates in a language-independent manner.
@@ -865,7 +867,7 @@ public:
* @return A copy of the object.
* @stable ICU 2.0
*/
- virtual Format* clone(void) const;
+ virtual SimpleDateFormat* clone() const;
/**
* Return true if the given Format objects are semantically equal. Objects
@@ -1643,7 +1645,7 @@ private:
UBool fHaveDefaultCentury;
- BreakIterator* fCapitalizationBrkIter;
+ const BreakIterator* fCapitalizationBrkIter;
};
inline UDate
@@ -1656,5 +1658,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // _SMPDTFMT
//eof
diff --git a/deps/icu-small/source/i18n/unicode/sortkey.h b/deps/icu-small/source/i18n/unicode/sortkey.h
index 6895be7a2b..d2d3ca9fd5 100644
--- a/deps/icu-small/source/i18n/unicode/sortkey.h
+++ b/deps/icu-small/source/i18n/unicode/sortkey.h
@@ -25,6 +25,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Keys for comparing strings multiple times.
@@ -337,4 +339,6 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_COLLATION */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/i18n/unicode/stsearch.h b/deps/icu-small/source/i18n/unicode/stsearch.h
index 46bc51b30e..f396371143 100644
--- a/deps/icu-small/source/i18n/unicode/stsearch.h
+++ b/deps/icu-small/source/i18n/unicode/stsearch.h
@@ -14,6 +14,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Service for searching text based on RuleBasedCollator.
@@ -119,8 +121,7 @@ U_NAMESPACE_BEGIN
* pos != USEARCH_DONE;
* pos = iter.next(error))
* {
- * printf("Found match at %d pos, length is %d\n", pos,
- * iter.getMatchLength());
+ * printf("Found match at %d pos, length is %d\n", pos, iter.getMatchedLength());
* }
* </code></pre>
* <p>
@@ -412,7 +413,7 @@ public:
* @return cloned object
* @stable ICU 2.0
*/
- virtual SearchIterator * safeClone(void) const;
+ virtual StringSearch * safeClone() const;
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
@@ -502,4 +503,6 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_COLLATION */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/i18n/unicode/tblcoll.h b/deps/icu-small/source/i18n/unicode/tblcoll.h
index 24ba213b41..f5dc135bc4 100644
--- a/deps/icu-small/source/i18n/unicode/tblcoll.h
+++ b/deps/icu-small/source/i18n/unicode/tblcoll.h
@@ -64,6 +64,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_COLLATION
#include "unicode/coll.h"
@@ -228,7 +230,7 @@ public:
* @return a copy of this object, owned by the caller
* @stable ICU 2.0
*/
- virtual Collator* clone(void) const;
+ virtual RuleBasedCollator* clone() const;
/**
* Creates a collation element iterator for the source string. The caller of
@@ -389,6 +391,7 @@ public:
*/
virtual int32_t hashCode() const;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Gets the locale of the Collator
* @param type can be either requested, valid or actual locale. For more
@@ -400,6 +403,7 @@ public:
* @deprecated ICU 2.8 likely to change in ICU 3.0, based on feedback
*/
virtual Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const;
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Gets the tailoring rules for this collator.
@@ -545,6 +549,7 @@ public:
*/
virtual UColReorderCode getMaxVariable() const;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Sets the variable top to the primary weight of the specified string.
*
@@ -592,6 +597,7 @@ public:
* @deprecated ICU 53 Call setMaxVariable() instead.
*/
virtual void setVariableTop(uint32_t varTop, UErrorCode &status);
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Gets the variable top value of a Collator.
@@ -874,4 +880,7 @@ private:
U_NAMESPACE_END
#endif // !UCONFIG_NO_COLLATION
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // TBLCOLL_H
diff --git a/deps/icu-small/source/i18n/unicode/timezone.h b/deps/icu-small/source/i18n/unicode/timezone.h
index 237ed911d0..4d321186be 100644
--- a/deps/icu-small/source/i18n/unicode/timezone.h
+++ b/deps/icu-small/source/i18n/unicode/timezone.h
@@ -31,6 +31,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: TimeZone object
@@ -321,10 +323,6 @@ public:
* zone is set to the default host time zone. This call adopts the TimeZone object
* passed in; the client is no longer responsible for deleting it.
*
- * <p>This function is not thread safe. It is an error for multiple threads
- * to concurrently attempt to set the default time zone, or for any thread
- * to attempt to reference the default zone while another thread is setting it.
- *
* @param zone A pointer to the new TimeZone object to use as the default.
* @stable ICU 2.0
*/
@@ -335,8 +333,6 @@ public:
* Same as adoptDefault(), except that the TimeZone object passed in is NOT adopted;
* the caller remains responsible for deleting it.
*
- * <p>See the thread safety note under adoptDefault().
- *
* @param zone The given timezone.
* @system
* @stable ICU 2.0
@@ -726,6 +722,7 @@ public:
*/
virtual UBool useDaylightTime(void) const = 0;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Queries if the given date is in daylight savings time in
* this time zone.
@@ -740,6 +737,7 @@ public:
* @deprecated ICU 2.4. Use Calendar::inDaylightTime() instead.
*/
virtual UBool inDaylightTime(UDate date, UErrorCode& status) const = 0;
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Returns true if this zone has the same rule and offset as another zone.
@@ -758,7 +756,7 @@ public:
* @return A new copy of this TimeZone object.
* @stable ICU 2.0
*/
- virtual TimeZone* clone(void) const = 0;
+ virtual TimeZone* clone() const = 0;
/**
* Return the class ID for this class. This is useful only for
@@ -972,5 +970,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif //_TIMEZONE
//eof
diff --git a/deps/icu-small/source/i18n/unicode/tmunit.h b/deps/icu-small/source/i18n/unicode/tmunit.h
index fa59f10473..2e949ddfbd 100644
--- a/deps/icu-small/source/i18n/unicode/tmunit.h
+++ b/deps/icu-small/source/i18n/unicode/tmunit.h
@@ -16,6 +16,9 @@
* \brief C++ API: time unit object
*/
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
#include "unicode/measunit.h"
@@ -70,7 +73,7 @@ public:
* Override clone.
* @stable ICU 4.2
*/
- virtual UObject* clone() const;
+ virtual TimeUnit* clone() const;
/**
* Copy operator.
@@ -132,6 +135,8 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __TMUNIT_H__
//eof
//
diff --git a/deps/icu-small/source/i18n/unicode/tmutamt.h b/deps/icu-small/source/i18n/unicode/tmutamt.h
index 1717b7605f..5ce5922cea 100644
--- a/deps/icu-small/source/i18n/unicode/tmutamt.h
+++ b/deps/icu-small/source/i18n/unicode/tmutamt.h
@@ -16,11 +16,15 @@
* \brief C++ API: time unit amount object.
*/
-#include "unicode/measure.h"
-#include "unicode/tmunit.h"
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
#if !UCONFIG_NO_FORMATTING
+#include "unicode/measure.h"
+#include "unicode/tmunit.h"
+
U_NAMESPACE_BEGIN
@@ -83,7 +87,7 @@ public:
* @return a polymorphic clone of this object. The result will have the same class as returned by getDynamicClassID().
* @stable ICU 4.2
*/
- virtual UObject* clone() const;
+ virtual TimeUnitAmount* clone() const;
/**
@@ -165,6 +169,8 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __TMUTAMT_H__
//eof
//
diff --git a/deps/icu-small/source/i18n/unicode/tmutfmt.h b/deps/icu-small/source/i18n/unicode/tmutfmt.h
index 8f245859a6..ad871f7c09 100644
--- a/deps/icu-small/source/i18n/unicode/tmutfmt.h
+++ b/deps/icu-small/source/i18n/unicode/tmutfmt.h
@@ -18,8 +18,9 @@
*/
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
-#ifndef U_HIDE_DEPRECATED_API
#include "unicode/unistr.h"
#include "unicode/tmunit.h"
@@ -28,6 +29,7 @@
#include "unicode/numfmt.h"
#include "unicode/plurrule.h"
+#ifndef U_HIDE_DEPRECATED_API
/**
* Constants for various styles.
@@ -124,7 +126,7 @@ public:
* @return A copy of the object.
* @deprecated ICU 53
*/
- virtual Format* clone(void) const;
+ virtual TimeUnitFormat* clone() const;
/**
* Assignment operator
@@ -244,5 +246,7 @@ U_NAMESPACE_END
#endif /* U_HIDE_DEPRECATED_API */
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // __TMUTFMT_H__
//eof
diff --git a/deps/icu-small/source/i18n/unicode/translit.h b/deps/icu-small/source/i18n/unicode/translit.h
index 6b4888145f..fe2568d50a 100644
--- a/deps/icu-small/source/i18n/unicode/translit.h
+++ b/deps/icu-small/source/i18n/unicode/translit.h
@@ -14,6 +14,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: Tranforms text from one format to another.
@@ -1588,4 +1590,6 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_TRANSLITERATION */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/i18n/unicode/tzfmt.h b/deps/icu-small/source/i18n/unicode/tzfmt.h
index d2aa768b8c..6d3863b1e5 100644
--- a/deps/icu-small/source/i18n/unicode/tzfmt.h
+++ b/deps/icu-small/source/i18n/unicode/tzfmt.h
@@ -16,6 +16,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
#include "unicode/format.h"
@@ -305,7 +307,7 @@ public:
* @return A copy of the object
* @stable ICU 50
*/
- virtual Format* clone() const;
+ virtual TimeZoneFormat* clone() const;
/**
* Creates an instance of <code>TimeZoneFormat</code> for the given locale.
@@ -1094,4 +1096,7 @@ private:
U_NAMESPACE_END
#endif /* !UCONFIG_NO_FORMATTING */
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/i18n/unicode/tznames.h b/deps/icu-small/source/i18n/unicode/tznames.h
index 399265d85a..860494221d 100644
--- a/deps/icu-small/source/i18n/unicode/tznames.h
+++ b/deps/icu-small/source/i18n/unicode/tznames.h
@@ -15,6 +15,8 @@
*/
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
#include "unicode/uloc.h"
@@ -411,4 +413,7 @@ public:
U_NAMESPACE_END
#endif
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/i18n/unicode/tzrule.h b/deps/icu-small/source/i18n/unicode/tzrule.h
index 171486f1c7..c6d6b9631f 100644
--- a/deps/icu-small/source/i18n/unicode/tzrule.h
+++ b/deps/icu-small/source/i18n/unicode/tzrule.h
@@ -16,6 +16,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
#include "unicode/uobject.h"
@@ -45,7 +47,7 @@ public:
* @return A copy of the object.
* @stable ICU 3.8
*/
- virtual TimeZoneRule* clone(void) const = 0;
+ virtual TimeZoneRule* clone() const = 0;
/**
* Return true if the given <code>TimeZoneRule</code> objects are semantically equal. Objects
@@ -229,7 +231,7 @@ public:
* @return A copy of the object.
* @stable ICU 3.8
*/
- virtual InitialTimeZoneRule* clone(void) const;
+ virtual InitialTimeZoneRule* clone() const;
/**
* Assignment operator.
@@ -440,7 +442,7 @@ public:
* @return A copy of the object.
* @stable ICU 3.8
*/
- virtual AnnualTimeZoneRule* clone(void) const;
+ virtual AnnualTimeZoneRule* clone() const;
/**
* Assignment operator.
@@ -656,7 +658,7 @@ public:
* @return A copy of the object.
* @stable ICU 3.8
*/
- virtual TimeArrayTimeZoneRule* clone(void) const;
+ virtual TimeArrayTimeZoneRule* clone() const;
/**
* Assignment operator.
@@ -825,6 +827,8 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // TZRULE_H
//eof
diff --git a/deps/icu-small/source/i18n/unicode/tztrans.h b/deps/icu-small/source/i18n/unicode/tztrans.h
index 1276d67c31..e87fea7c3c 100644
--- a/deps/icu-small/source/i18n/unicode/tztrans.h
+++ b/deps/icu-small/source/i18n/unicode/tztrans.h
@@ -16,6 +16,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
#if !UCONFIG_NO_FORMATTING
#include "unicode/uobject.h"
@@ -68,7 +70,7 @@ public:
* @return A copy of the object.
* @stable ICU 3.8
*/
- TimeZoneTransition* clone(void) const;
+ TimeZoneTransition* clone() const;
/**
* Assignment operator.
@@ -192,6 +194,8 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // TZTRANS_H
//eof
diff --git a/deps/icu-small/source/i18n/unicode/ucal.h b/deps/icu-small/source/i18n/unicode/ucal.h
index 71120b7aed..eee2ae9e22 100644
--- a/deps/icu-small/source/i18n/unicode/ucal.h
+++ b/deps/icu-small/source/i18n/unicode/ucal.h
@@ -441,11 +441,13 @@ enum UCalendarDateFields {
/* Do not conditionalize the following with #ifndef U_HIDE_DEPRECATED_API,
* it is needed for layout of Calendar, DateFormat, and other objects */
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* One more than the highest normal UCalendarDateFields value.
* @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
*/
- UCAL_FIELD_COUNT,
+ UCAL_FIELD_COUNT,
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Field number indicating the
@@ -657,6 +659,42 @@ ucal_getDefaultTimeZone(UChar* result, int32_t resultCapacity, UErrorCode* ec);
U_STABLE void U_EXPORT2
ucal_setDefaultTimeZone(const UChar* zoneID, UErrorCode* ec);
+#ifndef U_HIDE_DRAFT_API
+
+/**
+ * Return the current host time zone. The host time zone is detected from
+ * the current host system configuration by querying the host operating
+ * system. If the host system detection routines fail, or if they specify
+ * a TimeZone or TimeZone offset which is not recognized, then the special
+ * TimeZone "Etc/Unknown" is returned.
+ *
+ * Note that host time zone and the ICU default time zone can be different.
+ *
+ * The ICU default time zone does not change once initialized unless modified
+ * by calling `ucal_setDefaultTimeZone()` or with the C++ TimeZone API,
+ * `TimeZone::adoptDefault(TimeZone*)`.
+ *
+ * If the host operating system configuration has changed since ICU has
+ * initialized then the returned value can be different than the ICU default
+ * time zone, even if the default has not changed.
+ *
+ * <p>This function is not thread safe.</p>
+ *
+ * @param result A buffer to receive the result, or NULL
+ * @param resultCapacity The capacity of the result buffer
+ * @param ec input/output error code
+ * @return The result string length, not including the terminating
+ * null
+ *
+ * @see #UCAL_UNKNOWN_ZONE_ID
+ *
+ * @draft ICU 65
+ */
+U_DRAFT int32_t U_EXPORT2
+ucal_getHostTimeZone(UChar *result, int32_t resultCapacity, UErrorCode *ec);
+
+#endif // U_HIDE_DRAFT_API
+
/**
* Return the amount of time in milliseconds that the clock is
* advanced during daylight savings time for the given time zone, or
diff --git a/deps/icu-small/source/i18n/unicode/ucol.h b/deps/icu-small/source/i18n/unicode/ucol.h
index f084ac61e6..34b5d2476a 100644
--- a/deps/icu-small/source/i18n/unicode/ucol.h
+++ b/deps/icu-small/source/i18n/unicode/ucol.h
@@ -344,11 +344,13 @@ typedef enum {
/* Do not conditionalize the following with #ifndef U_HIDE_DEPRECATED_API,
* it is needed for layout of RuleBasedCollator object. */
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* One more than the highest normal UColAttribute value.
* @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
*/
UCOL_ATTRIBUTE_COUNT
+#endif // U_FORCE_HIDE_DEPRECATED_API
} UColAttribute;
/** Options for retrieving the rule string
diff --git a/deps/icu-small/source/i18n/unicode/udat.h b/deps/icu-small/source/i18n/unicode/udat.h
index c67a6d6d4b..bdbd080c00 100644
--- a/deps/icu-small/source/i18n/unicode/udat.h
+++ b/deps/icu-small/source/i18n/unicode/udat.h
@@ -923,11 +923,13 @@ typedef enum UDateFormatBooleanAttribute {
/* Do not conditionalize the following with #ifndef U_HIDE_DEPRECATED_API,
* it is needed for layout of DateFormat object. */
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* One more than the highest normal UDateFormatBooleanAttribute value.
* @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
*/
UDAT_BOOLEAN_ATTRIBUTE_COUNT = 4
+#endif // U_FORCE_HIDE_DEPRECATED_API
} UDateFormatBooleanAttribute;
/**
diff --git a/deps/icu-small/source/i18n/unicode/udatpg.h b/deps/icu-small/source/i18n/unicode/udatpg.h
index 238a27b4f4..81956d1270 100644
--- a/deps/icu-small/source/i18n/unicode/udatpg.h
+++ b/deps/icu-small/source/i18n/unicode/udatpg.h
@@ -88,11 +88,13 @@ typedef enum UDateTimePatternField {
/* Do not conditionalize the following with #ifndef U_HIDE_DEPRECATED_API,
* it is needed for layout of DateTimePatternGenerator object. */
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* One more than the highest normal UDateTimePatternField value.
* @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
*/
UDATPG_FIELD_COUNT
+#endif // U_FORCE_HIDE_DEPRECATED_API
} UDateTimePatternField;
/**
diff --git a/deps/icu-small/source/i18n/unicode/uformattedvalue.h b/deps/icu-small/source/i18n/unicode/uformattedvalue.h
index d1c2ad1e49..172558f7fb 100644
--- a/deps/icu-small/source/i18n/unicode/uformattedvalue.h
+++ b/deps/icu-small/source/i18n/unicode/uformattedvalue.h
@@ -7,10 +7,11 @@
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
-#ifndef U_HIDE_DRAFT_API
#include "unicode/ufieldpositer.h"
+#ifndef U_HIDE_DRAFT_API
+
/**
* \file
* \brief C API: Abstract operations for localized strings.
diff --git a/deps/icu-small/source/i18n/unicode/ulistformatter.h b/deps/icu-small/source/i18n/unicode/ulistformatter.h
index 4327fd5ec1..0fbf72c9ff 100644
--- a/deps/icu-small/source/i18n/unicode/ulistformatter.h
+++ b/deps/icu-small/source/i18n/unicode/ulistformatter.h
@@ -41,7 +41,7 @@ struct UFormattedList;
* @draft ICU 64
*/
typedef struct UFormattedList UFormattedList;
-#endif /* U_HIDE_DRAFT_API */
+#endif /* U_HIDE_DRAFT_API */
#ifndef U_HIDE_DRAFT_API
/**
@@ -61,7 +61,7 @@ typedef enum UListFormatterField {
*/
ULISTFMT_ELEMENT_FIELD
} UListFormatterField;
-#endif // U_HIDE_DRAFT_API
+#endif /* U_HIDE_DRAFT_API */
/**
* Open a new UListFormatter object using the rules for a given locale.
diff --git a/deps/icu-small/source/i18n/unicode/unirepl.h b/deps/icu-small/source/i18n/unicode/unirepl.h
index 8fb25d4689..61ee37f070 100644
--- a/deps/icu-small/source/i18n/unicode/unirepl.h
+++ b/deps/icu-small/source/i18n/unicode/unirepl.h
@@ -14,6 +14,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: UnicodeReplacer
@@ -96,4 +98,6 @@ class U_I18N_API UnicodeReplacer /* not : public UObject because this is an inte
U_NAMESPACE_END
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif
diff --git a/deps/icu-small/source/i18n/unicode/unum.h b/deps/icu-small/source/i18n/unicode/unum.h
index c03131f372..77cde03533 100644
--- a/deps/icu-small/source/i18n/unicode/unum.h
+++ b/deps/icu-small/source/i18n/unicode/unum.h
@@ -338,11 +338,13 @@ enum UCurrencySpacing {
/* Do not conditionalize the following with #ifndef U_HIDE_DEPRECATED_API,
* it is needed for layout of DecimalFormatSymbols object. */
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* One more than the highest normal UCurrencySpacing value.
* @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
*/
UNUM_CURRENCY_SPACING_COUNT
+#endif // U_FORCE_HIDE_DEPRECATED_API
};
typedef enum UCurrencySpacing UCurrencySpacing; /**< @stable ICU 4.8 */
@@ -409,7 +411,7 @@ typedef enum UNumberFormatFields {
* respectively.
*
* <p><strong>NOTE::</strong> New users with are strongly encouraged to
- * use unumf_openWithSkeletonAndLocale instead of unum_open.
+ * use unumf_openForSkeletonAndLocale instead of unum_open.
*
* @param pattern A pattern specifying the format to use.
* This parameter is ignored unless the style is
diff --git a/deps/icu-small/source/i18n/unicode/unumberformatter.h b/deps/icu-small/source/i18n/unicode/unumberformatter.h
index e4c21a4e4a..b27507f7a8 100644
--- a/deps/icu-small/source/i18n/unicode/unumberformatter.h
+++ b/deps/icu-small/source/i18n/unicode/unumberformatter.h
@@ -77,8 +77,6 @@
* </pre>
*/
-
-#ifndef U_HIDE_DRAFT_API
/**
* An enum declaring how to render units, including currencies. Example outputs when formatting 123 USD and 123
* meters in <em>en-CA</em>:
@@ -95,7 +93,7 @@
* <p>
* This enum is similar to {@link UMeasureFormatWidth}.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
typedef enum UNumberUnitWidth {
/**
@@ -107,7 +105,7 @@ typedef enum UNumberUnitWidth {
* In CLDR, this option corresponds to the "Narrow" format for measure units and the "¤¤¤¤¤" placeholder for
* currencies.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
UNUM_UNIT_WIDTH_NARROW,
@@ -123,7 +121,7 @@ typedef enum UNumberUnitWidth {
* In CLDR, this option corresponds to the "Short" format for measure units and the "¤" placeholder for
* currencies.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
UNUM_UNIT_WIDTH_SHORT,
@@ -134,7 +132,7 @@ typedef enum UNumberUnitWidth {
* In CLDR, this option corresponds to the default format for measure units and the "¤¤¤" placeholder for
* currencies.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
UNUM_UNIT_WIDTH_FULL_NAME,
@@ -145,7 +143,7 @@ typedef enum UNumberUnitWidth {
* <p>
* In CLDR, this option corresponds to the "¤¤" placeholder for currencies.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
UNUM_UNIT_WIDTH_ISO_CODE,
@@ -154,7 +152,7 @@ typedef enum UNumberUnitWidth {
* monetary symbols and formats as with SHORT, but omit the currency symbol. For measure units, the behavior is
* equivalent to not specifying the unit at all.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
UNUM_UNIT_WIDTH_HIDDEN,
@@ -165,9 +163,7 @@ typedef enum UNumberUnitWidth {
*/
UNUM_UNIT_WIDTH_COUNT
} UNumberUnitWidth;
-#endif /* U_HIDE_DRAFT_API */
-#ifndef U_HIDE_DRAFT_API
/**
* An enum declaring the strategy for when and how to display grouping separators (i.e., the
* separator, often a comma or period, after every 2-3 powers of ten). The choices are several
@@ -192,13 +188,13 @@ typedef enum UNumberUnitWidth {
* Note: This enum specifies the strategy for grouping sizes. To set which character to use as the
* grouping separator, use the "symbols" setter.
*
- * @draft ICU 63
+ * @stable ICU 63
*/
typedef enum UNumberGroupingStrategy {
/**
* Do not display grouping separators in any locale.
*
- * @draft ICU 61
+ * @stable ICU 61
*/
UNUM_GROUPING_OFF,
@@ -214,7 +210,7 @@ typedef enum UNumberGroupingStrategy {
* Locale data is used to determine whether to separate larger numbers into groups of 2
* (customary in South Asia) or groups of 3 (customary in Europe and the Americas).
*
- * @draft ICU 61
+ * @stable ICU 61
*/
UNUM_GROUPING_MIN2,
@@ -229,7 +225,7 @@ typedef enum UNumberGroupingStrategy {
* Locale data is used to determine whether to separate larger numbers into groups of 2
* (customary in South Asia) or groups of 3 (customary in Europe and the Americas).
*
- * @draft ICU 61
+ * @stable ICU 61
*/
UNUM_GROUPING_AUTO,
@@ -245,7 +241,7 @@ typedef enum UNumberGroupingStrategy {
* Locale data is used to determine whether to separate larger numbers into groups of 2
* (customary in South Asia) or groups of 3 (customary in Europe and the Americas).
*
- * @draft ICU 61
+ * @stable ICU 61
*/
UNUM_GROUPING_ON_ALIGNED,
@@ -253,7 +249,7 @@ typedef enum UNumberGroupingStrategy {
* Use the Western defaults: groups of 3 and enabled for all numbers 1000 or greater. Do not use
* locale data for determining the grouping strategy.
*
- * @draft ICU 61
+ * @stable ICU 61
*/
UNUM_GROUPING_THOUSANDS
@@ -269,10 +265,6 @@ typedef enum UNumberGroupingStrategy {
} UNumberGroupingStrategy;
-
-#endif /* U_HIDE_DRAFT_API */
-
-#ifndef U_HIDE_DRAFT_API
/**
* An enum declaring how to denote positive and negative numbers. Example outputs when formatting
* 123, 0, and -123 in <em>en-US</em>:
@@ -290,14 +282,14 @@ typedef enum UNumberGroupingStrategy {
* <p>
* The exact format, including the position and the code point of the sign, differ by locale.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
typedef enum UNumberSignDisplay {
/**
* Show the minus sign on negative numbers, and do not show the sign on positive numbers. This is the default
* behavior.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
UNUM_SIGN_AUTO,
@@ -305,14 +297,14 @@ typedef enum UNumberSignDisplay {
* Show the minus sign on negative numbers and the plus sign on positive numbers, including zero.
* To hide the sign on zero, see {@link UNUM_SIGN_EXCEPT_ZERO}.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
UNUM_SIGN_ALWAYS,
/**
* Do not show the sign on positive or negative numbers.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
UNUM_SIGN_NEVER,
@@ -328,7 +320,7 @@ typedef enum UNumberSignDisplay {
* AUTO sign display strategy when formatting without a currency unit. This limitation may be lifted in the
* future.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
UNUM_SIGN_ACCOUNTING,
@@ -338,24 +330,25 @@ typedef enum UNumberSignDisplay {
* ACCOUNTING sign display strategy. To hide the sign on zero, see
* {@link UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO}.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
UNUM_SIGN_ACCOUNTING_ALWAYS,
/**
* Show the minus sign on negative numbers and the plus sign on positive numbers. Do not show a
- * sign on zero.
+ * sign on zero or NaN, unless the sign bit is set (-0.0 gets a sign).
*
- * @draft ICU 61
+ * @stable ICU 61
*/
UNUM_SIGN_EXCEPT_ZERO,
/**
* Use the locale-dependent accounting format on negative numbers, and show the plus sign on
- * positive numbers. Do not show a sign on zero. For more information on the accounting format,
- * see the ACCOUNTING sign display strategy.
+ * positive numbers. Do not show a sign on zero or NaN, unless the sign bit is set (-0.0 gets a
+ * sign). For more information on the accounting format, see the ACCOUNTING sign display
+ * strategy.
*
- * @draft ICU 61
+ * @stable ICU 61
*/
UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO,
@@ -366,9 +359,7 @@ typedef enum UNumberSignDisplay {
*/
UNUM_SIGN_COUNT
} UNumberSignDisplay;
-#endif /* U_HIDE_DRAFT_API */
-#ifndef U_HIDE_DRAFT_API
/**
* An enum declaring how to render the decimal separator.
*
@@ -378,21 +369,21 @@ typedef enum UNumberSignDisplay {
* <li>UNUM_DECIMAL_SEPARATOR_ALWAYS: "1.", "1.1"
* </ul>
*
- * @draft ICU 60
+ * @stable ICU 60
*/
typedef enum UNumberDecimalSeparatorDisplay {
/**
* Show the decimal separator when there are one or more digits to display after the separator, and do not show
* it otherwise. This is the default behavior.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
UNUM_DECIMAL_SEPARATOR_AUTO,
/**
* Always show the decimal separator, even if there are no digits to display after the separator.
*
- * @draft ICU 60
+ * @stable ICU 60
*/
UNUM_DECIMAL_SEPARATOR_ALWAYS,
@@ -403,7 +394,6 @@ typedef enum UNumberDecimalSeparatorDisplay {
*/
UNUM_DECIMAL_SEPARATOR_COUNT
} UNumberDecimalSeparatorDisplay;
-#endif /* U_HIDE_DRAFT_API */
struct UNumberFormatter;
/**
@@ -649,6 +639,13 @@ unumf_resultGetAllFieldPositions(const UFormattedNumber* uresult, UFieldPosition
UErrorCode* ec);
+// TODO(ICU-20775): Propose this as API.
+// NOTE: This is not currently implemented.
+// U_DRAFT int32_t U_EXPORT2
+// unumf_resultToDecimalNumber(const UFormattedNumber* uresult, char* buffer, int32_t bufferCapacity,
+// UErrorCode* ec);
+
+
/**
* Releases the UNumberFormatter created by unumf_openForSkeletonAndLocale().
*
diff --git a/deps/icu-small/source/i18n/unicode/usearch.h b/deps/icu-small/source/i18n/unicode/usearch.h
index 6b495ef001..d9d84b4f6a 100644
--- a/deps/icu-small/source/i18n/unicode/usearch.h
+++ b/deps/icu-small/source/i18n/unicode/usearch.h
@@ -24,7 +24,7 @@
* \file
* \brief C API: StringSearch
*
- * C Apis for an engine that provides language-sensitive text searching based
+ * C APIs for an engine that provides language-sensitive text searching based
* on the comparison rules defined in a <tt>UCollator</tt> data struct,
* see <tt>ucol.h</tt>. This ensures that language eccentricity can be
* handled, e.g. for the German collator, characters &szlig; and SS will be matched
@@ -55,7 +55,7 @@
* <p>
* This search has APIs similar to that of other text iteration mechanisms
* such as the break iterators in <tt>ubrk.h</tt>. Using these
- * APIs, it is easy to scan through text looking for all occurances of
+ * APIs, it is easy to scan through text looking for all occurrences of
* a given pattern. This search iterator allows changing of direction by
* calling a <tt>reset</tt> followed by a <tt>next</tt> or <tt>previous</tt>.
* Though a direction change can occur without calling <tt>reset</tt> first,
@@ -130,7 +130,7 @@
* pos = usearch_next(search, &status))
* {
* printf("Found match at %d pos, length is %d\n", pos,
- * usearch_getMatchLength(search));
+ * usearch_getMatchedLength(search));
* }
* }
*
@@ -479,7 +479,7 @@ U_STABLE int32_t U_EXPORT2 usearch_getMatchedLength(
* possible. If the buffer fits the matched text exactly, a null-termination
* is not possible, then a U_STRING_NOT_TERMINATED_ERROR set in status.
* Pre-flighting can be either done with length = 0 or the API
-* <tt>usearch_getMatchLength</tt>.
+* <tt>usearch_getMatchedLength</tt>.
* @param strsrch search iterator data struct
* @param result UChar buffer to store the matched string
* @param resultCapacity length of the result buffer
@@ -766,7 +766,7 @@ U_STABLE void U_EXPORT2 usearch_reset(UStringSearch *strsrch);
#ifndef U_HIDE_INTERNAL_API
/**
* Simple forward search for the pattern, starting at a specified index,
- * and using using a default set search options.
+ * and using a default set search options.
*
* This is an experimental function, and is not an official part of the
* ICU API.
@@ -783,7 +783,7 @@ U_STABLE void U_EXPORT2 usearch_reset(UStringSearch *strsrch);
* are part of a combining sequence, as described below.
*
* A match will not include a partial combining sequence. Combining
- * character sequences are considered to be inseperable units,
+ * character sequences are considered to be inseparable units,
* and either match the pattern completely, or are considered to not match
* at all. Thus, for example, an A followed a combining accent mark will
* not be found when searching for a plain (unaccented) A. (unless
@@ -792,7 +792,7 @@ U_STABLE void U_EXPORT2 usearch_reset(UStringSearch *strsrch);
* When beginning a search, the initial starting position, startIdx,
* is assumed to be an acceptable match boundary with respect to
* combining characters. A combining sequence that spans across the
- * starting point will not supress a match beginning at startIdx.
+ * starting point will not suppress a match beginning at startIdx.
*
* Characters that expand to multiple collation elements
* (German sharp-S becoming 'ss', or the composed forms of accented
@@ -843,7 +843,7 @@ U_INTERNAL UBool U_EXPORT2 usearch_search(UStringSearch *strsrch,
* are part of a combining sequence, as described below.
*
* A match will not include a partial combining sequence. Combining
- * character sequences are considered to be inseperable units,
+ * character sequences are considered to be inseparable units,
* and either match the pattern completely, or are considered to not match
* at all. Thus, for example, an A followed a combining accent mark will
* not be found when searching for a plain (unaccented) A. (unless
@@ -852,7 +852,7 @@ U_INTERNAL UBool U_EXPORT2 usearch_search(UStringSearch *strsrch,
* When beginning a search, the initial starting position, startIdx,
* is assumed to be an acceptable match boundary with respect to
* combining characters. A combining sequence that spans across the
- * starting point will not supress a match beginning at startIdx.
+ * starting point will not suppress a match beginning at startIdx.
*
* Characters that expand to multiple collation elements
* (German sharp-S becoming 'ss', or the composed forms of accented
diff --git a/deps/icu-small/source/i18n/unicode/uspoof.h b/deps/icu-small/source/i18n/unicode/uspoof.h
index d15ba4b242..63a13387b0 100644
--- a/deps/icu-small/source/i18n/unicode/uspoof.h
+++ b/deps/icu-small/source/i18n/unicode/uspoof.h
@@ -353,6 +353,8 @@
* @stable ICU 4.6
*/
+U_CDECL_BEGIN
+
struct USpoofChecker;
/**
* @stable ICU 4.2
@@ -471,7 +473,6 @@ typedef enum USpoofChecks {
*/
USPOOF_MIXED_NUMBERS = 128,
-#ifndef U_HIDE_DRAFT_API
/**
* Check that an identifier does not have a combining character following a character in which that
* combining character would be hidden; for example 'i' followed by a U+0307 combining dot.
@@ -489,10 +490,9 @@ typedef enum USpoofChecks {
*
* This list and the number of combing characters considered by this check may grow over time.
*
- * @draft ICU 62
+ * @stable ICU 62
*/
USPOOF_HIDDEN_OVERLAY = 256,
-#endif /* U_HIDE_DRAFT_API */
/**
* Enable all spoof checks.
@@ -674,25 +674,6 @@ uspoof_openFromSource(const char *confusables, int32_t confusablesLen,
U_STABLE void U_EXPORT2
uspoof_close(USpoofChecker *sc);
-#if U_SHOW_CPLUSPLUS_API
-
-U_NAMESPACE_BEGIN
-
-/**
- * \class LocalUSpoofCheckerPointer
- * "Smart pointer" class, closes a USpoofChecker via uspoof_close().
- * For most methods see the LocalPointerBase base class.
- *
- * @see LocalPointerBase
- * @see LocalPointer
- * @stable ICU 4.4
- */
-U_DEFINE_LOCAL_OPEN_POINTER(LocalUSpoofCheckerPointer, USpoofChecker, uspoof_close);
-
-U_NAMESPACE_END
-
-#endif
-
/**
* Clone a Spoof Checker. The clone will be set to perform the same checks
* as the original source.
@@ -901,54 +882,6 @@ U_STABLE const USet * U_EXPORT2
uspoof_getAllowedChars(const USpoofChecker *sc, UErrorCode *status);
-#if U_SHOW_CPLUSPLUS_API
-/**
- * Limit the acceptable characters to those specified by a Unicode Set.
- * Any previously specified character limit is
- * is replaced by the new settings. This includes limits on
- * characters that were set with the uspoof_setAllowedLocales() function.
- *
- * The USPOOF_CHAR_LIMIT test is automatically enabled for this
- * USoofChecker by this function.
- *
- * @param sc The USpoofChecker
- * @param chars A Unicode Set containing the list of
- * characters that are permitted. Ownership of the set
- * remains with the caller. The incoming set is cloned by
- * this function, so there are no restrictions on modifying
- * or deleting the UnicodeSet after calling this function.
- * @param status The error code, set if this function encounters a problem.
- * @stable ICU 4.2
- */
-U_STABLE void U_EXPORT2
-uspoof_setAllowedUnicodeSet(USpoofChecker *sc, const icu::UnicodeSet *chars, UErrorCode *status);
-
-
-/**
- * Get a UnicodeSet for the characters permitted in an identifier.
- * This corresponds to the limits imposed by the Set Allowed Characters /
- * UnicodeSet functions. Limitations imposed by other checks will not be
- * reflected in the set returned by this function.
- *
- * The returned set will be frozen, meaning that it cannot be modified
- * by the caller.
- *
- * Ownership of the returned set remains with the Spoof Detector. The
- * returned set will become invalid if the spoof detector is closed,
- * or if a new set of allowed characters is specified.
- *
- *
- * @param sc The USpoofChecker
- * @param status The error code, set if this function encounters a problem.
- * @return A UnicodeSet containing the characters that are permitted by
- * the USPOOF_CHAR_LIMIT test.
- * @stable ICU 4.2
- */
-U_STABLE const icu::UnicodeSet * U_EXPORT2
-uspoof_getAllowedUnicodeSet(const USpoofChecker *sc, UErrorCode *status);
-#endif
-
-
/**
* Check the specified string for possible security issues.
* The text to be checked will typically be an identifier of some sort.
@@ -1027,43 +960,6 @@ uspoof_checkUTF8(const USpoofChecker *sc,
UErrorCode *status);
-#if U_SHOW_CPLUSPLUS_API
-/**
- * Check the specified string for possible security issues.
- * The text to be checked will typically be an identifier of some sort.
- * The set of checks to be performed is specified with uspoof_setChecks().
- *
- * \note
- * Consider using the newer API, {@link uspoof_check2UnicodeString}, instead.
- * The newer API exposes additional information from the check procedure
- * and is otherwise identical to this method.
- *
- * @param sc The USpoofChecker
- * @param id A identifier to be checked for possible security issues.
- * @param position Deprecated in ICU 51. Always returns zero.
- * Originally, an out parameter for the index of the first
- * string position that failed a check.
- * This parameter may be NULL.
- * @param status The error code, set if an error occurred while attempting to
- * perform the check.
- * Spoofing or security issues detected with the input string are
- * not reported here, but through the function's return value.
- * @return An integer value with bits set for any potential security
- * or spoofing issues detected. The bits are defined by
- * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS)
- * will be zero if the input string passes all of the
- * enabled checks.
- * @see uspoof_check2UnicodeString
- * @stable ICU 4.2
- */
-U_STABLE int32_t U_EXPORT2
-uspoof_checkUnicodeString(const USpoofChecker *sc,
- const icu::UnicodeString &id,
- int32_t *position,
- UErrorCode *status);
-#endif
-
-
/**
* Check the specified string for possible security issues.
* The text to be checked will typically be an identifier of some sort.
@@ -1135,39 +1031,6 @@ uspoof_check2UTF8(const USpoofChecker *sc,
USpoofCheckResult* checkResult,
UErrorCode *status);
-#if U_SHOW_CPLUSPLUS_API
-/**
- * Check the specified string for possible security issues.
- * The text to be checked will typically be an identifier of some sort.
- * The set of checks to be performed is specified with uspoof_setChecks().
- *
- * @param sc The USpoofChecker
- * @param id A identifier to be checked for possible security issues.
- * @param checkResult An instance of USpoofCheckResult to be filled with
- * details about the identifier. Can be NULL.
- * @param status The error code, set if an error occurred while attempting to
- * perform the check.
- * Spoofing or security issues detected with the input string are
- * not reported here, but through the function's return value.
- * @return An integer value with bits set for any potential security
- * or spoofing issues detected. The bits are defined by
- * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS)
- * will be zero if the input string passes all of the
- * enabled checks. Any information in this bitmask will be
- * consistent with the information saved in the optional
- * checkResult parameter.
- * @see uspoof_openCheckResult
- * @see uspoof_check2
- * @see uspoof_check2UTF8
- * @stable ICU 58
- */
-U_STABLE int32_t U_EXPORT2
-uspoof_check2UnicodeString(const USpoofChecker *sc,
- const icu::UnicodeString &id,
- USpoofCheckResult* checkResult,
- UErrorCode *status);
-#endif
-
/**
* Create a USpoofCheckResult, used by the {@link uspoof_check2} class of functions to return
* information about the identifier. Information includes:
@@ -1199,32 +1062,6 @@ uspoof_openCheckResult(UErrorCode *status);
U_STABLE void U_EXPORT2
uspoof_closeCheckResult(USpoofCheckResult *checkResult);
-#if U_SHOW_CPLUSPLUS_API
-
-U_NAMESPACE_BEGIN
-
-/**
- * \class LocalUSpoofCheckResultPointer
- * "Smart pointer" class, closes a USpoofCheckResult via `uspoof_closeCheckResult()`.
- * For most methods see the LocalPointerBase base class.
- *
- * @see LocalPointerBase
- * @see LocalPointer
- * @stable ICU 58
- */
-
-/**
- * \cond
- * Note: Doxygen is giving a bogus warning on this U_DEFINE_LOCAL_OPEN_POINTER.
- * For now, suppress with a Doxygen cond
- */
-U_DEFINE_LOCAL_OPEN_POINTER(LocalUSpoofCheckResultPointer, USpoofCheckResult, uspoof_closeCheckResult);
-/** \endcond */
-
-U_NAMESPACE_END
-
-#endif
-
/**
* Indicates which of the spoof check(s) have failed. The value is a bitwise OR of the constants for the tests
* in question: USPOOF_RESTRICTION_LEVEL, USPOOF_CHAR_LIMIT, and so on.
@@ -1355,36 +1192,6 @@ uspoof_areConfusableUTF8(const USpoofChecker *sc,
-#if U_SHOW_CPLUSPLUS_API
-/**
- * A version of {@link uspoof_areConfusable} accepting UnicodeStrings.
- *
- * @param sc The USpoofChecker
- * @param s1 The first of the two identifiers to be compared for
- * confusability. The strings are in UTF-8 format.
- * @param s2 The second of the two identifiers to be compared for
- * confusability. The strings are in UTF-8 format.
- * @param status The error code, set if an error occurred while attempting to
- * perform the check.
- * Confusability of the identifiers is not reported here,
- * but through this function's return value.
- * @return An integer value with bit(s) set corresponding to
- * the type of confusability found, as defined by
- * enum USpoofChecks. Zero is returned if the identifiers
- * are not confusable.
- *
- * @stable ICU 4.2
- *
- * @see uspoof_areConfusable
- */
-U_STABLE int32_t U_EXPORT2
-uspoof_areConfusableUnicodeString(const USpoofChecker *sc,
- const icu::UnicodeString &s1,
- const icu::UnicodeString &s2,
- UErrorCode *status);
-#endif
-
-
/**
* Get the "skeleton" for an identifier.
* Skeletons are a transformation of the input identifier;
@@ -1463,38 +1270,6 @@ uspoof_getSkeletonUTF8(const USpoofChecker *sc,
char *dest, int32_t destCapacity,
UErrorCode *status);
-#if U_SHOW_CPLUSPLUS_API
-/**
- * Get the "skeleton" for an identifier.
- * Skeletons are a transformation of the input identifier;
- * Two identifiers are confusable if their skeletons are identical.
- * See Unicode UAX #39 for additional information.
- *
- * Using skeletons directly makes it possible to quickly check
- * whether an identifier is confusable with any of some large
- * set of existing identifiers, by creating an efficiently
- * searchable collection of the skeletons.
- *
- * @param sc The USpoofChecker.
- * @param type Deprecated in ICU 58. You may pass any number.
- * Originally, controlled which of the Unicode confusable data
- * tables to use.
- * @param id The input identifier whose skeleton will be computed.
- * @param dest The output identifier, to receive the skeleton string.
- * @param status The error code, set if an error occurred while attempting to
- * perform the check.
- * @return A reference to the destination (skeleton) string.
- *
- * @stable ICU 4.2
- */
-U_I18N_API icu::UnicodeString & U_EXPORT2
-uspoof_getSkeletonUnicodeString(const USpoofChecker *sc,
- uint32_t type,
- const icu::UnicodeString &id,
- icu::UnicodeString &dest,
- UErrorCode *status);
-#endif /* U_SHOW_CPLUSPLUS_API */
-
/**
* Get the set of Candidate Characters for Inclusion in Identifiers, as defined
* in http://unicode.org/Public/security/latest/xidmodifications.txt
@@ -1525,8 +1300,243 @@ uspoof_getInclusionSet(UErrorCode *status);
U_STABLE const USet * U_EXPORT2
uspoof_getRecommendedSet(UErrorCode *status);
+/**
+ * Serialize the data for a spoof detector into a chunk of memory.
+ * The flattened spoof detection tables can later be used to efficiently
+ * instantiate a new Spoof Detector.
+ *
+ * The serialized spoof checker includes only the data compiled from the
+ * Unicode data tables by uspoof_openFromSource(); it does not include
+ * include any other state or configuration that may have been set.
+ *
+ * @param sc the Spoof Detector whose data is to be serialized.
+ * @param data a pointer to 32-bit-aligned memory to be filled with the data,
+ * can be NULL if capacity==0
+ * @param capacity the number of bytes available at data,
+ * or 0 for preflighting
+ * @param status an in/out ICU UErrorCode; possible errors include:
+ * - U_BUFFER_OVERFLOW_ERROR if the data storage block is too small for serialization
+ * - U_ILLEGAL_ARGUMENT_ERROR the data or capacity parameters are bad
+ * @return the number of bytes written or needed for the spoof data
+ *
+ * @see utrie2_openFromSerialized()
+ * @stable ICU 4.2
+ */
+U_STABLE int32_t U_EXPORT2
+uspoof_serialize(USpoofChecker *sc,
+ void *data, int32_t capacity,
+ UErrorCode *status);
+
+U_CDECL_END
+
#if U_SHOW_CPLUSPLUS_API
+U_NAMESPACE_BEGIN
+
+/**
+ * \class LocalUSpoofCheckerPointer
+ * "Smart pointer" class, closes a USpoofChecker via uspoof_close().
+ * For most methods see the LocalPointerBase base class.
+ *
+ * @see LocalPointerBase
+ * @see LocalPointer
+ * @stable ICU 4.4
+ */
+/**
+ * \cond
+ * Note: Doxygen is giving a bogus warning on this U_DEFINE_LOCAL_OPEN_POINTER.
+ * For now, suppress with a Doxygen cond
+ */
+U_DEFINE_LOCAL_OPEN_POINTER(LocalUSpoofCheckerPointer, USpoofChecker, uspoof_close);
+/** \endcond */
+
+/**
+ * \class LocalUSpoofCheckResultPointer
+ * "Smart pointer" class, closes a USpoofCheckResult via `uspoof_closeCheckResult()`.
+ * For most methods see the LocalPointerBase base class.
+ *
+ * @see LocalPointerBase
+ * @see LocalPointer
+ * @stable ICU 58
+ */
+
+/**
+ * \cond
+ * Note: Doxygen is giving a bogus warning on this U_DEFINE_LOCAL_OPEN_POINTER.
+ * For now, suppress with a Doxygen cond
+ */
+U_DEFINE_LOCAL_OPEN_POINTER(LocalUSpoofCheckResultPointer, USpoofCheckResult, uspoof_closeCheckResult);
+/** \endcond */
+
+U_NAMESPACE_END
+
+/**
+ * Limit the acceptable characters to those specified by a Unicode Set.
+ * Any previously specified character limit is
+ * is replaced by the new settings. This includes limits on
+ * characters that were set with the uspoof_setAllowedLocales() function.
+ *
+ * The USPOOF_CHAR_LIMIT test is automatically enabled for this
+ * USoofChecker by this function.
+ *
+ * @param sc The USpoofChecker
+ * @param chars A Unicode Set containing the list of
+ * characters that are permitted. Ownership of the set
+ * remains with the caller. The incoming set is cloned by
+ * this function, so there are no restrictions on modifying
+ * or deleting the UnicodeSet after calling this function.
+ * @param status The error code, set if this function encounters a problem.
+ * @stable ICU 4.2
+ */
+U_STABLE void U_EXPORT2
+uspoof_setAllowedUnicodeSet(USpoofChecker *sc, const icu::UnicodeSet *chars, UErrorCode *status);
+
+
+/**
+ * Get a UnicodeSet for the characters permitted in an identifier.
+ * This corresponds to the limits imposed by the Set Allowed Characters /
+ * UnicodeSet functions. Limitations imposed by other checks will not be
+ * reflected in the set returned by this function.
+ *
+ * The returned set will be frozen, meaning that it cannot be modified
+ * by the caller.
+ *
+ * Ownership of the returned set remains with the Spoof Detector. The
+ * returned set will become invalid if the spoof detector is closed,
+ * or if a new set of allowed characters is specified.
+ *
+ *
+ * @param sc The USpoofChecker
+ * @param status The error code, set if this function encounters a problem.
+ * @return A UnicodeSet containing the characters that are permitted by
+ * the USPOOF_CHAR_LIMIT test.
+ * @stable ICU 4.2
+ */
+U_STABLE const icu::UnicodeSet * U_EXPORT2
+uspoof_getAllowedUnicodeSet(const USpoofChecker *sc, UErrorCode *status);
+
+/**
+ * Check the specified string for possible security issues.
+ * The text to be checked will typically be an identifier of some sort.
+ * The set of checks to be performed is specified with uspoof_setChecks().
+ *
+ * \note
+ * Consider using the newer API, {@link uspoof_check2UnicodeString}, instead.
+ * The newer API exposes additional information from the check procedure
+ * and is otherwise identical to this method.
+ *
+ * @param sc The USpoofChecker
+ * @param id A identifier to be checked for possible security issues.
+ * @param position Deprecated in ICU 51. Always returns zero.
+ * Originally, an out parameter for the index of the first
+ * string position that failed a check.
+ * This parameter may be NULL.
+ * @param status The error code, set if an error occurred while attempting to
+ * perform the check.
+ * Spoofing or security issues detected with the input string are
+ * not reported here, but through the function's return value.
+ * @return An integer value with bits set for any potential security
+ * or spoofing issues detected. The bits are defined by
+ * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS)
+ * will be zero if the input string passes all of the
+ * enabled checks.
+ * @see uspoof_check2UnicodeString
+ * @stable ICU 4.2
+ */
+U_STABLE int32_t U_EXPORT2
+uspoof_checkUnicodeString(const USpoofChecker *sc,
+ const icu::UnicodeString &id,
+ int32_t *position,
+ UErrorCode *status);
+
+/**
+ * Check the specified string for possible security issues.
+ * The text to be checked will typically be an identifier of some sort.
+ * The set of checks to be performed is specified with uspoof_setChecks().
+ *
+ * @param sc The USpoofChecker
+ * @param id A identifier to be checked for possible security issues.
+ * @param checkResult An instance of USpoofCheckResult to be filled with
+ * details about the identifier. Can be NULL.
+ * @param status The error code, set if an error occurred while attempting to
+ * perform the check.
+ * Spoofing or security issues detected with the input string are
+ * not reported here, but through the function's return value.
+ * @return An integer value with bits set for any potential security
+ * or spoofing issues detected. The bits are defined by
+ * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS)
+ * will be zero if the input string passes all of the
+ * enabled checks. Any information in this bitmask will be
+ * consistent with the information saved in the optional
+ * checkResult parameter.
+ * @see uspoof_openCheckResult
+ * @see uspoof_check2
+ * @see uspoof_check2UTF8
+ * @stable ICU 58
+ */
+U_STABLE int32_t U_EXPORT2
+uspoof_check2UnicodeString(const USpoofChecker *sc,
+ const icu::UnicodeString &id,
+ USpoofCheckResult* checkResult,
+ UErrorCode *status);
+
+/**
+ * A version of {@link uspoof_areConfusable} accepting UnicodeStrings.
+ *
+ * @param sc The USpoofChecker
+ * @param s1 The first of the two identifiers to be compared for
+ * confusability. The strings are in UTF-8 format.
+ * @param s2 The second of the two identifiers to be compared for
+ * confusability. The strings are in UTF-8 format.
+ * @param status The error code, set if an error occurred while attempting to
+ * perform the check.
+ * Confusability of the identifiers is not reported here,
+ * but through this function's return value.
+ * @return An integer value with bit(s) set corresponding to
+ * the type of confusability found, as defined by
+ * enum USpoofChecks. Zero is returned if the identifiers
+ * are not confusable.
+ *
+ * @stable ICU 4.2
+ *
+ * @see uspoof_areConfusable
+ */
+U_STABLE int32_t U_EXPORT2
+uspoof_areConfusableUnicodeString(const USpoofChecker *sc,
+ const icu::UnicodeString &s1,
+ const icu::UnicodeString &s2,
+ UErrorCode *status);
+
+/**
+ * Get the "skeleton" for an identifier.
+ * Skeletons are a transformation of the input identifier;
+ * Two identifiers are confusable if their skeletons are identical.
+ * See Unicode UAX #39 for additional information.
+ *
+ * Using skeletons directly makes it possible to quickly check
+ * whether an identifier is confusable with any of some large
+ * set of existing identifiers, by creating an efficiently
+ * searchable collection of the skeletons.
+ *
+ * @param sc The USpoofChecker.
+ * @param type Deprecated in ICU 58. You may pass any number.
+ * Originally, controlled which of the Unicode confusable data
+ * tables to use.
+ * @param id The input identifier whose skeleton will be computed.
+ * @param dest The output identifier, to receive the skeleton string.
+ * @param status The error code, set if an error occurred while attempting to
+ * perform the check.
+ * @return A reference to the destination (skeleton) string.
+ *
+ * @stable ICU 4.2
+ */
+U_I18N_API icu::UnicodeString & U_EXPORT2
+uspoof_getSkeletonUnicodeString(const USpoofChecker *sc,
+ uint32_t type,
+ const icu::UnicodeString &id,
+ icu::UnicodeString &dest,
+ UErrorCode *status);
+
/**
* Get the set of Candidate Characters for Inclusion in Identifiers, as defined
* in http://unicode.org/Public/security/latest/xidmodifications.txt
@@ -1559,34 +1569,6 @@ uspoof_getRecommendedUnicodeSet(UErrorCode *status);
#endif /* U_SHOW_CPLUSPLUS_API */
-/**
- * Serialize the data for a spoof detector into a chunk of memory.
- * The flattened spoof detection tables can later be used to efficiently
- * instantiate a new Spoof Detector.
- *
- * The serialized spoof checker includes only the data compiled from the
- * Unicode data tables by uspoof_openFromSource(); it does not include
- * include any other state or configuration that may have been set.
- *
- * @param sc the Spoof Detector whose data is to be serialized.
- * @param data a pointer to 32-bit-aligned memory to be filled with the data,
- * can be NULL if capacity==0
- * @param capacity the number of bytes available at data,
- * or 0 for preflighting
- * @param status an in/out ICU UErrorCode; possible errors include:
- * - U_BUFFER_OVERFLOW_ERROR if the data storage block is too small for serialization
- * - U_ILLEGAL_ARGUMENT_ERROR the data or capacity parameters are bad
- * @return the number of bytes written or needed for the spoof data
- *
- * @see utrie2_openFromSerialized()
- * @stable ICU 4.2
- */
-U_STABLE int32_t U_EXPORT2
-uspoof_serialize(USpoofChecker *sc,
- void *data, int32_t capacity,
- UErrorCode *status);
-
-
-#endif
+#endif /* UCONFIG_NO_NORMALIZATION */
#endif /* USPOOF_H */
diff --git a/deps/icu-small/source/i18n/unicode/utrans.h b/deps/icu-small/source/i18n/unicode/utrans.h
index 7672b4428f..56640eda96 100644
--- a/deps/icu-small/source/i18n/unicode/utrans.h
+++ b/deps/icu-small/source/i18n/unicode/utrans.h
@@ -142,7 +142,7 @@ typedef struct UTransPosition {
int32_t contextLimit;
/**
- * Beginning index, inclusive, of the text to be transliteratd.
+ * Beginning index, inclusive, of the text to be transliterated.
* INPUT/OUTPUT parameter: This parameter is advanced past
* characters that have already been transliterated by a
* transliteration operation.
@@ -151,7 +151,7 @@ typedef struct UTransPosition {
int32_t start;
/**
- * Ending index, exclusive, of the text to be transliteratd.
+ * Ending index, exclusive, of the text to be transliterated.
* INPUT/OUTPUT parameter: This parameter is updated to reflect
* changes in the length of the text, but points to the same
* logical position in the text.
@@ -389,7 +389,7 @@ utrans_trans(const UTransliterator* trans,
/**
* Transliterate the portion of the UReplaceable text buffer that can
- * be transliterated unambiguosly. This method is typically called
+ * be transliterated unambiguously. This method is typically called
* after new text has been inserted, e.g. as a result of a keyboard
* event. The transliterator will try to transliterate characters of
* <code>rep</code> between <code>index.cursor</code> and
@@ -454,8 +454,7 @@ utrans_transIncremental(const UTransliterator* trans,
* zero-terminated. Upon return, the new length is stored in
* *textLength. If textLength is NULL then the string is assumed to
* be zero-terminated.
- * @param textCapacity a pointer to the length of the text buffer.
- * Upon return,
+ * @param textCapacity the length of the text buffer
* @param start the beginning index, inclusive; <code>0 <= start <=
* limit</code>.
* @param limit pointer to the ending index, exclusive; <code>start <=
@@ -479,7 +478,7 @@ utrans_transUChars(const UTransliterator* trans,
/**
* Transliterate the portion of the UChar* text buffer that can be
- * transliterated unambiguosly. See utrans_transIncremental(). The
+ * transliterated unambiguously. See utrans_transIncremental(). The
* string is passed in in a UChar* buffer. The string is modified in
* place. If the result is longer than textCapacity, it is truncated.
* The actual length of the result is returned in *textLength, if
diff --git a/deps/icu-small/source/i18n/unicode/vtzone.h b/deps/icu-small/source/i18n/unicode/vtzone.h
index 5d16177868..43a5652d6a 100644
--- a/deps/icu-small/source/i18n/unicode/vtzone.h
+++ b/deps/icu-small/source/i18n/unicode/vtzone.h
@@ -11,6 +11,8 @@
#include "unicode/utypes.h"
+#if U_SHOW_CPLUSPLUS_API
+
/**
* \file
* \brief C++ API: RFC2445 VTIMEZONE support
@@ -185,7 +187,7 @@ public:
* @return A new copy of this TimeZone object.
* @stable ICU 3.8
*/
- virtual TimeZone* clone(void) const;
+ virtual VTimeZone* clone() const;
/**
* Returns the TimeZone's adjusted GMT offset (i.e., the number of milliseconds to add
@@ -288,6 +290,7 @@ public:
*/
virtual UBool useDaylightTime(void) const;
+#ifndef U_FORCE_HIDE_DEPRECATED_API
/**
* Queries if the given date is in daylight savings time in
* this time zone.
@@ -302,6 +305,7 @@ public:
* @deprecated ICU 2.4. Use Calendar::inDaylightTime() instead.
*/
virtual UBool inDaylightTime(UDate date, UErrorCode& status) const;
+#endif // U_FORCE_HIDE_DEPRECATED_API
/**
* Returns true if this zone has the same rule and offset as another zone.
@@ -453,5 +457,7 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* U_SHOW_CPLUSPLUS_API */
+
#endif // VTZONE_H
//eof
diff --git a/deps/icu-small/source/i18n/unum.cpp b/deps/icu-small/source/i18n/unum.cpp
index 907a1cd95e..ba3d519162 100644
--- a/deps/icu-small/source/i18n/unum.cpp
+++ b/deps/icu-small/source/i18n/unum.cpp
@@ -135,6 +135,11 @@ unum_open( UNumberFormatStyle style,
*status = U_MEMORY_ALLOCATION_ERROR;
}
+ if (U_FAILURE(*status) && retVal != NULL) {
+ delete retVal;
+ retVal = NULL;
+ }
+
return reinterpret_cast<UNumberFormat *>(retVal);
}
diff --git a/deps/icu-small/source/i18n/usearch.cpp b/deps/icu-small/source/i18n/usearch.cpp
index 0e9b876d2b..1b22e201e5 100644
--- a/deps/icu-small/source/i18n/usearch.cpp
+++ b/deps/icu-small/source/i18n/usearch.cpp
@@ -317,7 +317,7 @@ inline uint16_t initializePatternCETable(UStringSearch *strsrch,
uprv_free(pattern->ces);
}
- uint16_t offset = 0;
+ uint32_t offset = 0;
uint16_t result = 0;
int32_t ce;
@@ -388,7 +388,7 @@ inline uint16_t initializePatternPCETable(UStringSearch *strsrch,
uprv_free(pattern->pces);
}
- uint16_t offset = 0;
+ uint32_t offset = 0;
uint16_t result = 0;
int64_t pce;
@@ -1351,7 +1351,7 @@ inline int getUnblockedAccentIndex(UChar *accents, int32_t *accentsindex)
* @param destinationlength target array size, returning the appended length
* @param source1 null-terminated first array
* @param source2 second array
-* @param source2length length of seond array
+* @param source2length length of second array
* @param source3 null-terminated third array
* @param status error status if any
* @return new destination array, destination if there was no new allocation
@@ -1560,7 +1560,7 @@ inline void cleanUpSafeText(const UStringSearch *strsrch, UChar *safetext,
/**
* Take the rearranged end accents and tries matching. If match failed at
-* a seperate preceding set of accents (seperated from the rearranged on by
+* a separate preceding set of accents (separated from the rearranged on by
* at least a base character) then we rearrange the preceding accents and
* tries matching again.
* We allow skipping of the ends of the accent set if the ces do not match.
@@ -2220,7 +2220,7 @@ int32_t doPreviousCanonicalSuffixMatch(UStringSearch *strsrch,
/**
* Take the rearranged start accents and tries matching. If match failed at
-* a seperate following set of accents (seperated from the rearranged on by
+* a separate following set of accents (separated from the rearranged on by
* at least a base character) then we rearrange the preceding accents and
* tries matching again.
* We allow skipping of the ends of the accent set if the ces do not match.
@@ -3544,7 +3544,12 @@ const CEI *CEIBuffer::get(int32_t index) {
// Verify that it is the next one in sequence, which is all
// that is allowed.
if (index != limitIx) {
- UPRV_UNREACHABLE;
+ U_ASSERT(FALSE);
+ // TODO: In ICU 64 the above assert was changed to use UPRV_UNREACHABLE instead
+ // which unconditionally calls abort(). However, there were cases where this was
+ // being hit. This change is reverted for now, restoring the existing behavior.
+ // ICU-20792 tracks the follow-up work/further investigation on this.
+ return NULL;
}
// Manage the circular CE buffer indexing
@@ -3581,7 +3586,12 @@ const CEI *CEIBuffer::getPrevious(int32_t index) {
// Verify that it is the next one in sequence, which is all
// that is allowed.
if (index != limitIx) {
- UPRV_UNREACHABLE;
+ U_ASSERT(FALSE);
+ // TODO: In ICU 64 the above assert was changed to use UPRV_UNREACHABLE instead
+ // which unconditionally calls abort(). However, there were cases where this was
+ // being hit. This change is reverted for now, restoring the existing behavior.
+ // ICU-20792 tracks the follow-up work/further investigation on this.
+ return NULL;
}
// Manage the circular CE buffer indexing
@@ -3852,7 +3862,7 @@ U_CAPI UBool U_EXPORT2 usearch_search(UStringSearch *strsrch,
#endif
// Input parameter sanity check.
- // TODO: should input indicies clip to the text length
+ // TODO: should input indices clip to the text length
// in the same way that UText does.
if(strsrch->pattern.cesLength == 0 ||
startIdx < 0 ||
@@ -4014,7 +4024,7 @@ U_CAPI UBool U_EXPORT2 usearch_search(UStringSearch *strsrch,
// Check for the start of the match being within an Collation Element Expansion,
// meaning that the first char of the match is only partially matched.
- // With exapnsions, the first CE will report the index of the source
+ // With expansions, the first CE will report the index of the source
// character, and all subsequent (expansions) CEs will report the source index of the
// _following_ character.
int32_t secondIx = firstCEI->highIndex;
diff --git a/deps/icu-small/source/i18n/uspoof.cpp b/deps/icu-small/source/i18n/uspoof.cpp
index c8fbec27bb..c44c60028b 100644
--- a/deps/icu-small/source/i18n/uspoof.cpp
+++ b/deps/icu-small/source/i18n/uspoof.cpp
@@ -349,7 +349,7 @@ uspoof_setAllowedUnicodeSet(USpoofChecker *sc, const UnicodeSet *chars, UErrorCo
*status = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
- UnicodeSet *clonedSet = static_cast<UnicodeSet *>(chars->clone());
+ UnicodeSet *clonedSet = chars->clone();
if (clonedSet == NULL || clonedSet->isBogus()) {
*status = U_MEMORY_ALLOCATION_ERROR;
return;
diff --git a/deps/icu-small/source/i18n/uspoof_impl.cpp b/deps/icu-small/source/i18n/uspoof_impl.cpp
index 85a028bdfa..3c1f84a19b 100644
--- a/deps/icu-small/source/i18n/uspoof_impl.cpp
+++ b/deps/icu-small/source/i18n/uspoof_impl.cpp
@@ -82,7 +82,7 @@ SpoofImpl::SpoofImpl(const SpoofImpl &src, UErrorCode &status) :
if (src.fSpoofData != NULL) {
fSpoofData = src.fSpoofData->addReference();
}
- fAllowedCharsSet = static_cast<const UnicodeSet *>(src.fAllowedCharsSet->clone());
+ fAllowedCharsSet = src.fAllowedCharsSet->clone();
fAllowedLocales = uprv_strdup(src.fAllowedLocales);
if (fAllowedCharsSet == NULL || fAllowedLocales == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
@@ -193,7 +193,7 @@ void SpoofImpl::setAllowedLocales(const char *localesList, UErrorCode &status) {
}
// Store the updated spoof checker state.
- tmpSet = static_cast<UnicodeSet *>(allowedChars.clone());
+ tmpSet = allowedChars.clone();
const char *tmpLocalesList = uprv_strdup(localesList);
if (tmpSet == NULL || tmpLocalesList == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
diff --git a/deps/icu-small/source/i18n/vtzone.cpp b/deps/icu-small/source/i18n/vtzone.cpp
index e39eada51b..bda3d1115e 100644
--- a/deps/icu-small/source/i18n/vtzone.cpp
+++ b/deps/icu-small/source/i18n/vtzone.cpp
@@ -965,7 +965,7 @@ VTimeZone::VTimeZone(const VTimeZone& source)
tzurl(source.tzurl), lastmod(source.lastmod),
olsonzid(source.olsonzid), icutzver(source.icutzver) {
if (source.tz != NULL) {
- tz = (BasicTimeZone*)source.tz->clone();
+ tz = source.tz->clone();
}
if (source.vtzlines != NULL) {
UErrorCode status = U_ZERO_ERROR;
@@ -1007,7 +1007,7 @@ VTimeZone::operator=(const VTimeZone& right) {
tz = NULL;
}
if (right.tz != NULL) {
- tz = (BasicTimeZone*)right.tz->clone();
+ tz = right.tz->clone();
}
if (vtzlines != NULL) {
delete vtzlines;
@@ -1092,7 +1092,7 @@ VTimeZone::createVTimeZoneFromBasicTimeZone(const BasicTimeZone& basic_time_zone
status = U_MEMORY_ALLOCATION_ERROR;
return NULL;
}
- vtz->tz = (BasicTimeZone *)basic_time_zone.clone();
+ vtz->tz = basic_time_zone.clone();
if (vtz->tz == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
delete vtz;
@@ -1177,8 +1177,8 @@ VTimeZone::writeSimple(UDate time, UnicodeString& result, UErrorCode& status) co
writeSimple(time, writer, status);
}
-TimeZone*
-VTimeZone::clone(void) const {
+VTimeZone*
+VTimeZone::clone() const {
return new VTimeZone(*this);
}
@@ -1957,7 +1957,7 @@ VTimeZone::writeZone(VTZWriter& w, BasicTimeZone& basictz,
&& (atzrule = dynamic_cast<const AnnualTimeZoneRule *>(tzt.getTo())) != NULL
&& atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR
) {
- finalDstRule = (AnnualTimeZoneRule*)tzt.getTo()->clone();
+ finalDstRule = atzrule->clone();
}
if (dstCount > 0) {
if (year == dstStartYear + dstCount
@@ -2008,7 +2008,7 @@ VTimeZone::writeZone(VTZWriter& w, BasicTimeZone& basictz,
&& (atzrule = dynamic_cast<const AnnualTimeZoneRule *>(tzt.getTo())) != NULL
&& atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR
) {
- finalStdRule = (AnnualTimeZoneRule*)tzt.getTo()->clone();
+ finalStdRule = atzrule->clone();
}
if (stdCount > 0) {
if (year == stdStartYear + stdCount
diff --git a/deps/icu-small/source/i18n/windtfmt.cpp b/deps/icu-small/source/i18n/windtfmt.cpp
index 983fd46c12..c35adc0987 100644
--- a/deps/icu-small/source/i18n/windtfmt.cpp
+++ b/deps/icu-small/source/i18n/windtfmt.cpp
@@ -213,7 +213,7 @@ Win32DateFormat &Win32DateFormat::operator=(const Win32DateFormat &other)
return *this;
}
-Format *Win32DateFormat::clone(void) const
+Win32DateFormat *Win32DateFormat::clone() const
{
return new Win32DateFormat(*this);
}
diff --git a/deps/icu-small/source/i18n/windtfmt.h b/deps/icu-small/source/i18n/windtfmt.h
index 43b6fe6dba..f13a1ae687 100644
--- a/deps/icu-small/source/i18n/windtfmt.h
+++ b/deps/icu-small/source/i18n/windtfmt.h
@@ -48,7 +48,7 @@ public:
virtual ~Win32DateFormat();
- virtual Format *clone(void) const;
+ virtual Win32DateFormat *clone() const;
Win32DateFormat &operator=(const Win32DateFormat &other);
diff --git a/deps/icu-small/source/i18n/winnmfmt.cpp b/deps/icu-small/source/i18n/winnmfmt.cpp
index b1724b62c2..1ae2310123 100644
--- a/deps/icu-small/source/i18n/winnmfmt.cpp
+++ b/deps/icu-small/source/i18n/winnmfmt.cpp
@@ -294,7 +294,7 @@ Win32NumberFormat &Win32NumberFormat::operator=(const Win32NumberFormat &other)
return *this;
}
-Format *Win32NumberFormat::clone(void) const
+Win32NumberFormat *Win32NumberFormat::clone() const
{
return new Win32NumberFormat(*this);
}
diff --git a/deps/icu-small/source/i18n/winnmfmt.h b/deps/icu-small/source/i18n/winnmfmt.h
index 7ea5da9170..8cf59ccf48 100644
--- a/deps/icu-small/source/i18n/winnmfmt.h
+++ b/deps/icu-small/source/i18n/winnmfmt.h
@@ -44,7 +44,7 @@ public:
virtual ~Win32NumberFormat();
- virtual Format *clone(void) const;
+ virtual Win32NumberFormat *clone() const;
Win32NumberFormat &operator=(const Win32NumberFormat &other);
diff --git a/deps/icu-small/source/i18n/zonemeta.cpp b/deps/icu-small/source/i18n/zonemeta.cpp
index 0e3ee89316..72c590f424 100644
--- a/deps/icu-small/source/i18n/zonemeta.cpp
+++ b/deps/icu-small/source/i18n/zonemeta.cpp
@@ -30,10 +30,7 @@
#include "olsontz.h"
#include "uinvchar.h"
-static icu::UMutex *gZoneMetaLock() {
- static icu::UMutex m = U_MUTEX_INITIALIZER;
- return &m;
-}
+static icu::UMutex gZoneMetaLock;
// CLDR Canonical ID mapping table
static UHashtable *gCanonicalIDCache = NULL;
@@ -266,11 +263,11 @@ ZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UErrorCode& status) {
}
// Check if it was already cached
- umtx_lock(gZoneMetaLock());
+ umtx_lock(&gZoneMetaLock);
{
canonicalID = (const UChar *)uhash_get(gCanonicalIDCache, utzid);
}
- umtx_unlock(gZoneMetaLock());
+ umtx_unlock(&gZoneMetaLock);
if (canonicalID != NULL) {
return canonicalID;
@@ -351,7 +348,7 @@ ZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UErrorCode& status) {
U_ASSERT(canonicalID != NULL); // canocanilD must be non-NULL here
// Put the resolved canonical ID to the cache
- umtx_lock(gZoneMetaLock());
+ umtx_lock(&gZoneMetaLock);
{
const UChar* idInCache = (const UChar *)uhash_get(gCanonicalIDCache, utzid);
if (idInCache == NULL) {
@@ -371,7 +368,7 @@ ZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UErrorCode& status) {
}
}
}
- umtx_unlock(gZoneMetaLock());
+ umtx_unlock(&gZoneMetaLock);
}
return canonicalID;
@@ -449,14 +446,14 @@ ZoneMeta::getCanonicalCountry(const UnicodeString &tzid, UnicodeString &country,
// Check if it was already cached
UBool cached = FALSE;
UBool singleZone = FALSE;
- umtx_lock(gZoneMetaLock());
+ umtx_lock(&gZoneMetaLock);
{
singleZone = cached = gSingleZoneCountries->contains((void*)region);
if (!cached) {
cached = gMultiZonesCountries->contains((void*)region);
}
}
- umtx_unlock(gZoneMetaLock());
+ umtx_unlock(&gZoneMetaLock);
if (!cached) {
// We need to go through all zones associated with the region.
@@ -475,7 +472,7 @@ ZoneMeta::getCanonicalCountry(const UnicodeString &tzid, UnicodeString &country,
delete ids;
// Cache the result
- umtx_lock(gZoneMetaLock());
+ umtx_lock(&gZoneMetaLock);
{
UErrorCode ec = U_ZERO_ERROR;
if (singleZone) {
@@ -488,7 +485,7 @@ ZoneMeta::getCanonicalCountry(const UnicodeString &tzid, UnicodeString &country,
}
}
}
- umtx_unlock(gZoneMetaLock());
+ umtx_unlock(&gZoneMetaLock);
}
if (singleZone) {
@@ -575,11 +572,11 @@ ZoneMeta::getMetazoneMappings(const UnicodeString &tzid) {
// get the mapping from cache
const UVector *result = NULL;
- umtx_lock(gZoneMetaLock());
+ umtx_lock(&gZoneMetaLock);
{
result = (UVector*) uhash_get(gOlsonToMeta, tzidUChars);
}
- umtx_unlock(gZoneMetaLock());
+ umtx_unlock(&gZoneMetaLock);
if (result != NULL) {
return result;
@@ -593,7 +590,7 @@ ZoneMeta::getMetazoneMappings(const UnicodeString &tzid) {
}
// put the new one into the cache
- umtx_lock(gZoneMetaLock());
+ umtx_lock(&gZoneMetaLock);
{
// make sure it's already created
result = (UVector*) uhash_get(gOlsonToMeta, tzidUChars);
@@ -621,7 +618,7 @@ ZoneMeta::getMetazoneMappings(const UnicodeString &tzid) {
delete tmpResult;
}
}
- umtx_unlock(gZoneMetaLock());
+ umtx_unlock(&gZoneMetaLock);
return result;
}
diff --git a/deps/icu-small/source/python/icutools/databuilder/filtration_schema.json b/deps/icu-small/source/python/icutools/databuilder/filtration_schema.json
new file mode 100644
index 0000000000..2b7ff99899
--- /dev/null
+++ b/deps/icu-small/source/python/icutools/databuilder/filtration_schema.json
@@ -0,0 +1,169 @@
+// Copyright (C) 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+{
+ "$id": "http://unicode.org/icu-filter-schema",
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "JSON Schema for an ICU data filter file",
+ "type": "object",
+ "properties": {
+ "strategy": {
+ "type": "string",
+ "enum": ["additive", "subtractive"]
+ },
+ "localeFilter": { "$ref": "#/definitions/filter" },
+ "featureFilters": {
+ "type": "object",
+ "additionalProperties": {
+ "oneOf": [
+ { "$ref": "#/definitions/filter" },
+ {
+ "type": "string",
+ "enum": ["include", "exclude"]
+ }
+ ]
+ }
+ },
+ "resourceFilters": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "categories": {
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "files": { "$ref": "#/definitions/filter" },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "pattern": "^[+-]/[\\S]*$"
+ }
+ }
+ },
+ "required": ["categories", "rules"],
+ "additionalProperties": false
+ }
+ },
+ "fileReplacements": {
+ "type": "object",
+ "properties": {
+ "directory": {
+ "type": "string",
+ "pattern": "^(\\$SRC|\\$FILTERS|\\$CWD|/$|/[^/]+)(/[^/]+)*$"
+ },
+ "replacements": {
+ "type": "array",
+ "items": {
+ "oneOf": [
+ { "type": "string" },
+ {
+ "type": "object",
+ "properties": {
+ "src": { "type": "string" },
+ "dest": { "type": "string" }
+ },
+ "additionalProperties": false,
+ "required": ["src", "dest"]
+ }
+ ]
+ }
+ }
+ },
+ "additionalProperties": false,
+ "required": ["directory", "replacements"]
+ },
+ "collationUCAData": {
+ "type": "string",
+ "enum": ["unihan", "implicithan"]
+ },
+ "usePoolBundle": {
+ "type": "boolean"
+ }
+ },
+ "additionalProperties": false,
+ "definitions": {
+ "filter": {
+ "type": "object",
+ "oneOf": [
+ {
+ "properties": {
+ "filterType": {
+ "$ref": "#/definitions/blacklistWhitelistFilterTypes"
+ },
+ "whitelist": { "$ref": "#/definitions/stringList" }
+ },
+ "required": ["whitelist"],
+ "additionalProperties": false
+ },
+ {
+ "properties": {
+ "filterType": {
+ "$ref": "#/definitions/blacklistWhitelistFilterTypes"
+ },
+ "blacklist": { "$ref": "#/definitions/stringList" }
+ },
+ "required": ["blacklist"],
+ "additionalProperties": false
+ },
+ {
+ "properties": {
+ "filterType": {
+ "type": "string",
+ "enum": ["exclude"]
+ }
+ },
+ "required": ["filterType"],
+ "additionalProperties": false
+ },
+ {
+ "properties": {
+ "filterType": {
+ "type": "string",
+ "enum": ["locale"]
+ },
+ "includeChildren": {
+ "type": "boolean"
+ },
+ "includeScripts": {
+ "type": "boolean"
+ },
+ "whitelist": { "$ref": "#/definitions/stringList" }
+ },
+ "required": ["filterType", "whitelist"],
+ "additionalProperties": false
+ },
+ {
+ "properties": {
+ "filterType": {
+ "type": "string",
+ "enum": ["union"]
+ },
+ "unionOf": {
+ "type": "array",
+ "items": { "$ref": "#/definitions/filter" }
+ }
+ },
+ "required": ["filterType", "unionOf"],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "blacklistWhitelistFilterTypes": {
+ "type": "string",
+ "enum": [
+ "language",
+ "regex"
+ ]
+ },
+ "stringList": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "minItems": 1,
+ "uniqueItems": true
+ }
+ }
+}
diff --git a/deps/icu-small/source/tools/genccode/genccode.c b/deps/icu-small/source/tools/genccode/genccode.c
index d35b589010..91e94d7f51 100644
--- a/deps/icu-small/source/tools/genccode/genccode.c
+++ b/deps/icu-small/source/tools/genccode/genccode.c
@@ -63,6 +63,7 @@ enum {
kOptHelpH = 0,
kOptHelpQuestionMark,
kOptDestDir,
+ kOptQuiet,
kOptName,
kOptEntryPoint,
#ifdef CAN_GENERATE_OBJECTS
@@ -77,6 +78,7 @@ static UOption options[]={
/*0*/UOPTION_HELP_H,
UOPTION_HELP_QUESTION_MARK,
UOPTION_DESTDIR,
+ UOPTION_QUIET,
UOPTION_DEF("name", 'n', UOPT_REQUIRES_ARG),
UOPTION_DEF("entrypoint", 'e', UOPT_REQUIRES_ARG),
#ifdef CAN_GENERATE_OBJECTS
@@ -116,6 +118,7 @@ main(int argc, char* argv[]) {
"options:\n"
"\t-h or -? or --help this usage text\n"
"\t-d or --destdir destination directory, followed by the path\n"
+ "\t-q or --quiet do not display warnings and progress\n"
"\t-n or --name symbol prefix, followed by the prefix\n"
"\t-e or --entrypoint entry point name, followed by the name (_dat will be appended)\n"
"\t-r or --revision Specify a version\n"
@@ -159,6 +162,9 @@ main(int argc, char* argv[]) {
writeCode = CALL_WRITECCODE;
/* TODO: remove writeCode=&writeCCode; */
}
+ if (options[kOptQuiet].doesOccur) {
+ verbose = FALSE;
+ }
while(--argc) {
filename=getLongPathname(argv[argc]);
if (verbose) {
@@ -170,13 +176,15 @@ main(int argc, char* argv[]) {
writeCCode(filename, options[kOptDestDir].value,
options[kOptName].doesOccur ? options[kOptName].value : NULL,
options[kOptFilename].doesOccur ? options[kOptFilename].value : NULL,
- NULL);
+ NULL,
+ 0);
break;
case CALL_WRITEASSEMBLY:
writeAssemblyCode(filename, options[kOptDestDir].value,
options[kOptEntryPoint].doesOccur ? options[kOptEntryPoint].value : NULL,
options[kOptFilename].doesOccur ? options[kOptFilename].value : NULL,
- NULL);
+ NULL,
+ 0);
break;
#ifdef CAN_GENERATE_OBJECTS
case CALL_WRITEOBJECT:
@@ -184,7 +192,8 @@ main(int argc, char* argv[]) {
options[kOptEntryPoint].doesOccur ? options[kOptEntryPoint].value : NULL,
options[kOptMatchArch].doesOccur ? options[kOptMatchArch].value : NULL,
options[kOptFilename].doesOccur ? options[kOptFilename].value : NULL,
- NULL);
+ NULL,
+ 0);
break;
#endif
default:
diff --git a/deps/icu-small/source/tools/genrb/derb.cpp b/deps/icu-small/source/tools/genrb/derb.cpp
index ac26d95be4..997b400129 100644
--- a/deps/icu-small/source/tools/genrb/derb.cpp
+++ b/deps/icu-small/source/tools/genrb/derb.cpp
@@ -631,7 +631,7 @@ static const char *getEncodingName(const char *encoding) {
if (!(enc = ucnv_getStandardName(encoding, "MIME", &err))) {
err = U_ZERO_ERROR;
if (!(enc = ucnv_getStandardName(encoding, "IANA", &err))) {
- ;
+ // do nothing
}
}
diff --git a/deps/icu-small/source/tools/genrb/filterrb.cpp b/deps/icu-small/source/tools/genrb/filterrb.cpp
index d62d185d77..dcc02fc621 100644
--- a/deps/icu-small/source/tools/genrb/filterrb.cpp
+++ b/deps/icu-small/source/tools/genrb/filterrb.cpp
@@ -23,6 +23,9 @@ ResKeyPath::ResKeyPath(const std::string& path, UErrorCode& status) {
status = U_PARSE_ERROR;
return;
}
+ if (path.length() == 1) {
+ return;
+ }
size_t i;
size_t j = 0;
while (true) {
diff --git a/deps/icu-small/source/tools/genrb/genrb.cpp b/deps/icu-small/source/tools/genrb/genrb.cpp
index 885f3039bf..6f3a13a0a6 100644
--- a/deps/icu-small/source/tools/genrb/genrb.cpp
+++ b/deps/icu-small/source/tools/genrb/genrb.cpp
@@ -205,10 +205,10 @@ main(int argc,
"\t-c or --copyright include copyright notice\n");
fprintf(stderr,
"\t-e or --encoding encoding of source files\n"
- "\t-d of --destdir destination directory, followed by the path, defaults to %s\n"
- "\t-s or --sourcedir source directory for files followed by path, defaults to %s\n"
+ "\t-d or --destdir destination directory, followed by the path, defaults to '%s'\n"
+ "\t-s or --sourcedir source directory for files followed by path, defaults to '%s'\n"
"\t-i or --icudatadir directory for locating any needed intermediate data files,\n"
- "\t followed by path, defaults to %s\n",
+ "\t followed by path, defaults to '%s'\n",
u_getDataDirectory(), u_getDataDirectory(), u_getDataDirectory());
fprintf(stderr,
"\t-j or --write-java write a Java ListResourceBundle for ICU4J, followed by optional encoding\n"
@@ -240,7 +240,7 @@ main(int argc,
"\t (--writePoolBundle and --usePoolBundle cannot be combined)\n");
fprintf(stderr,
"\t --filterDir Input directory where filter files are available.\n"
- "\t For more on filter files, see Python buildtool.\n");
+ "\t For more on filter files, see ICU Data Build Tool.\n");
return illegalArg ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
}
diff --git a/deps/icu-small/source/tools/genrb/parse.cpp b/deps/icu-small/source/tools/genrb/parse.cpp
index 884d5d5666..18a8c76dbc 100644
--- a/deps/icu-small/source/tools/genrb/parse.cpp
+++ b/deps/icu-small/source/tools/genrb/parse.cpp
@@ -274,11 +274,11 @@ expect(ParseState* state, enum ETokenType expectedToken, struct UString **tokenV
}
}
-static char *getInvariantString(ParseState* state, uint32_t *line, struct UString *comment, UErrorCode *status)
+static char *getInvariantString(ParseState* state, uint32_t *line, struct UString *comment,
+ int32_t &stringLength, UErrorCode *status)
{
struct UString *tokenValue;
char *result;
- uint32_t count;
expect(state, TOK_STRING, &tokenValue, comment, line, status);
@@ -287,14 +287,13 @@ static char *getInvariantString(ParseState* state, uint32_t *line, struct UStrin
return NULL;
}
- count = u_strlen(tokenValue->fChars);
- if(!uprv_isInvariantUString(tokenValue->fChars, count)) {
+ if(!uprv_isInvariantUString(tokenValue->fChars, tokenValue->fLength)) {
*status = U_INVALID_FORMAT_ERROR;
error(*line, "invariant characters required for table keys, binary data, etc.");
return NULL;
}
- result = static_cast<char *>(uprv_malloc(count+1));
+ result = static_cast<char *>(uprv_malloc(tokenValue->fLength+1));
if (result == NULL)
{
@@ -302,7 +301,8 @@ static char *getInvariantString(ParseState* state, uint32_t *line, struct UStrin
return NULL;
}
- u_UCharsToChars(tokenValue->fChars, result, count+1);
+ u_UCharsToChars(tokenValue->fChars, result, tokenValue->fLength+1);
+ stringLength = tokenValue->fLength;
return result;
}
@@ -1371,7 +1371,6 @@ parseIntVector(ParseState* state, char *tag, uint32_t startline, const struct US
int32_t value;
UBool readToken = FALSE;
char *stopstring;
- uint32_t len;
struct UString memberComments;
IntVectorResource *result = intvector_open(state->bundle, tag, comment, status);
@@ -1404,7 +1403,8 @@ parseIntVector(ParseState* state, char *tag, uint32_t startline, const struct US
return result;
}
- string = getInvariantString(state, NULL, NULL, status);
+ int32_t stringLength;
+ string = getInvariantString(state, NULL, NULL, stringLength, status);
if (U_FAILURE(*status))
{
@@ -1414,9 +1414,9 @@ parseIntVector(ParseState* state, char *tag, uint32_t startline, const struct US
/* For handling illegal char in the Intvector */
value = uprv_strtoul(string, &stopstring, 0);/* make intvector support decimal,hexdigit,octal digit ranging from -2^31-2^32-1*/
- len=(uint32_t)(stopstring-string);
+ int32_t len = (int32_t)(stopstring-string);
- if(len==uprv_strlen(string))
+ if(len==stringLength)
{
result->add(value, *status);
uprv_free(string);
@@ -1454,7 +1454,8 @@ static struct SResource *
parseBinary(ParseState* state, char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status)
{
uint32_t line;
- LocalMemory<char> string(getInvariantString(state, &line, NULL, status));
+ int32_t stringLength;
+ LocalMemory<char> string(getInvariantString(state, &line, NULL, stringLength, status));
if (string.isNull() || U_FAILURE(*status))
{
return NULL;
@@ -1470,46 +1471,45 @@ parseBinary(ParseState* state, char *tag, uint32_t startline, const struct UStri
printf(" binary %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline);
}
- uint32_t count = (uint32_t)uprv_strlen(string.getAlias());
- if (count > 0){
- if((count % 2)==0){
- LocalMemory<uint8_t> value;
- if (value.allocateInsteadAndCopy(count) == NULL)
- {
- *status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
- }
-
- char toConv[3] = {'\0', '\0', '\0'};
- for (uint32_t i = 0; i < count; i += 2)
- {
- toConv[0] = string[i];
- toConv[1] = string[i + 1];
+ LocalMemory<uint8_t> value;
+ int32_t count = 0;
+ if (stringLength > 0 && value.allocateInsteadAndCopy(stringLength) == NULL)
+ {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ return NULL;
+ }
- char *stopstring;
- value[i >> 1] = (uint8_t) uprv_strtoul(toConv, &stopstring, 16);
- uint32_t len=(uint32_t)(stopstring-toConv);
+ char toConv[3] = {'\0', '\0', '\0'};
+ for (int32_t i = 0; i < stringLength;)
+ {
+ // Skip spaces (which may have been line endings).
+ char c0 = string[i++];
+ if (c0 == ' ') { continue; }
+ if (i == stringLength) {
+ *status=U_INVALID_CHAR_FOUND;
+ error(line, "Encountered invalid binary value (odd number of hex digits)");
+ return NULL;
+ }
+ toConv[0] = c0;
+ toConv[1] = string[i++];
- if(len!=2)
- {
- *status=U_INVALID_CHAR_FOUND;
- return NULL;
- }
- }
+ char *stopstring;
+ value[count++] = (uint8_t) uprv_strtoul(toConv, &stopstring, 16);
+ uint32_t len=(uint32_t)(stopstring-toConv);
- return bin_open(state->bundle, tag, count >> 1, value.getAlias(), NULL, comment, status);
- }
- else
+ if(len!=2)
{
- *status = U_INVALID_CHAR_FOUND;
- error(line, "Encountered invalid binary value (length is odd)");
+ *status=U_INVALID_CHAR_FOUND;
+ error(line, "Encountered invalid binary value (not all pairs of hex digits)");
return NULL;
}
}
- else
- {
+
+ if (count == 0) {
warning(startline, "Encountered empty binary value");
return bin_open(state->bundle, tag, 0, NULL, "", comment, status);
+ } else {
+ return bin_open(state->bundle, tag, count, value.getAlias(), NULL, comment, status);
}
}
@@ -1520,9 +1520,9 @@ parseInteger(ParseState* state, char *tag, uint32_t startline, const struct UStr
int32_t value;
char *string;
char *stopstring;
- uint32_t len;
- string = getInvariantString(state, NULL, NULL, status);
+ int32_t stringLength;
+ string = getInvariantString(state, NULL, NULL, stringLength, status);
if (string == NULL || U_FAILURE(*status))
{
@@ -1541,7 +1541,7 @@ parseInteger(ParseState* state, char *tag, uint32_t startline, const struct UStr
printf(" integer %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline);
}
- if (uprv_strlen(string) <= 0)
+ if (stringLength == 0)
{
warning(startline, "Encountered empty integer. Default value is 0.");
}
@@ -1549,8 +1549,8 @@ parseInteger(ParseState* state, char *tag, uint32_t startline, const struct UStr
/* Allow integer support for hexdecimal, octal digit and decimal*/
/* and handle illegal char in the integer*/
value = uprv_strtoul(string, &stopstring, 0);
- len=(uint32_t)(stopstring-string);
- if(len==uprv_strlen(string))
+ int32_t len = (int32_t)(stopstring-string);
+ if(len==stringLength)
{
result = int_open(state->bundle, tag, value, comment, status);
}
@@ -1567,7 +1567,8 @@ static struct SResource *
parseImport(ParseState* state, char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status)
{
uint32_t line;
- LocalMemory<char> filename(getInvariantString(state, &line, NULL, status));
+ int32_t stringLength;
+ LocalMemory<char> filename(getInvariantString(state, &line, NULL, stringLength, status));
if (U_FAILURE(*status))
{
return NULL;
@@ -1628,12 +1629,11 @@ parseInclude(ParseState* state, char *tag, uint32_t startline, const struct UStr
UCHARBUF *ucbuf;
char *fullname = NULL;
- int32_t count = 0;
const char* cp = NULL;
const UChar* uBuffer = NULL;
- filename = getInvariantString(state, &line, NULL, status);
- count = (int32_t)uprv_strlen(filename);
+ int32_t stringLength;
+ filename = getInvariantString(state, &line, NULL, stringLength, status);
if (U_FAILURE(*status))
{
@@ -1652,7 +1652,7 @@ parseInclude(ParseState* state, char *tag, uint32_t startline, const struct UStr
printf(" include %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline);
}
- fullname = (char *) uprv_malloc(state->inputdirLength + count + 2);
+ fullname = (char *) uprv_malloc(state->inputdirLength + stringLength + 2);
/* test for NULL */
if(fullname == NULL)
{
diff --git a/deps/icu-small/source/tools/genrb/reslist.cpp b/deps/icu-small/source/tools/genrb/reslist.cpp
index bf57516047..3186c781e9 100644
--- a/deps/icu-small/source/tools/genrb/reslist.cpp
+++ b/deps/icu-small/source/tools/genrb/reslist.cpp
@@ -1371,7 +1371,7 @@ SRBRoot::compactKeys(UErrorCode &errorCode) {
}
int32_t keysCount = fUsePoolBundle->fKeysCount + fKeysCount;
- if (U_FAILURE(errorCode) || fKeysCount == 0 || fKeyMap != NULL) {
+ if (U_FAILURE(errorCode) || fKeyMap != NULL) {
return;
}
map = (KeyMapEntry *)uprv_malloc(keysCount * sizeof(KeyMapEntry));
diff --git a/deps/icu-small/source/tools/genrb/rle.c b/deps/icu-small/source/tools/genrb/rle.c
index 08495c2b4f..3d034f78ca 100644
--- a/deps/icu-small/source/tools/genrb/rle.c
+++ b/deps/icu-small/source/tools/genrb/rle.c
@@ -91,14 +91,14 @@ encodeRunByte(uint16_t* buffer,uint16_t* bufLimit, uint8_t value, int32_t length
return buffer;
}
-#define APPEND( buffer, bufLimit, value, num, status){ \
+#define APPEND( buffer, bufLimit, value, num, status) UPRV_BLOCK_MACRO_BEGIN { \
if(buffer<bufLimit){ \
*buffer++=(value); \
}else{ \
*status = U_BUFFER_OVERFLOW_ERROR; \
} \
num++; \
-}
+} UPRV_BLOCK_MACRO_END
/**
* Encode a run, possibly a degenerate run (of < 4 values).
diff --git a/deps/icu-small/source/tools/genrb/ustr.h b/deps/icu-small/source/tools/genrb/ustr.h
index 91483d1f0f..8a69e9d4d5 100644
--- a/deps/icu-small/source/tools/genrb/ustr.h
+++ b/deps/icu-small/source/tools/genrb/ustr.h
@@ -22,7 +22,7 @@
#include "unicode/utypes.h"
-#define U_APPEND_CHAR32(c,target,len) { \
+#define U_APPEND_CHAR32(c,target,len) UPRV_BLOCK_MACRO_BEGIN { \
if (c <= 0xffff) \
{ \
*(target)++ = (UChar) c; \
@@ -35,9 +35,9 @@
len=2; \
target +=2; \
} \
-}
+} UPRV_BLOCK_MACRO_END
-#define U_APPEND_CHAR32_ONLY(c,target) { \
+#define U_APPEND_CHAR32_ONLY(c,target) UPRV_BLOCK_MACRO_BEGIN { \
if (c <= 0xffff) \
{ \
*(target)++ = (UChar) c; \
@@ -48,7 +48,7 @@
target[1] = U16_TRAIL(c); \
target +=2; \
} \
-}
+} UPRV_BLOCK_MACRO_END
/* A C representation of a string "object" (to avoid realloc all the time) */
struct UString {
diff --git a/deps/icu-small/source/tools/pkgdata/pkgdata.cpp b/deps/icu-small/source/tools/pkgdata/pkgdata.cpp
index 9d512a3ae5..ad067c361f 100644
--- a/deps/icu-small/source/tools/pkgdata/pkgdata.cpp
+++ b/deps/icu-small/source/tools/pkgdata/pkgdata.cpp
@@ -122,8 +122,9 @@ enum {
QUIET,
WITHOUT_ASSEMBLY,
PDS_BUILD,
- UWP_BUILD,
- UWP_ARM_BUILD
+ WIN_UWP_BUILD,
+ WIN_DLL_ARCH,
+ WIN_DYNAMICBASE
};
/* This sets the modes that are available */
@@ -167,7 +168,8 @@ static UOption options[]={
/*20*/ UOPTION_DEF( "without-assembly", 'w', UOPT_NO_ARG),
/*21*/ UOPTION_DEF("zos-pds-build", 'z', UOPT_NO_ARG),
/*22*/ UOPTION_DEF("windows-uwp-build", 'u', UOPT_NO_ARG),
- /*23*/ UOPTION_DEF("windows-uwp-arm-build", 'a', UOPT_NO_ARG)
+ /*23*/ UOPTION_DEF("windows-DLL-arch", 'a', UOPT_REQUIRES_ARG),
+ /*24*/ UOPTION_DEF("windows-dynamicbase", 'b', UOPT_NO_ARG),
};
/* This enum and the following char array should be kept in sync. */
@@ -258,7 +260,8 @@ const char options_help[][320]={
"Build the data without assembly code",
"Build PDS dataset (zOS build only)",
"Build for Universal Windows Platform (Windows build only)",
- "Set DLL machine type for UWP to target windows ARM (Windows UWP build only)"
+ "Specify the DLL machine architecture for LINK.exe (Windows build only)",
+ "Ignored. Enable DYNAMICBASE on the DLL. This is now the default. (Windows build only)",
};
const char *progname = "PKGDATA";
@@ -468,6 +471,10 @@ main(int argc, char* argv[]) {
#endif
}
+ if (options[WIN_DYNAMICBASE].doesOccur) {
+ fprintf(stdout, "Note: Ignoring option -b (windows-dynamicbase).\n");
+ }
+
/* OK options are set up. Now the file lists. */
tail = NULL;
for( n=1; n<argc; n++) {
@@ -718,7 +725,13 @@ static int32_t pkg_executeOptions(UPKGOptions *o) {
if (genccodeAssembly &&
(uprv_strlen(genccodeAssembly)>3) &&
checkAssemblyHeaderName(genccodeAssembly+3)) {
- writeAssemblyCode(datFileNamePath, o->tmpDir, o->entryName, NULL, gencFilePath);
+ writeAssemblyCode(
+ datFileNamePath,
+ o->tmpDir,
+ o->entryName,
+ NULL,
+ gencFilePath,
+ sizeof(gencFilePath));
result = pkg_createWithAssemblyCode(targetDir, mode, gencFilePath);
if (result != 0) {
@@ -753,7 +766,14 @@ static int32_t pkg_executeOptions(UPKGOptions *o) {
/* Try to detect the arch type, use NULL if unsuccessful */
char optMatchArch[10] = { 0 };
pkg_createOptMatchArch(optMatchArch);
- writeObjectCode(datFileNamePath, o->tmpDir, o->entryName, (optMatchArch[0] == 0 ? NULL : optMatchArch), NULL, gencFilePath);
+ writeObjectCode(
+ datFileNamePath,
+ o->tmpDir,
+ o->entryName,
+ (optMatchArch[0] == 0 ? NULL : optMatchArch),
+ NULL,
+ gencFilePath,
+ sizeof(gencFilePath));
pkg_destroyOptMatchArch(optMatchArch);
#if U_PLATFORM_IS_LINUX_BASED
result = pkg_generateLibraryFile(targetDir, mode, gencFilePath);
@@ -1685,7 +1705,13 @@ static int32_t pkg_createWithoutAssemblyCode(UPKGOptions *o, const char *targetD
printf("# Generating %s \n", gencmnFile);
}
- writeCCode(file, o->tmpDir, dataName[0] != 0 ? dataName : o->shortName, newName[0] != 0 ? newName : NULL, gencmnFile);
+ writeCCode(
+ file,
+ o->tmpDir,
+ dataName[0] != 0 ? dataName : o->shortName,
+ newName[0] != 0 ? newName : NULL,
+ gencmnFile,
+ sizeof(gencmnFile));
#ifdef USE_SINGLE_CCODE_FILE
sprintf(cmd, "#include \"%s\"\n", gencmnFile);
@@ -1758,14 +1784,12 @@ static int32_t pkg_createWithoutAssemblyCode(UPKGOptions *o, const char *targetD
#ifdef WINDOWS_WITH_MSVC
#define LINK_CMD "link.exe /nologo /release /out:"
-#define LINK_FLAGS "/DLL /NOENTRY /MANIFEST:NO /implib:"
-#ifdef _WIN64
-#define LINK_EXTRA_UWP_FLAGS "/NXCOMPAT /DYNAMICBASE /APPCONTAINER "
-#else
-#define LINK_EXTRA_UWP_FLAGS "/NXCOMPAT /SAFESEH /DYNAMICBASE /APPCONTAINER /MACHINE:X86"
-#endif
-#define LINK_EXTRA_UWP_FLAGS_ARM "/NXCOMPAT /DYNAMICBASE /APPCONTAINER /MACHINE:ARM"
-#define LINK_EXTRA_NO_UWP_FLAGS "/base:0x4ad00000 "
+#define LINK_FLAGS "/NXCOMPAT /DYNAMICBASE /DLL /NOENTRY /MANIFEST:NO /implib:"
+
+#define LINK_EXTRA_UWP_FLAGS "/APPCONTAINER "
+#define LINK_EXTRA_UWP_FLAGS_X86_ONLY "/SAFESEH "
+
+#define LINK_EXTRA_FLAGS_MACHINE "/MACHINE:"
#define LIB_CMD "LIB.exe /nologo /out:"
#define LIB_FILE "icudt.lib"
#define LIB_EXT UDATA_LIB_SUFFIX
@@ -1845,23 +1869,23 @@ static int32_t pkg_createWindowsDLL(const char mode, const char *gencFilePath, U
return 0;
}
- char *extraFlags = "";
+ char extraFlags[SMALL_BUFFER_MAX_SIZE] = "";
#ifdef WINDOWS_WITH_MSVC
- if (options[UWP_BUILD].doesOccur)
- {
- if (options[UWP_ARM_BUILD].doesOccur)
- {
- extraFlags = LINK_EXTRA_UWP_FLAGS_ARM;
- }
- else
- {
- extraFlags = LINK_EXTRA_UWP_FLAGS;
+ if (options[WIN_UWP_BUILD].doesOccur) {
+ uprv_strcat(extraFlags, LINK_EXTRA_UWP_FLAGS);
+
+ if (options[WIN_DLL_ARCH].doesOccur) {
+ if (uprv_strcmp(options[WIN_DLL_ARCH].value, "X86") == 0) {
+ uprv_strcat(extraFlags, LINK_EXTRA_UWP_FLAGS_X86_ONLY);
+ }
}
}
- else
- {
- extraFlags = LINK_EXTRA_NO_UWP_FLAGS;
+
+ if (options[WIN_DLL_ARCH].doesOccur) {
+ uprv_strcat(extraFlags, LINK_EXTRA_FLAGS_MACHINE);
+ uprv_strcat(extraFlags, options[WIN_DLL_ARCH].value);
}
+
#endif
sprintf(cmd, "%s\"%s\" %s %s\"%s\" \"%s\" %s",
LINK_CMD,
diff --git a/deps/icu-small/source/tools/toolutil/filetools.cpp b/deps/icu-small/source/tools/toolutil/filetools.cpp
index 6e88c94b52..0f0e9c5984 100644
--- a/deps/icu-small/source/tools/toolutil/filetools.cpp
+++ b/deps/icu-small/source/tools/toolutil/filetools.cpp
@@ -65,7 +65,7 @@ isFileModTimeLater(const char *filePath, const char *checkAgainst, UBool isDir)
if (U_FAILURE(status)) {
fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, u_errorName(status));
return FALSE;
- };
+ }
if ((subDirp = opendir(newpath.data())) != NULL) {
/* If this new path is a directory, make a recursive call with the newpath. */
diff --git a/deps/icu-small/source/tools/toolutil/pkg_genc.cpp b/deps/icu-small/source/tools/toolutil/pkg_genc.cpp
index 2a8425e334..1a63eb0fa1 100644
--- a/deps/icu-small/source/tools/toolutil/pkg_genc.cpp
+++ b/deps/icu-small/source/tools/toolutil/pkg_genc.cpp
@@ -48,6 +48,8 @@
#include "uoptions.h"
#include "pkg_genc.h"
#include "filetools.h"
+#include "charstr.h"
+#include "unicode/errorcode.h"
#define MAX_COLUMN ((uint32_t)(0xFFFFFFFFU))
@@ -56,7 +58,15 @@
/* prototypes --------------------------------------------------------------- */
static void
-getOutFilename(const char *inFilename, const char *destdir, char *outFilename, char *entryName, const char *newSuffix, const char *optFilename);
+getOutFilename(
+ const char *inFilename,
+ const char *destdir,
+ char *outFilename,
+ int32_t outFilenameCapacity,
+ char *entryName,
+ int32_t entryNameCapacity,
+ const char *newSuffix,
+ const char *optFilename);
static uint32_t
write8(FileStream *out, uint8_t byte, uint32_t column);
@@ -259,13 +269,21 @@ printAssemblyHeadersToStdErr(void) {
}
U_CAPI void U_EXPORT2
-writeAssemblyCode(const char *filename, const char *destdir, const char *optEntryPoint, const char *optFilename, char *outFilePath) {
+writeAssemblyCode(
+ const char *filename,
+ const char *destdir,
+ const char *optEntryPoint,
+ const char *optFilename,
+ char *outFilePath,
+ size_t outFilePathCapacity) {
uint32_t column = MAX_COLUMN;
- char entry[64];
- uint32_t buffer[1024];
- char *bufferStr = (char *)buffer;
+ char entry[96];
+ union {
+ uint32_t uint32s[1024];
+ char chars[4096];
+ } buffer;
FileStream *in, *out;
- size_t i, length;
+ size_t i, length, count;
in=T_FileStream_open(filename, "rb");
if(in==NULL) {
@@ -273,15 +291,27 @@ writeAssemblyCode(const char *filename, const char *destdir, const char *optEntr
exit(U_FILE_ACCESS_ERROR);
}
- getOutFilename(filename, destdir, bufferStr, entry, ".S", optFilename);
- out=T_FileStream_open(bufferStr, "w");
+ getOutFilename(
+ filename,
+ destdir,
+ buffer.chars,
+ sizeof(buffer.chars),
+ entry,
+ sizeof(entry),
+ ".S",
+ optFilename);
+ out=T_FileStream_open(buffer.chars, "w");
if(out==NULL) {
- fprintf(stderr, "genccode: unable to open output file %s\n", bufferStr);
+ fprintf(stderr, "genccode: unable to open output file %s\n", buffer.chars);
exit(U_FILE_ACCESS_ERROR);
}
if (outFilePath != NULL) {
- uprv_strcpy(outFilePath, bufferStr);
+ if (uprv_strlen(buffer.chars) >= outFilePathCapacity) {
+ fprintf(stderr, "genccode: filename too long\n");
+ exit(U_ILLEGAL_ARGUMENT_ERROR);
+ }
+ uprv_strcpy(outFilePath, buffer.chars);
}
#if defined (WINDOWS_WITH_GNUC) && U_PLATFORM != U_PF_CYGWIN
@@ -302,29 +332,42 @@ writeAssemblyCode(const char *filename, const char *destdir, const char *optEntr
}
}
- sprintf(bufferStr, assemblyHeader[assemblyHeaderIndex].header,
+ count = snprintf(
+ buffer.chars, sizeof(buffer.chars),
+ assemblyHeader[assemblyHeaderIndex].header,
entry, entry, entry, entry,
entry, entry, entry, entry);
- T_FileStream_writeLine(out, bufferStr);
+ if (count >= sizeof(buffer.chars)) {
+ fprintf(stderr, "genccode: entry name too long (long filename?)\n");
+ exit(U_ILLEGAL_ARGUMENT_ERROR);
+ }
+ T_FileStream_writeLine(out, buffer.chars);
T_FileStream_writeLine(out, assemblyHeader[assemblyHeaderIndex].beginLine);
for(;;) {
- memset(buffer, 0, sizeof(buffer));
- length=T_FileStream_read(in, buffer, sizeof(buffer));
+ memset(buffer.uint32s, 0, sizeof(buffer.uint32s));
+ length=T_FileStream_read(in, buffer.uint32s, sizeof(buffer.uint32s));
if(length==0) {
break;
}
- for(i=0; i<(length/sizeof(buffer[0])); i++) {
- column = write32(out, buffer[i], column);
+ for(i=0; i<(length/sizeof(buffer.uint32s[0])); i++) {
+ // TODO: What if the last read sees length not as a multiple of 4?
+ column = write32(out, buffer.uint32s[i], column);
}
}
T_FileStream_writeLine(out, "\n");
- sprintf(bufferStr, assemblyHeader[assemblyHeaderIndex].footer,
+ count = snprintf(
+ buffer.chars, sizeof(buffer.chars),
+ assemblyHeader[assemblyHeaderIndex].footer,
entry, entry, entry, entry,
entry, entry, entry, entry);
- T_FileStream_writeLine(out, bufferStr);
+ if (count >= sizeof(buffer.chars)) {
+ fprintf(stderr, "genccode: entry name too long (long filename?)\n");
+ exit(U_ILLEGAL_ARGUMENT_ERROR);
+ }
+ T_FileStream_writeLine(out, buffer.chars);
if(T_FileStream_error(in)) {
fprintf(stderr, "genccode: file read error while generating from file %s\n", filename);
@@ -341,11 +384,17 @@ writeAssemblyCode(const char *filename, const char *destdir, const char *optEntr
}
U_CAPI void U_EXPORT2
-writeCCode(const char *filename, const char *destdir, const char *optName, const char *optFilename, char *outFilePath) {
+writeCCode(
+ const char *filename,
+ const char *destdir,
+ const char *optName,
+ const char *optFilename,
+ char *outFilePath,
+ size_t outFilePathCapacity) {
uint32_t column = MAX_COLUMN;
- char buffer[4096], entry[64];
+ char buffer[4096], entry[96];
FileStream *in, *out;
- size_t i, length;
+ size_t i, length, count;
in=T_FileStream_open(filename, "rb");
if(in==NULL) {
@@ -354,16 +403,35 @@ writeCCode(const char *filename, const char *destdir, const char *optName, const
}
if(optName != NULL) { /* prepend 'icudt28_' */
- strcpy(entry, optName);
- strcat(entry, "_");
+ // +2 includes the _ and the NUL
+ if (uprv_strlen(optName) + 2 > sizeof(entry)) {
+ fprintf(stderr, "genccode: entry name too long (long filename?)\n");
+ exit(U_ILLEGAL_ARGUMENT_ERROR);
+ }
+ strcpy(entry, optName);
+ strcat(entry, "_");
} else {
- entry[0] = 0;
+ entry[0] = 0;
}
- getOutFilename(filename, destdir, buffer, entry+uprv_strlen(entry), ".c", optFilename);
+ getOutFilename(
+ filename,
+ destdir,
+ buffer,
+ sizeof(buffer),
+ entry + uprv_strlen(entry),
+ sizeof(entry) - uprv_strlen(entry),
+ ".c",
+ optFilename);
+
if (outFilePath != NULL) {
+ if (uprv_strlen(buffer) >= outFilePathCapacity) {
+ fprintf(stderr, "genccode: filename too long\n");
+ exit(U_ILLEGAL_ARGUMENT_ERROR);
+ }
uprv_strcpy(outFilePath, buffer);
}
+
out=T_FileStream_open(buffer, "w");
if(out==NULL) {
fprintf(stderr, "genccode: unable to open output file %s\n", buffer);
@@ -391,7 +459,7 @@ writeCCode(const char *filename, const char *destdir, const char *optName, const
magic numbers we must still use the initial double.
[grhoten 4/24/2003]
*/
- sprintf(buffer,
+ count = snprintf(buffer, sizeof(buffer),
"#ifndef IN_GENERATED_CCODE\n"
"#define IN_GENERATED_CCODE\n"
"#define U_DISABLE_RENAMING 1\n"
@@ -403,6 +471,10 @@ writeCCode(const char *filename, const char *destdir, const char *optName, const
" const char *bytes; \n"
"} %s={ 0.0, \n",
entry);
+ if (count >= sizeof(buffer)) {
+ fprintf(stderr, "genccode: entry name too long (long filename?)\n");
+ exit(U_ILLEGAL_ARGUMENT_ERROR);
+ }
T_FileStream_writeLine(out, buffer);
for(;;) {
@@ -418,7 +490,7 @@ writeCCode(const char *filename, const char *destdir, const char *optName, const
T_FileStream_writeLine(out, "\"\n};\nU_CDECL_END\n");
#else
/* Function renaming shouldn't be done in data */
- sprintf(buffer,
+ count = snprintf(buffer, sizeof(buffer),
"#ifndef IN_GENERATED_CCODE\n"
"#define IN_GENERATED_CCODE\n"
"#define U_DISABLE_RENAMING 1\n"
@@ -430,6 +502,10 @@ writeCCode(const char *filename, const char *destdir, const char *optName, const
" uint8_t bytes[%ld]; \n"
"} %s={ 0.0, {\n",
(long)T_FileStream_size(in), entry);
+ if (count >= sizeof(buffer)) {
+ fprintf(stderr, "genccode: entry name too long (long filename?)\n");
+ exit(U_ILLEGAL_ARGUMENT_ERROR);
+ }
T_FileStream_writeLine(out, buffer);
for(;;) {
@@ -583,66 +659,84 @@ write8str(FileStream *out, uint8_t byte, uint32_t column) {
#endif
static void
-getOutFilename(const char *inFilename, const char *destdir, char *outFilename, char *entryName, const char *newSuffix, const char *optFilename) {
+getOutFilename(
+ const char *inFilename,
+ const char *destdir,
+ char *outFilename,
+ int32_t outFilenameCapacity,
+ char *entryName,
+ int32_t entryNameCapacity,
+ const char *newSuffix,
+ const char *optFilename) {
const char *basename=findBasename(inFilename), *suffix=uprv_strrchr(basename, '.');
+ icu::CharString outFilenameBuilder;
+ icu::CharString entryNameBuilder;
+ icu::ErrorCode status;
+
/* copy path */
if(destdir!=NULL && *destdir!=0) {
- do {
- *outFilename++=*destdir++;
- } while(*destdir!=0);
- if(*(outFilename-1)!=U_FILE_SEP_CHAR) {
- *outFilename++=U_FILE_SEP_CHAR;
- }
- inFilename=basename;
+ outFilenameBuilder.append(destdir, status);
+ outFilenameBuilder.ensureEndsWithFileSeparator(status);
} else {
- while(inFilename<basename) {
- *outFilename++=*inFilename++;
- }
+ outFilenameBuilder.append(inFilename, basename - inFilename, status);
}
+ inFilename=basename;
if(suffix==NULL) {
/* the filename does not have a suffix */
- uprv_strcpy(entryName, inFilename);
+ entryNameBuilder.append(inFilename, status);
if(optFilename != NULL) {
- uprv_strcpy(outFilename, optFilename);
+ outFilenameBuilder.append(optFilename, status);
} else {
- uprv_strcpy(outFilename, inFilename);
+ outFilenameBuilder.append(inFilename, status);
}
- uprv_strcat(outFilename, newSuffix);
+ outFilenameBuilder.append(newSuffix, status);
} else {
- char *saveOutFilename = outFilename;
+ int32_t saveOutFilenameLength = outFilenameBuilder.length();
/* copy basename */
while(inFilename<suffix) {
- if(*inFilename=='-') {
- /* iSeries cannot have '-' in the .o objects. */
- *outFilename++=*entryName++='_';
- inFilename++;
- }
- else {
- *outFilename++=*entryName++=*inFilename++;
- }
+ // iSeries cannot have '-' in the .o objects.
+ char c = (*inFilename=='-') ? '_' : *inFilename;
+ outFilenameBuilder.append(c, status);
+ entryNameBuilder.append(c, status);
+ inFilename++;
}
/* replace '.' by '_' */
- *outFilename++=*entryName++='_';
+ outFilenameBuilder.append('_', status);
+ entryNameBuilder.append('_', status);
++inFilename;
/* copy suffix */
- while(*inFilename!=0) {
- *outFilename++=*entryName++=*inFilename++;
- }
-
- *entryName=0;
+ outFilenameBuilder.append(inFilename, status);
+ entryNameBuilder.append(inFilename, status);
if(optFilename != NULL) {
- uprv_strcpy(saveOutFilename, optFilename);
- uprv_strcat(saveOutFilename, newSuffix);
- } else {
- /* add ".c" */
- uprv_strcpy(outFilename, newSuffix);
+ outFilenameBuilder.truncate(saveOutFilenameLength);
+ outFilenameBuilder.append(optFilename, status);
}
+ // add ".c"
+ outFilenameBuilder.append(newSuffix, status);
+ }
+
+ if (status.isFailure()) {
+ fprintf(stderr, "genccode: error building filename or entrypoint\n");
+ exit(status.get());
}
+
+ if (outFilenameBuilder.length() >= outFilenameCapacity) {
+ fprintf(stderr, "genccode: output filename too long\n");
+ exit(U_ILLEGAL_ARGUMENT_ERROR);
+ }
+
+ if (entryNameBuilder.length() >= entryNameCapacity) {
+ fprintf(stderr, "genccode: entry name too long (long filename?)\n");
+ exit(U_ILLEGAL_ARGUMENT_ERROR);
+ }
+
+ uprv_strcpy(outFilename, outFilenameBuilder.data());
+ uprv_strcpy(entryName, entryNameBuilder.data());
}
#ifdef CAN_GENERATE_OBJECTS
@@ -777,7 +871,14 @@ getArchitecture(uint16_t *pCPU, uint16_t *pBits, UBool *pIsBigEndian, const char
}
U_CAPI void U_EXPORT2
-writeObjectCode(const char *filename, const char *destdir, const char *optEntryPoint, const char *optMatchArch, const char *optFilename, char *outFilePath) {
+writeObjectCode(
+ const char *filename,
+ const char *destdir,
+ const char *optEntryPoint,
+ const char *optMatchArch,
+ const char *optFilename,
+ char *outFilePath,
+ size_t outFilePathCapacity) {
/* common variables */
char buffer[4096], entry[96]={ 0 };
FileStream *in, *out;
@@ -1061,8 +1162,21 @@ writeObjectCode(const char *filename, const char *destdir, const char *optEntryP
}
size=T_FileStream_size(in);
- getOutFilename(filename, destdir, buffer, entry+entryOffset, newSuffix, optFilename);
+ getOutFilename(
+ filename,
+ destdir,
+ buffer,
+ sizeof(buffer),
+ entry + entryOffset,
+ sizeof(entry) - entryOffset,
+ newSuffix,
+ optFilename);
+
if (outFilePath != NULL) {
+ if (uprv_strlen(buffer) >= outFilePathCapacity) {
+ fprintf(stderr, "genccode: filename too long\n");
+ exit(U_ILLEGAL_ARGUMENT_ERROR);
+ }
uprv_strcpy(outFilePath, buffer);
}
diff --git a/deps/icu-small/source/tools/toolutil/pkg_genc.h b/deps/icu-small/source/tools/toolutil/pkg_genc.h
index 5039f27db5..47e8304a68 100644
--- a/deps/icu-small/source/tools/toolutil/pkg_genc.h
+++ b/deps/icu-small/source/tools/toolutil/pkg_genc.h
@@ -75,12 +75,31 @@ U_INTERNAL UBool U_EXPORT2
checkAssemblyHeaderName(const char* optAssembly);
U_INTERNAL void U_EXPORT2
-writeCCode(const char *filename, const char *destdir, const char *optName, const char *optFilename, char *outFilePath);
+writeCCode(
+ const char *filename,
+ const char *destdir,
+ const char *optName,
+ const char *optFilename,
+ char *outFilePath,
+ size_t outFilePathCapacity);
U_INTERNAL void U_EXPORT2
-writeAssemblyCode(const char *filename, const char *destdir, const char *optEntryPoint, const char *optFilename, char *outFilePath);
+writeAssemblyCode(
+ const char *filename,
+ const char *destdir,
+ const char *optEntryPoint,
+ const char *optFilename,
+ char *outFilePath,
+ size_t outFilePathCapacity);
U_INTERNAL void U_EXPORT2
-writeObjectCode(const char *filename, const char *destdir, const char *optEntryPoint, const char *optMatchArch, const char *optFilename, char *outFilePath);
+writeObjectCode(
+ const char *filename,
+ const char *destdir,
+ const char *optEntryPoint,
+ const char *optMatchArch,
+ const char *optFilename,
+ char *outFilePath,
+ size_t outFilePathCapacity);
#endif
diff --git a/deps/icu-small/source/tools/toolutil/pkgitems.cpp b/deps/icu-small/source/tools/toolutil/pkgitems.cpp
index dd414c2f87..b0ea980d60 100644
--- a/deps/icu-small/source/tools/toolutil/pkgitems.cpp
+++ b/deps/icu-small/source/tools/toolutil/pkgitems.cpp
@@ -305,7 +305,8 @@ ures_enumDependencies(const char *itemName,
break;
}
int32_t length;
- const UChar *alias=res_getString(pResData, res, &length);
+ // No tracing: build tool
+ const UChar *alias=res_getStringNoTrace(pResData, res, &length);
checkAlias(itemName, res, alias, length, useResSuffix, check, context, pErrorCode);
}
break;
diff --git a/deps/icu-small/source/tools/toolutil/toolutil.cpp b/deps/icu-small/source/tools/toolutil/toolutil.cpp
index 21dca7fe5d..25f9c116ee 100644
--- a/deps/icu-small/source/tools/toolutil/toolutil.cpp
+++ b/deps/icu-small/source/tools/toolutil/toolutil.cpp
@@ -243,7 +243,7 @@ struct UToolMemory {
char name[64];
int32_t capacity, maxCapacity, size, idx;
void *array;
- UAlignedMemory staticArray[1];
+ alignas(max_align_t) char staticArray[1];
};
U_CAPI UToolMemory * U_EXPORT2
diff --git a/deps/icu-small/source/tools/toolutil/ucbuf.h b/deps/icu-small/source/tools/toolutil/ucbuf.h
index 48d41ef4cd..7a9b7af5cc 100644
--- a/deps/icu-small/source/tools/toolutil/ucbuf.h
+++ b/deps/icu-small/source/tools/toolutil/ucbuf.h
@@ -32,11 +32,11 @@ typedef struct UCHARBUF UCHARBUF;
/**
* End of file value
*/
-#define U_EOF 0xFFFFFFFF
+#define U_EOF ((int32_t)0xFFFFFFFF)
/**
* Error value if a sequence cannot be unescaped
*/
-#define U_ERR 0xFFFFFFFE
+#define U_ERR ((int32_t)0xFFFFFFFE)
typedef struct ULine ULine;
diff --git a/deps/icu-small/source/tools/toolutil/xmlparser.cpp b/deps/icu-small/source/tools/toolutil/xmlparser.cpp
index ae7ef17020..e3d5b42ef4 100644
--- a/deps/icu-small/source/tools/toolutil/xmlparser.cpp
+++ b/deps/icu-small/source/tools/toolutil/xmlparser.cpp
@@ -313,7 +313,7 @@ UXMLParser::parseFile(const char *filename, UErrorCode &errorCode) {
// reached end of file, convert once more to flush the converter
flush=TRUE;
}
- };
+ }
exit:
ucnv_close(cnv);
diff --git a/tools/icu/current_ver.dep b/tools/icu/current_ver.dep
index 2d467a6fd0..2980335bdd 100644
--- a/tools/icu/current_ver.dep
+++ b/tools/icu/current_ver.dep
@@ -1,6 +1,6 @@
[
{
- "url": "https://github.com/unicode-org/icu/releases/download/release-64-2/icu4c-64_2-src.tgz",
- "md5": "a3d18213beec454e3cdec9a3116d6b05"
+ "url": "https://github.com/unicode-org/icu/releases/download/release-65-1/icu4c-65_1-src.tgz",
+ "md5": "d1ff436e26cabcb28e6cb383d32d1339"
}
]