diff options
Diffstat (limited to 'intl/icu-patches')
-rw-r--r-- | intl/icu-patches/bug-1198952-workaround-make-3.82-bug.diff | 42 | ||||
-rw-r--r-- | intl/icu-patches/bug-1614941-dsb-hsb-dates.diff | 62 | ||||
-rw-r--r-- | intl/icu-patches/bug-1636984-append-item-dayperiod-fractional-seconds.diff | 86 | ||||
-rw-r--r-- | intl/icu-patches/bug-1636984-display-name-fractional-seconds.diff | 39 | ||||
-rw-r--r-- | intl/icu-patches/bug-1706949-wasi-workaround.diff | 757 | ||||
-rw-r--r-- | intl/icu-patches/bug-1790071-ICU-22132-standardize-vtzone-output.diff | 28 | ||||
-rw-r--r-- | intl/icu-patches/bug-1792775-ICU-22198.diff | 19 | ||||
-rw-r--r-- | intl/icu-patches/bug-1792775-ICU-22206.diff | 351 | ||||
-rw-r--r-- | intl/icu-patches/bug-915735 | 28 | ||||
-rw-r--r-- | intl/icu-patches/suppress-warnings.diff | 80 |
10 files changed, 1492 insertions, 0 deletions
diff --git a/intl/icu-patches/bug-1198952-workaround-make-3.82-bug.diff b/intl/icu-patches/bug-1198952-workaround-make-3.82-bug.diff new file mode 100644 index 0000000000..dc4f4e2692 --- /dev/null +++ b/intl/icu-patches/bug-1198952-workaround-make-3.82-bug.diff @@ -0,0 +1,42 @@ +diff --git a/intl/icu/source/Makefile.in b/intl/icu/source/Makefile.in +--- a/intl/icu/source/Makefile.in ++++ b/intl/icu/source/Makefile.in +@@ -134,32 +134,36 @@ endif + + LOCAL_SUBDIRS = $(SUBDIRS) + CLEAN_FIRST_SUBDIRS = $(TOOLS) + + $(LIBDIR) $(BINDIR): + -$(MKINSTALLDIRS) $@ + + ## Recursive targets ++## Strictly speaking, the $(MAKEOVERRIDES) is not necessary when recursing, but ++## there is a bug in GNU make 3.82 that throws away the original overrides in ++## favor of RECURSIVE=YES when the submake in the subdirectory restarts itself ++## after dependency files have been created. + all-recursive install-recursive clean-recursive distclean-recursive dist-recursive check-recursive check-exhaustive-recursive: $(LIBDIR) $(BINDIR) + ifneq ($(NEED_ESCAPING),) + @echo "building tools/escapesrc (Needed for this platform with NEED_ESCAPING)" +- @(cd tools/escapesrc && $(MAKE) RECURSIVE=YES $$local_target) || exit ++ @(cd tools/escapesrc && $(MAKE) $(MAKEOVERRIDES) RECURSIVE=YES $$local_target) || exit + endif + @dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(LOCAL_SUBDIRS)'; for subdir in $$list; do \ + echo "$(MAKE)[$(MAKELEVEL)]: Making \`$$target' in \`$$subdir'"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-local"; \ + else \ + local_target="$$target"; \ + fi; \ +- (cd $$subdir && $(MAKE) RECURSIVE=YES $$local_target) || exit; \ ++ (cd $$subdir && $(MAKE) $(MAKEOVERRIDES) RECURSIVE=YES $$local_target) || exit; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) "$$target-local" || exit; \ + fi + + clean-recursive-with-twist: + $(MAKE) clean-recursive LOCAL_SUBDIRS='$(CLEAN_FIRST_SUBDIRS) $(filter-out $(CLEAN_FIRST_SUBDIRS),$(LOCAL_SUBDIRS))' + diff --git a/intl/icu-patches/bug-1614941-dsb-hsb-dates.diff b/intl/icu-patches/bug-1614941-dsb-hsb-dates.diff new file mode 100644 index 0000000000..222b1e4678 --- /dev/null +++ b/intl/icu-patches/bug-1614941-dsb-hsb-dates.diff @@ -0,0 +1,62 @@ +diff --git a/intl/icu/source/data/locales/dsb.txt b/intl/icu/source/data/locales/dsb.txt +--- a/intl/icu/source/data/locales/dsb.txt ++++ b/intl/icu/source/data/locales/dsb.txt +@@ -547,23 +547,27 @@ dsb{ + other{"W. 'tyźeń' MMMM"} + two{"W. 'tyźeń' MMMM"} + } + MMMMd{"d. MMMM"} + MMMd{"d. MMM"} ++ MMd{"d. MM"} ++ MMdd{"dd. MM"} + Md{"d.M."} + d{"d."} + h{"h a"} + hm{"h:mm a"} + hms{"h:mm:ss a"} + ms{"mm:ss"} + y{"y"} + yM{"M.y"} + yMEd{"E, d.M.y"} ++ yMM{"MM y"} + yMMM{"MMM y"} + yMMMEd{"E, d. MMM y"} + yMMMM{"LLLL y"} + yMMMd{"d. MMM y"} ++ yMMdd{"dd. MM y"} + yMd{"d.M.y"} + yQQQ{"QQQ y"} + yQQQQ{"QQQQ y"} + yw{ + few{"w. 'tyźeń' 'lěta' Y"} +diff --git a/intl/icu/source/data/locales/hsb.txt b/intl/icu/source/data/locales/hsb.txt +--- a/intl/icu/source/data/locales/hsb.txt ++++ b/intl/icu/source/data/locales/hsb.txt +@@ -546,23 +546,27 @@ hsb{ + other{"W. 'tydźeń' MMMM"} + two{"W. 'tydźeń' MMMM"} + } + MMMMd{"d. MMMM"} + MMMd{"d. MMM"} ++ MMd{"d. MM"} ++ MMdd{"dd. MM"} + Md{"d.M."} + d{"d."} + h{"h a"} + hm{"h:mm a"} + hms{"h:mm:ss a"} + ms{"mm:ss"} + y{"y"} + yM{"M.y"} + yMEd{"E, d.M.y"} ++ yMM{"MM y"} + yMMM{"MMM y"} + yMMMEd{"E, d. MMM y"} + yMMMM{"LLLL y"} + yMMMd{"d. MMM y"} ++ yMMdd{"dd. MM y"} + yMd{"d.M.y"} + yQQQ{"QQQ y"} + yQQQQ{"QQQQ y"} + yw{ + few{"w. 'tydźeń' 'lěta' Y"} diff --git a/intl/icu-patches/bug-1636984-append-item-dayperiod-fractional-seconds.diff b/intl/icu-patches/bug-1636984-append-item-dayperiod-fractional-seconds.diff new file mode 100644 index 0000000000..32ba468950 --- /dev/null +++ b/intl/icu-patches/bug-1636984-append-item-dayperiod-fractional-seconds.diff @@ -0,0 +1,86 @@ +# Add <appendItem> entries for "DayPeriod" and "FractionalSeconds" to avoid the +# "├ ┤" parentheses from ICU and instead use the normal "( )" parentheses. +# +# CLDR bug: https://unicode-org.atlassian.net/browse/CLDR-13184 + +diff --git a/intl/icu/source/data/locales/root.txt b/intl/icu/source/data/locales/root.txt +--- a/intl/icu/source/data/locales/root.txt ++++ b/intl/icu/source/data/locales/root.txt +@@ -213,17 +213,19 @@ root{ + } + NoonMarker:alias{"/LOCALE/calendar/gregorian/NoonMarker"} + NoonMarkerNarrow:alias{"/LOCALE/calendar/gregorian/NoonMarkerNarrow"} + appendItems{ + Day{"{0} ({2}: {1})"} ++ DayPeriod{"{0} ({2}: {1})"} + Day-Of-Week{"{0} {1}"} + Era{"{1} {0}"} + Hour{"{0} ({2}: {1})"} + Minute{"{0} ({2}: {1})"} + Month{"{0} ({2}: {1})"} + Quarter{"{0} ({2}: {1})"} + Second{"{0} ({2}: {1})"} ++ FractionalSecond{"{0} ({2}: {1})"} + Timezone{"{0} {1}"} + Week{"{0} ({2}: {1})"} + Year{"{1} {0}"} + } + availableFormats{ +@@ -749,17 +751,19 @@ root{ + } + NoonMarker:alias{"/LOCALE/calendar/gregorian/NoonMarker"} + NoonMarkerNarrow:alias{"/LOCALE/calendar/gregorian/NoonMarkerNarrow"} + appendItems{ + Day{"{0} ({2}: {1})"} ++ DayPeriod{"{0} ({2}: {1})"} + Day-Of-Week{"{0} {1}"} + Era{"{1} {0}"} + Hour{"{0} ({2}: {1})"} + Minute{"{0} ({2}: {1})"} + Month{"{0} ({2}: {1})"} + Quarter{"{0} ({2}: {1})"} + Second{"{0} ({2}: {1})"} ++ FractionalSecond{"{0} ({2}: {1})"} + Timezone{"{0} {1}"} + Week{"{0} ({2}: {1})"} + Year{"{1} {0}"} + } + availableFormats{ +@@ -1018,17 +1022,19 @@ root{ + "{1} {0}", + "{1} {0}", + } + appendItems{ + Day{"{0} ({2}: {1})"} ++ DayPeriod{"{0} ({2}: {1})"} + Day-Of-Week{"{0} {1}"} + Era{"{1} {0}"} + Hour{"{0} ({2}: {1})"} + Minute{"{0} ({2}: {1})"} + Month{"{0} ({2}: {1})"} + Quarter{"{0} ({2}: {1})"} + Second{"{0} ({2}: {1})"} ++ FractionalSecond{"{0} ({2}: {1})"} + Timezone{"{0} {1}"} + Week{"{0} ({2}: {1})"} + Year{"{1} {0}"} + } + availableFormats{ +diff --git a/intl/icu/source/i18n/dtptngen.cpp b/intl/icu/source/i18n/dtptngen.cpp +--- a/intl/icu/source/i18n/dtptngen.cpp ++++ b/intl/icu/source/i18n/dtptngen.cpp +@@ -257,12 +257,12 @@ static const dtTypeElem dtTypes[] = { + {0, UDATPG_FIELD_COUNT, 0, 0, 0} , // last row of dtTypes[] + }; + + static const char* const CLDR_FIELD_APPEND[] = { + "Era", "Year", "Quarter", "Month", "Week", "*", "Day-Of-Week", +- "*", "*", "Day", "*", // The UDATPG_x_FIELD constants and these fields have a different order than in ICU4J +- "Hour", "Minute", "Second", "*", "Timezone" ++ "*", "*", "Day", "DayPeriod", // The UDATPG_x_FIELD constants and these fields have a different order than in ICU4J ++ "Hour", "Minute", "Second", "FractionalSecond", "Timezone" + }; + + static const char* const CLDR_FIELD_NAME[UDATPG_FIELD_COUNT] = { + "era", "year", "quarter", "month", "week", "weekOfMonth", "weekday", + "dayOfYear", "weekdayOfMonth", "day", "dayperiod", // The UDATPG_x_FIELD constants and these fields have a different order than in ICU4J diff --git a/intl/icu-patches/bug-1636984-display-name-fractional-seconds.diff b/intl/icu-patches/bug-1636984-display-name-fractional-seconds.diff new file mode 100644 index 0000000000..1e68a20b42 --- /dev/null +++ b/intl/icu-patches/bug-1636984-display-name-fractional-seconds.diff @@ -0,0 +1,39 @@ +# Give fractional seconds a more useful display name than "F14". +# +# CLDR bug: https://unicode-org.atlassian.net/browse/CLDR-13623 + +diff --git a/intl/icu/source/data/locales/root.txt b/intl/icu/source/data/locales/root.txt +--- a/intl/icu/source/data/locales/root.txt ++++ b/intl/icu/source/data/locales/root.txt +@@ -2527,10 +2527,15 @@ root{ + zone{ + dn{"Zone"} + } + zone-narrow:alias{"/LOCALE/fields/zone-short"} + zone-short:alias{"/LOCALE/fields/zone"} ++ fractionalSecond{ ++ dn{"Fractional Second"} ++ } ++ fractionalSecond-narrow:alias{"/LOCALE/fields/fractionalSecond-short"} ++ fractionalSecond-short:alias{"/LOCALE/fields/fractionalSecond"} + } + layout{ + characters{"left-to-right"} + lines{"top-to-bottom"} + } +diff --git a/intl/icu/source/i18n/dtptngen.cpp b/intl/icu/source/i18n/dtptngen.cpp +--- a/intl/icu/source/i18n/dtptngen.cpp ++++ b/intl/icu/source/i18n/dtptngen.cpp +@@ -264,11 +264,11 @@ static const char* const CLDR_FIELD_APPE + }; + + static const char* const CLDR_FIELD_NAME[UDATPG_FIELD_COUNT] = { + "era", "year", "quarter", "month", "week", "weekOfMonth", "weekday", + "dayOfYear", "weekdayOfMonth", "day", "dayperiod", // The UDATPG_x_FIELD constants and these fields have a different order than in ICU4J +- "hour", "minute", "second", "*", "zone" ++ "hour", "minute", "second", "fractionalSecond", "zone" + }; + + static const char* const CLDR_FIELD_WIDTH[] = { // [UDATPG_WIDTH_COUNT] + "", "-short", "-narrow" + }; diff --git a/intl/icu-patches/bug-1706949-wasi-workaround.diff b/intl/icu-patches/bug-1706949-wasi-workaround.diff new file mode 100644 index 0000000000..f56432f174 --- /dev/null +++ b/intl/icu-patches/bug-1706949-wasi-workaround.diff @@ -0,0 +1,757 @@ +# Handle WASI lack of support for <thread> and <atomic>. +# +# WASI issue: https://github.com/WebAssembly/wasi-sdk/issues/180 + +diff --git a/intl/icu/source/common/putilimp.h b/intl/icu/source/common/putilimp.h +index 5b95a68..7097232 100644 +--- a/intl/icu/source/common/putilimp.h ++++ b/intl/icu/source/common/putilimp.h +@@ -103,6 +103,8 @@ typedef size_t uintptr_t; + #endif + #elif U_PLATFORM == U_PF_OS400 + /* not defined */ ++#elif defined(__wasi__) ++ /* not defined */ + #else + # define U_TZSET tzset + #endif +@@ -128,6 +130,8 @@ typedef size_t uintptr_t; + /* not defined */ + #elif U_PLATFORM == U_PF_IPHONE + /* not defined */ ++#elif defined(__wasi__) ++ /* not defined */ + #else + # define U_TIMEZONE timezone + #endif +@@ -141,6 +145,8 @@ typedef size_t uintptr_t; + #endif + #elif U_PLATFORM == U_PF_OS400 + /* not defined */ ++#elif defined(__wasi__) ++ /* not defined */ + #else + # define U_TZNAME tzname + #endif +diff --git a/intl/icu/source/common/umapfile.h b/intl/icu/source/common/umapfile.h +index 92bd567..4ed1112 100644 +--- a/intl/icu/source/common/umapfile.h ++++ b/intl/icu/source/common/umapfile.h +@@ -41,6 +41,8 @@ U_CFUNC void uprv_unmapFile(UDataMemory *pData); + + #if UCONFIG_NO_FILE_IO + # define MAP_IMPLEMENTATION MAP_NONE ++#elif defined(__wasi__) ++# define MAP_IMPLEMENTATION MAP_STDIO + #elif U_PLATFORM_USES_ONLY_WIN32_API + # define MAP_IMPLEMENTATION MAP_WIN32 + #elif U_HAVE_MMAP || U_PLATFORM == U_PF_OS390 +diff --git a/intl/icu/source/common/umutex.cpp b/intl/icu/source/common/umutex.cpp +index ccbee99..6c3452c 100644 +--- a/intl/icu/source/common/umutex.cpp ++++ b/intl/icu/source/common/umutex.cpp +@@ -43,6 +43,7 @@ U_NAMESPACE_BEGIN + * + *************************************************************************************************/ + ++#ifndef __wasi__ + namespace { + std::mutex *initMutex; + std::condition_variable *initCondition; +@@ -55,9 +56,11 @@ std::once_flag initFlag; + std::once_flag *pInitFlag = &initFlag; + + } // Anonymous namespace ++#endif + + U_CDECL_BEGIN + static UBool U_CALLCONV umtx_cleanup() { ++#ifndef __wasi__ + initMutex->~mutex(); + initCondition->~condition_variable(); + UMutex::cleanup(); +@@ -66,17 +69,21 @@ static UBool U_CALLCONV umtx_cleanup() { + // 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(); ++#endif + return true; + } + + static void U_CALLCONV umtx_init() { ++#ifndef __wasi__ + initMutex = STATIC_NEW(std::mutex); + initCondition = STATIC_NEW(std::condition_variable); + ucln_common_registerCleanup(UCLN_COMMON_MUTEX, umtx_cleanup); ++#endif + } + U_CDECL_END + + ++#ifndef __wasi__ + std::mutex *UMutex::getMutex() { + std::mutex *retPtr = fMutex.load(std::memory_order_acquire); + if (retPtr == nullptr) { +@@ -93,14 +100,17 @@ std::mutex *UMutex::getMutex() { + U_ASSERT(retPtr != nullptr); + return retPtr; + } ++#endif + + UMutex *UMutex::gListHead = nullptr; + + void UMutex::cleanup() { + UMutex *next = nullptr; + for (UMutex *m = gListHead; m != nullptr; m = next) { ++#ifndef __wasi__ + (*m->fMutex).~mutex(); + m->fMutex = nullptr; ++#endif + next = m->fListLink; + m->fListLink = nullptr; + } +@@ -110,20 +120,24 @@ void UMutex::cleanup() { + + U_CAPI void U_EXPORT2 + umtx_lock(UMutex *mutex) { ++#ifndef __wasi__ + if (mutex == nullptr) { + mutex = &globalMutex; + } + mutex->lock(); ++#endif + } + + + U_CAPI void U_EXPORT2 + umtx_unlock(UMutex* mutex) + { ++#ifndef __wasi__ + if (mutex == nullptr) { + mutex = &globalMutex; + } + mutex->unlock(); ++#endif + } + + +@@ -143,18 +157,22 @@ umtx_unlock(UMutex* mutex) + // + U_COMMON_API UBool U_EXPORT2 + umtx_initImplPreInit(UInitOnce &uio) { ++#ifndef __wasi__ + std::call_once(*pInitFlag, umtx_init); + std::unique_lock<std::mutex> lock(*initMutex); ++#endif + if (umtx_loadAcquire(uio.fState) == 0) { + umtx_storeRelease(uio.fState, 1); + return true; // Caller will next call the init function. + } else { ++#ifndef __wasi__ + while (umtx_loadAcquire(uio.fState) == 1) { + // Another thread is currently running the initialization. + // Wait until it completes. + initCondition->wait(lock); + } + U_ASSERT(uio.fState == 2); ++#endif + return false; + } + } +@@ -168,11 +186,13 @@ umtx_initImplPreInit(UInitOnce &uio) { + + U_COMMON_API void U_EXPORT2 + umtx_initImplPostInit(UInitOnce &uio) { ++#ifndef __wasi__ + { + std::unique_lock<std::mutex> lock(*initMutex); + umtx_storeRelease(uio.fState, 2); + } + initCondition->notify_all(); ++#endif + } + + U_NAMESPACE_END +diff --git a/intl/icu/source/common/umutex.h b/intl/icu/source/common/umutex.h +index 8d76b3f..c1a58db 100644 +--- a/intl/icu/source/common/umutex.h ++++ b/intl/icu/source/common/umutex.h +@@ -20,9 +20,12 @@ + #ifndef UMUTEX_H + #define UMUTEX_H + ++#ifndef __wasi__ + #include <atomic> + #include <condition_variable> + #include <mutex> ++#endif ++ + #include <type_traits> + + #include "unicode/utypes.h" +@@ -37,6 +40,8 @@ + #error U_USER_ATOMICS and U_USER_MUTEX_H are not supported + #endif + ++#ifndef __wasi__ ++ + // 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. +@@ -61,6 +66,7 @@ template struct std::atomic<std::mutex *>; + #endif + #endif + ++#endif + + U_NAMESPACE_BEGIN + +@@ -70,6 +76,8 @@ U_NAMESPACE_BEGIN + * + ****************************************************************************/ + ++#ifndef __wasi__ ++ + typedef std::atomic<int32_t> u_atomic_int32_t; + #define ATOMIC_INT32_T_INITIALIZER(val) ATOMIC_VAR_INIT(val) + +@@ -89,6 +97,28 @@ inline int32_t umtx_atomic_dec(u_atomic_int32_t *var) { + return var->fetch_sub(1) - 1; + } + ++#else ++ ++typedef int32_t u_atomic_int32_t; ++#define ATOMIC_INT32_T_INITIALIZER(val) val ++ ++inline int32_t umtx_loadAcquire(u_atomic_int32_t &var) { ++ return var; ++} ++ ++inline void umtx_storeRelease(u_atomic_int32_t &var, int32_t val) { ++ var = val; ++} ++ ++inline int32_t umtx_atomic_inc(u_atomic_int32_t *var) { ++ return ++(*var); ++} ++ ++inline int32_t umtx_atomic_dec(u_atomic_int32_t *var) { ++ return --(*var); ++} ++ ++#endif + + /************************************************************************************************* + * +@@ -231,17 +261,25 @@ class U_COMMON_API UMutex { + + // requirements for C++ BasicLockable, allows UMutex to work with std::lock_guard + void lock() { ++#ifndef __wasi__ + std::mutex *m = fMutex.load(std::memory_order_acquire); + if (m == nullptr) { m = getMutex(); } + m->lock(); ++#endif ++ } ++ void unlock() { ++#ifndef __wasi__ ++ fMutex.load(std::memory_order_relaxed)->unlock(); ++#endif + } +- void unlock() { fMutex.load(std::memory_order_relaxed)->unlock(); } + + static void cleanup(); + + private: ++#ifndef __wasi__ + alignas(std::mutex) char fStorage[sizeof(std::mutex)] {}; + std::atomic<std::mutex *> fMutex { nullptr }; ++#endif + + /** All initialized UMutexes are kept in a linked list, so that they can be found, + * and the underlying std::mutex destructed, by u_cleanup(). +@@ -253,7 +291,9 @@ class U_COMMON_API UMutex { + * Initial fast check is inline, in lock(). The returned value may never + * be nullptr. + */ ++#ifndef __wasi__ + std::mutex *getMutex(); ++#endif + }; + + +diff --git a/intl/icu/source/common/unifiedcache.cpp b/intl/icu/source/common/unifiedcache.cpp +--- a/intl/icu/source/common/unifiedcache.cpp ++++ b/intl/icu/source/common/unifiedcache.cpp +@@ -11,19 +11,23 @@ + */ + + #include "unifiedcache.h" + + #include <algorithm> // For std::max() +-#include <mutex> ++#ifndef __wasi__ ++ #include <mutex> ++#endif + + #include "uassert.h" + #include "uhash.h" + #include "ucln_cmn.h" + + static icu::UnifiedCache *gCache = NULL; ++#ifndef __wasi__ + static std::mutex *gCacheMutex = nullptr; + static std::condition_variable *gInProgressValueAddedCond; ++#endif + static icu::UInitOnce gCacheInitOnce {}; + + static const int32_t MAX_EVICT_ITERATIONS = 10; + static const int32_t DEFAULT_MAX_UNUSED = 1000; + static const int32_t DEFAULT_PERCENTAGE_OF_IN_USE = 100; +@@ -32,14 +36,16 @@ static const int32_t DEFAULT_PERCENTAGE_OF_IN_USE = 100; + U_CDECL_BEGIN + static UBool U_CALLCONV unifiedcache_cleanup() { + gCacheInitOnce.reset(); + delete gCache; + gCache = nullptr; ++#ifndef __wasi__ + gCacheMutex->~mutex(); + gCacheMutex = nullptr; + gInProgressValueAddedCond->~condition_variable(); + gInProgressValueAddedCond = nullptr; ++#endif + return true; + } + U_CDECL_END + + +@@ -70,12 +76,14 @@ CacheKeyBase::~CacheKeyBase() { + static void U_CALLCONV cacheInit(UErrorCode &status) { + U_ASSERT(gCache == NULL); + ucln_common_registerCleanup( + UCLN_COMMON_UNIFIED_CACHE, unifiedcache_cleanup); + ++#ifndef __wasi__ + gCacheMutex = STATIC_NEW(std::mutex); + gInProgressValueAddedCond = STATIC_NEW(std::condition_variable); ++#endif + gCache = new UnifiedCache(status); + if (gCache == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + } + if (U_FAILURE(status)) { +@@ -133,41 +141,53 @@ void UnifiedCache::setEvictionPolicy( + } + if (count < 0 || percentageOfInUseItems < 0) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return; + } ++#ifndef __wasi__ + std::lock_guard<std::mutex> lock(*gCacheMutex); ++#endif + fMaxUnused = count; + fMaxPercentageOfInUse = percentageOfInUseItems; + } + + int32_t UnifiedCache::unusedCount() const { ++#ifndef __wasi__ + std::lock_guard<std::mutex> lock(*gCacheMutex); ++#endif + return uhash_count(fHashtable) - fNumValuesInUse; + } + + int64_t UnifiedCache::autoEvictedCount() const { ++#ifndef __wasi__ + std::lock_guard<std::mutex> lock(*gCacheMutex); ++#endif + return fAutoEvictedCount; + } + + int32_t UnifiedCache::keyCount() const { ++#ifndef __wasi__ + std::lock_guard<std::mutex> lock(*gCacheMutex); ++#endif + return uhash_count(fHashtable); + } + + void UnifiedCache::flush() const { ++#ifndef __wasi__ + std::lock_guard<std::mutex> lock(*gCacheMutex); ++#endif + + // Use a loop in case cache items that are flushed held hard references to + // other cache items making those additional cache items eligible for + // flushing. + while (_flush(false)); + } + + void UnifiedCache::handleUnreferencedObject() const { ++#ifndef __wasi__ + std::lock_guard<std::mutex> lock(*gCacheMutex); ++#endif + --fNumValuesInUse; + _runEvictionSlice(); + } + + #ifdef UNIFIED_CACHE_DEBUG +@@ -182,11 +202,13 @@ void UnifiedCache::dump() { + } + cache->dumpContents(); + } + + void UnifiedCache::dumpContents() const { ++#ifndef __wasi__ + std::lock_guard<std::mutex> lock(*gCacheMutex); ++#endif + _dumpContents(); + } + + // Dumps content of cache. + // On entry, gCacheMutex must be held. +@@ -222,11 +244,13 @@ UnifiedCache::~UnifiedCache() { + flush(); + { + // 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. ++#ifndef __wasi__ + std::lock_guard<std::mutex> lock(*gCacheMutex); ++#endif + _flush(true); + } + uhash_close(fHashtable); + fHashtable = nullptr; + delete fNoValue; +@@ -323,11 +347,13 @@ void UnifiedCache::_putNew( + + void UnifiedCache::_putIfAbsentAndGet( + const CacheKeyBase &key, + const SharedObject *&value, + UErrorCode &status) const { ++#ifndef __wasi__ + std::lock_guard<std::mutex> lock(*gCacheMutex); ++#endif + const UHashElement *element = uhash_find(fHashtable, &key); + if (element != NULL && !_inProgress(element)) { + _fetch(element, value, status); + return; + } +@@ -348,18 +374,22 @@ UBool UnifiedCache::_poll( + const CacheKeyBase &key, + const SharedObject *&value, + UErrorCode &status) const { + U_ASSERT(value == NULL); + U_ASSERT(status == U_ZERO_ERROR); ++#ifndef __wasi__ + std::unique_lock<std::mutex> lock(*gCacheMutex); ++#endif + 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)) { ++#ifndef __wasi__ + gInProgressValueAddedCond->wait(lock); ++#endif + element = uhash_find(fHashtable, &key); + } + + // If the hash table contains an entry for the key, + // fetch out the contents and return them. +@@ -426,13 +456,15 @@ void UnifiedCache::_put( + UHashElement *ptr = const_cast<UHashElement *>(element); + ptr->value.pointer = (void *) value; + U_ASSERT(oldValue == fNoValue); + removeSoftRef(oldValue); + ++#ifndef __wasi__ + // Tell waiting threads that we replace in-progress status with + // an error. + gInProgressValueAddedCond->notify_all(); ++#endif + } + + void UnifiedCache::_fetch( + const UHashElement *element, + const SharedObject *&value, +diff --git a/intl/icu/source/i18n/decContext.h b/intl/icu/source/i18n/decContext.h +index 59ab65e..20f3526 100644 +--- a/intl/icu/source/i18n/decContext.h ++++ b/intl/icu/source/i18n/decContext.h +@@ -61,7 +61,9 @@ + /* #include <stdint.h> */ /* C99 standard integers */ + #endif + #include <stdio.h> /* for printf, etc. */ ++#ifndef __wasi__ + #include <signal.h> /* for traps */ ++#endif + + /* Extended flags setting -- set this to 0 to use only IEEE flags */ + #if !defined(DECEXTFLAG) +diff --git a/intl/icu/source/i18n/decimfmt.cpp b/intl/icu/source/i18n/decimfmt.cpp +index daa1129..c8f1eda 100644 +--- a/intl/icu/source/i18n/decimfmt.cpp ++++ b/intl/icu/source/i18n/decimfmt.cpp +@@ -480,8 +480,13 @@ DecimalFormat& DecimalFormat::operator=(const DecimalFormat& rhs) { + DecimalFormat::~DecimalFormat() { + if (fields == nullptr) { return; } + ++#ifndef __wasi__ + delete fields->atomicParser.exchange(nullptr); + delete fields->atomicCurrencyParser.exchange(nullptr); ++#else ++ delete fields->atomicParser; ++ delete fields->atomicCurrencyParser; ++#endif + delete fields; + } + +@@ -1626,8 +1631,13 @@ void DecimalFormat::touch(UErrorCode& status) { + setupFastFormat(); + + // Delete the parsers if they were made previously ++#ifndef __wasi__ + delete fields->atomicParser.exchange(nullptr); + delete fields->atomicCurrencyParser.exchange(nullptr); ++#else ++ delete fields->atomicParser; ++ delete fields->atomicCurrencyParser; ++#endif + + // In order for the getters to work, we need to populate some fields in NumberFormat. + NumberFormat::setCurrency(fields->exportedProperties.currency.get(status).getISOCurrency(), status); +@@ -1662,7 +1672,11 @@ const numparse::impl::NumberParserImpl* DecimalFormat::getParser(UErrorCode& sta + } + + // First try to get the pre-computed parser ++#ifndef __wasi__ + auto* ptr = fields->atomicParser.load(); ++#else ++ auto* ptr = fields->atomicParser; ++#endif + if (ptr != nullptr) { + return ptr; + } +@@ -1681,6 +1695,7 @@ const numparse::impl::NumberParserImpl* DecimalFormat::getParser(UErrorCode& sta + // it is set to what is actually stored in the atomic + // if another thread beat us to computing the parser object. + auto* nonConstThis = const_cast<DecimalFormat*>(this); ++#ifndef __wasi__ + if (!nonConstThis->fields->atomicParser.compare_exchange_strong(ptr, temp)) { + // Another thread beat us to computing the parser + delete temp; +@@ -1689,13 +1704,21 @@ const numparse::impl::NumberParserImpl* DecimalFormat::getParser(UErrorCode& sta + // Our copy of the parser got stored in the atomic + return temp; + } ++#else ++ nonConstThis->fields->atomicParser = temp; ++ return temp; ++#endif + } + + const numparse::impl::NumberParserImpl* DecimalFormat::getCurrencyParser(UErrorCode& status) const { + if (U_FAILURE(status)) { return nullptr; } + + // First try to get the pre-computed parser ++#ifndef __wasi__ + auto* ptr = fields->atomicCurrencyParser.load(); ++#else ++ auto* ptr = fields->atomicCurrencyParser; ++#endif + if (ptr != nullptr) { + return ptr; + } +@@ -1710,6 +1733,7 @@ const numparse::impl::NumberParserImpl* DecimalFormat::getCurrencyParser(UErrorC + // Note: ptr starts as nullptr; during compare_exchange, it is set to what is actually stored in the + // atomic if another thread beat us to computing the parser object. + auto* nonConstThis = const_cast<DecimalFormat*>(this); ++#ifndef __wasi__ + if (!nonConstThis->fields->atomicCurrencyParser.compare_exchange_strong(ptr, temp)) { + // Another thread beat us to computing the parser + delete temp; +@@ -1718,6 +1742,10 @@ const numparse::impl::NumberParserImpl* DecimalFormat::getCurrencyParser(UErrorC + // Our copy of the parser got stored in the atomic + return temp; + } ++#else ++ nonConstThis->fields->atomicCurrencyParser = temp; ++ return temp; ++#endif + } + + void +diff --git a/intl/icu/source/i18n/number_mapper.h b/intl/icu/source/i18n/number_mapper.h +index 9ecd776..d094289 100644 +--- a/intl/icu/source/i18n/number_mapper.h ++++ b/intl/icu/source/i18n/number_mapper.h +@@ -7,7 +7,6 @@ + #ifndef __NUMBER_MAPPER_H__ + #define __NUMBER_MAPPER_H__ + +-#include <atomic> + #include "number_types.h" + #include "unicode/currpinf.h" + #include "standardplural.h" +@@ -15,6 +14,10 @@ + #include "number_currencysymbols.h" + #include "numparse_impl.h" + ++#ifndef __wasi__ ++#include <atomic> ++#endif ++ + U_NAMESPACE_BEGIN + namespace number { + namespace impl { +@@ -193,10 +196,18 @@ struct DecimalFormatFields : public UMemory { + LocalizedNumberFormatter formatter; + + /** The lazy-computed parser for .parse() */ ++#ifndef __wasi__ + std::atomic<::icu::numparse::impl::NumberParserImpl*> atomicParser = {}; ++#else ++ ::icu::numparse::impl::NumberParserImpl* atomicParser = nullptr; ++#endif + + /** The lazy-computed parser for .parseCurrency() */ ++#ifndef __wasi__ + std::atomic<::icu::numparse::impl::NumberParserImpl*> atomicCurrencyParser = {}; ++#else ++ ::icu::numparse::impl::NumberParserImpl* atomicCurrencyParser = {}; ++#endif + + /** Small object ownership warehouse for the formatter and parser */ + DecimalFormatWarehouse warehouse; +diff --git a/intl/icu/source/i18n/numrange_fluent.cpp b/intl/icu/source/i18n/numrange_fluent.cpp +index f1060b3..66e12ee 100644 +--- a/intl/icu/source/i18n/numrange_fluent.cpp ++++ b/intl/icu/source/i18n/numrange_fluent.cpp +@@ -240,29 +240,49 @@ LocalizedNumberRangeFormatter::LocalizedNumberRangeFormatter(NFS<LNF>&& src) U_N + : NFS<LNF>(std::move(src)) { + // Steal the compiled formatter + LNF&& _src = static_cast<LNF&&>(src); ++#ifndef __wasi__ + auto* stolen = _src.fAtomicFormatter.exchange(nullptr); + delete fAtomicFormatter.exchange(stolen); ++#else ++ delete fAtomicFormatter; ++ fAtomicFormatter = _src.fAtomicFormatter; ++ _src.fAtomicFormatter = nullptr; ++#endif + } + + LocalizedNumberRangeFormatter& LocalizedNumberRangeFormatter::operator=(const LNF& other) { + if (this == &other) { return *this; } // self-assignment: no-op + NFS<LNF>::operator=(static_cast<const NFS<LNF>&>(other)); + // Do not steal; just clear ++#ifndef __wasi__ + delete fAtomicFormatter.exchange(nullptr); ++#else ++ delete fAtomicFormatter; ++#endif + return *this; + } + + LocalizedNumberRangeFormatter& LocalizedNumberRangeFormatter::operator=(LNF&& src) U_NOEXCEPT { + NFS<LNF>::operator=(static_cast<NFS<LNF>&&>(src)); + // Steal the compiled formatter ++#ifndef __wasi__ + auto* stolen = src.fAtomicFormatter.exchange(nullptr); + delete fAtomicFormatter.exchange(stolen); ++#else ++ delete fAtomicFormatter; ++ fAtomicFormatter = src.fAtomicFormatter; ++ src.fAtomicFormatter = nullptr; ++#endif + return *this; + } + + + LocalizedNumberRangeFormatter::~LocalizedNumberRangeFormatter() { ++#ifndef __wasi__ + delete fAtomicFormatter.exchange(nullptr); ++#else ++ delete fAtomicFormatter; ++#endif + } + + LocalizedNumberRangeFormatter::LocalizedNumberRangeFormatter(const RangeMacroProps& macros, const Locale& locale) { +@@ -346,7 +366,11 @@ LocalizedNumberRangeFormatter::getFormatter(UErrorCode& status) const { + } + + // First try to get the pre-computed formatter ++#ifndef __wasi__ + auto* ptr = fAtomicFormatter.load(); ++#else ++ auto* ptr = fAtomicFormatter; ++#endif + if (ptr != nullptr) { + return ptr; + } +@@ -365,6 +389,7 @@ LocalizedNumberRangeFormatter::getFormatter(UErrorCode& status) const { + // it is set to what is actually stored in the atomic + // if another thread beat us to computing the formatter object. + auto* nonConstThis = const_cast<LocalizedNumberRangeFormatter*>(this); ++#ifndef __wasi__ + if (!nonConstThis->fAtomicFormatter.compare_exchange_strong(ptr, temp)) { + // Another thread beat us to computing the formatter + delete temp; +@@ -373,6 +398,10 @@ LocalizedNumberRangeFormatter::getFormatter(UErrorCode& status) const { + // Our copy of the formatter got stored in the atomic + return temp; + } ++#else ++ nonConstThis->fAtomicFormatter = temp; ++ return temp; ++#endif + + } + +diff --git a/intl/icu/source/i18n/unicode/numberrangeformatter.h b/intl/icu/source/i18n/unicode/numberrangeformatter.h +index b9a4600..0ba2fa0 100644 +--- a/intl/icu/source/i18n/unicode/numberrangeformatter.h ++++ b/intl/icu/source/i18n/unicode/numberrangeformatter.h +@@ -10,7 +10,6 @@ + + #if !UCONFIG_NO_FORMATTING + +-#include <atomic> + #include "unicode/appendable.h" + #include "unicode/fieldpos.h" + #include "unicode/formattedvalue.h" +@@ -18,6 +17,10 @@ + #include "unicode/numberformatter.h" + #include "unicode/unumberrangeformatter.h" + ++#ifndef __wasi__ ++#include <atomic> ++#endif ++ + /** + * \file + * \brief C++ API: Library for localized formatting of number, currency, and unit ranges. +@@ -77,7 +80,9 @@ struct UFormattedNumberRangeImpl; + } // namespace icu::number + U_NAMESPACE_END + ++#ifndef __wasi__ + template struct U_I18N_API std::atomic< U_NAMESPACE_QUALIFIER number::impl::NumberRangeFormatterImpl*>; ++#endif + + U_NAMESPACE_BEGIN + namespace number { // icu::number +@@ -546,7 +551,11 @@ class U_I18N_API LocalizedNumberRangeFormatter + ~LocalizedNumberRangeFormatter(); + + private: ++#ifndef __wasi__ + std::atomic<impl::NumberRangeFormatterImpl*> fAtomicFormatter = {}; ++#else ++ impl::NumberRangeFormatterImpl* fAtomicFormatter = nullptr; ++#endif + + const impl::NumberRangeFormatterImpl* getFormatter(UErrorCode& stauts) const; + diff --git a/intl/icu-patches/bug-1790071-ICU-22132-standardize-vtzone-output.diff b/intl/icu-patches/bug-1790071-ICU-22132-standardize-vtzone-output.diff new file mode 100644 index 0000000000..e31f02d637 --- /dev/null +++ b/intl/icu-patches/bug-1790071-ICU-22132-standardize-vtzone-output.diff @@ -0,0 +1,28 @@ +diff --git a/intl/icu/source/i18n/vtzone.cpp b/intl/icu/source/i18n/vtzone.cpp +--- a/intl/icu/source/i18n/vtzone.cpp ++++ b/intl/icu/source/i18n/vtzone.cpp +@@ -1735,14 +1735,17 @@ VTimeZone::write(VTZWriter& writer, UErr + } + } + } else { +- UnicodeString icutzprop; +- UVector customProps(nullptr, uhash_compareUnicodeString, status); ++ UVector customProps(uprv_deleteUObject, uhash_compareUnicodeString, status); + if (olsonzid.length() > 0 && icutzver.length() > 0) { +- icutzprop.append(olsonzid); +- icutzprop.append(u'['); +- icutzprop.append(icutzver); +- icutzprop.append(u']'); +- customProps.addElement(&icutzprop, status); ++ LocalPointer<UnicodeString> icutzprop(new UnicodeString(ICU_TZINFO_PROP), status); ++ if (U_FAILURE(status)) { ++ return; ++ } ++ icutzprop->append(olsonzid); ++ icutzprop->append(u'['); ++ icutzprop->append(icutzver); ++ icutzprop->append(u']'); ++ customProps.adoptElement(icutzprop.orphan(), status); + } + writeZone(writer, *tz, &customProps, status); + } diff --git a/intl/icu-patches/bug-1792775-ICU-22198.diff b/intl/icu-patches/bug-1792775-ICU-22198.diff new file mode 100644 index 0000000000..ec5211b651 --- /dev/null +++ b/intl/icu-patches/bug-1792775-ICU-22198.diff @@ -0,0 +1,19 @@ +# https://github.com/unicode-org/icu/pull/2248 +# https://github.com/unicode-org/icu/pull/2248.diff +# +# ICU bug: https://unicode-org.atlassian.net/browse/ICU-22198 + +diff --git a/intl/icu/source/common/uresbund.cpp b/intl/icu/source/common/uresbund.cpp +index 17c0177a05c..81fb90e1384 100644 +--- a/intl/icu/source/common/uresbund.cpp ++++ b/intl/icu/source/common/uresbund.cpp +@@ -202,7 +202,8 @@ typedef enum UResOpenType UResOpenType; + */ + static bool getParentLocaleID(char *name, const char *origName, UResOpenType openType) { + // early out if the locale ID has a variant code or ends with _ +- if (name[uprv_strlen(name) - 1] == '_' || hasVariant(name)) { ++ size_t nameLen = uprv_strlen(name); ++ if (!nameLen || name[nameLen - 1] == '_' || hasVariant(name)) { + return chopLocale(name); + } + diff --git a/intl/icu-patches/bug-1792775-ICU-22206.diff b/intl/icu-patches/bug-1792775-ICU-22206.diff new file mode 100644 index 0000000000..34e3625803 --- /dev/null +++ b/intl/icu-patches/bug-1792775-ICU-22206.diff @@ -0,0 +1,351 @@ +# https://github.com/unicode-org/icu/pull/2255 +# https://github.com/unicode-org/icu/pull/2255.diff +# +# ICU bug: https://unicode-org.atlassian.net/browse/ICU-22206 + +diff --git a/intl/icu/source/common/rbbiscan.cpp b/intl/icu/source/common/rbbiscan.cpp +index 8232bd94e47..87d31f8af40 100644 +--- a/intl/icu/source/common/rbbiscan.cpp ++++ b/intl/icu/source/common/rbbiscan.cpp +@@ -918,7 +918,7 @@ void RBBIRuleScanner::nextChar(RBBIRuleChar &c) { + // Toggle quoting mode. + // Return either '(' or ')', because quotes cause a grouping of the quoted text. + fQuoteMode = !fQuoteMode; +- if (fQuoteMode == true) { ++ if (fQuoteMode) { + c.fChar = chLParen; + } else { + c.fChar = chRParen; +diff --git a/intl/icu/source/common/ucnvisci.cpp b/intl/icu/source/common/ucnvisci.cpp +index 4d747e1ff84..839f7ff9c62 100644 +--- a/intl/icu/source/common/ucnvisci.cpp ++++ b/intl/icu/source/common/ucnvisci.cpp +@@ -1472,7 +1472,7 @@ UConverter_toUnicode_ISCII_OFFSETS_LOGIC(UConverterToUnicodeArgs *args, UErrorCo + if (targetUniChar != missingCharMarker) { + /* now save the targetUniChar for delayed write */ + *toUnicodeStatus = (UChar) targetUniChar; +- if (data->resetToDefaultToUnicode==true) { ++ if (data->resetToDefaultToUnicode) { + data->currentDeltaToUnicode = data->defDeltaToUnicode; + data->currentMaskToUnicode = data->defMaskToUnicode; + data->resetToDefaultToUnicode=false; +diff --git a/intl/icu/source/common/udata.cpp b/intl/icu/source/common/udata.cpp +index 2bc74c97898..c5d0a9feb7b 100644 +--- a/intl/icu/source/common/udata.cpp ++++ b/intl/icu/source/common/udata.cpp +@@ -568,7 +568,7 @@ const char *UDataPathIterator::next(UErrorCode *pErrorCode) + /* check for .dat files */ + pathBasename = findBasename(pathBuffer.data()); + +- if(checkLastFour == true && ++ if(checkLastFour && + (pathLen>=4) && + uprv_strncmp(pathBuffer.data() +(pathLen-4), suffix.data(), 4)==0 && /* suffix matches */ + uprv_strncmp(findBasename(pathBuffer.data()), basename, basenameLen)==0 && /* base matches */ +diff --git a/intl/icu/source/common/uidna.cpp b/intl/icu/source/common/uidna.cpp +index 1cbdeec3272..7135a166f21 100644 +--- a/intl/icu/source/common/uidna.cpp ++++ b/intl/icu/source/common/uidna.cpp +@@ -287,7 +287,7 @@ _internal_toASCII(const UChar* src, int32_t srcLength, + failPos = j; + } + } +- if(useSTD3ASCIIRules == true){ ++ if(useSTD3ASCIIRules){ + // verify 3a and 3b + // 3(a) Verify the absence of non-LDH ASCII code points; that is, the + // absence of 0..2C, 2E..2F, 3A..40, 5B..60, and 7B..7F. +@@ -731,7 +731,7 @@ uidna_IDNToASCII( const UChar *src, int32_t srcLength, + remainingDestCapacity = 0; + } + +- if(done == true){ ++ if(done){ + break; + } + +@@ -829,7 +829,7 @@ uidna_IDNToUnicode( const UChar* src, int32_t srcLength, + remainingDestCapacity = 0; + } + +- if(done == true){ ++ if(done){ + break; + } + +diff --git a/intl/icu/source/common/uresbund.cpp b/intl/icu/source/common/uresbund.cpp +index 17c0177a05c..c065387bdae 100644 +--- a/intl/icu/source/common/uresbund.cpp ++++ b/intl/icu/source/common/uresbund.cpp +@@ -2448,7 +2448,7 @@ U_CAPI UResourceBundle* U_EXPORT2 ures_getByKey(const UResourceBundle *resB, con + res = res_getTableItemByKey(&resB->getResData(), resB->fRes, &t, &key); + if(res == RES_BOGUS) { + key = inKey; +- if(resB->fHasFallback == true) { ++ if(resB->fHasFallback) { + dataEntry = getFallbackData(resB, &key, &res, status); + if(U_SUCCESS(*status)) { + /* check if resB->fResPath gives the right name here */ +@@ -2503,7 +2503,7 @@ U_CAPI const UChar* U_EXPORT2 ures_getStringByKey(const UResourceBundle *resB, c + + if(res == RES_BOGUS) { + key = inKey; +- if(resB->fHasFallback == true) { ++ if(resB->fHasFallback) { + dataEntry = getFallbackData(resB, &key, &res, status); + if(U_SUCCESS(*status)) { + switch (RES_GET_TYPE(res)) { +diff --git a/intl/icu/source/common/usprep.cpp b/intl/icu/source/common/usprep.cpp +index 50d16081d1d..8175dc7fa82 100644 +--- a/intl/icu/source/common/usprep.cpp ++++ b/intl/icu/source/common/usprep.cpp +@@ -160,7 +160,7 @@ usprep_internal_flushCache(UBool noRefCount){ + key = (UStringPrepKey *) e->key.pointer; + + if ((noRefCount== false && profile->refCount == 0) || +- noRefCount== true) { ++ noRefCount) { + deletedNum++; + uhash_removeElement(SHARED_DATA_HASHTABLE, e); + +@@ -746,16 +746,16 @@ usprep_prepare( const UStringPrepProfile* profile, + } + } + } +- if(profile->checkBiDi == true){ ++ if(profile->checkBiDi){ + // satisfy 2 +- if( leftToRight == true && rightToLeft == true){ ++ if( leftToRight && rightToLeft){ + *status = U_STRINGPREP_CHECK_BIDI_ERROR; + uprv_syntaxError(b2,(rtlPos>ltrPos) ? rtlPos : ltrPos, b2Len, parseError); + return 0; + } + + //satisfy 3 +- if( rightToLeft == true && ++ if( rightToLeft && + !((firstCharDir == U_RIGHT_TO_LEFT || firstCharDir == U_RIGHT_TO_LEFT_ARABIC) && + (direction == U_RIGHT_TO_LEFT || direction == U_RIGHT_TO_LEFT_ARABIC)) + ){ +diff --git a/intl/icu/source/common/utext.cpp b/intl/icu/source/common/utext.cpp +index 548e6a60f31..89e3d669f6e 100644 +--- a/intl/icu/source/common/utext.cpp ++++ b/intl/icu/source/common/utext.cpp +@@ -223,7 +223,7 @@ utext_current32(UText *ut) { + trail = ut->chunkContents[ut->chunkOffset]; + } + UBool r = ut->pFuncs->access(ut, nativePosition, false); // reverse iteration flag loads preceding chunk +- U_ASSERT(r==true); ++ U_ASSERT(r); + ut->chunkOffset = originalOffset; + if(!r) { + return U_SENTINEL; +diff --git a/intl/icu/source/i18n/calendar.cpp b/intl/icu/source/i18n/calendar.cpp +index f5a40e48395..5431d87bdd2 100644 +--- a/intl/icu/source/i18n/calendar.cpp ++++ b/intl/icu/source/i18n/calendar.cpp +@@ -3510,7 +3510,7 @@ int32_t Calendar::handleGetExtendedYearFromWeekFields(int32_t yearWoy, int32_t w + switch(bestField) { + case UCAL_WEEK_OF_YEAR: + if(woy == 1) { +- if(jan1InPrevYear == true) { ++ if(jan1InPrevYear) { + // the first week of January is in the previous year + // therefore WOY1 is always solidly within yearWoy + return yearWoy; +diff --git a/intl/icu/source/i18n/dcfmtsym.cpp b/intl/icu/source/i18n/dcfmtsym.cpp +index 5d06c189fbe..fa5920aaa50 100644 +--- a/intl/icu/source/i18n/dcfmtsym.cpp ++++ b/intl/icu/source/i18n/dcfmtsym.cpp +@@ -329,11 +329,13 @@ struct CurrencySpacingSink : public ResourceSink { + // both beforeCurrency and afterCurrency were found in CLDR. + static const char* defaults[] = { "[:letter:]", "[:digit:]", " " }; + if (!hasBeforeCurrency || !hasAfterCurrency) { +- for (UBool beforeCurrency = 0; beforeCurrency <= true; beforeCurrency++) { +- for (int32_t pattern = 0; pattern < UNUM_CURRENCY_SPACING_COUNT; pattern++) { +- dfs.setPatternForCurrencySpacing((UCurrencySpacing)pattern, +- beforeCurrency, UnicodeString(defaults[pattern], -1, US_INV)); +- } ++ for (int32_t pattern = 0; pattern < UNUM_CURRENCY_SPACING_COUNT; pattern++) { ++ dfs.setPatternForCurrencySpacing((UCurrencySpacing)pattern, ++ false, UnicodeString(defaults[pattern], -1, US_INV)); ++ } ++ for (int32_t pattern = 0; pattern < UNUM_CURRENCY_SPACING_COUNT; pattern++) { ++ dfs.setPatternForCurrencySpacing((UCurrencySpacing)pattern, ++ true, UnicodeString(defaults[pattern], -1, US_INV)); + } + } + } +diff --git a/intl/icu/source/i18n/dtitvinf.cpp b/intl/icu/source/i18n/dtitvinf.cpp +index f5fb86ce581..0a30cf14419 100644 +--- a/intl/icu/source/i18n/dtitvinf.cpp ++++ b/intl/icu/source/i18n/dtitvinf.cpp +@@ -504,7 +504,7 @@ DateIntervalInfo::setIntervalPatternInternally(const UnicodeString& skeleton, + } + + patternsOfOneSkeleton[index] = intervalPattern; +- if ( emptyHash == true ) { ++ if ( emptyHash ) { + fIntervalPatterns->put(skeleton, patternsOfOneSkeleton, status); + } + } +@@ -748,7 +748,7 @@ U_CALLCONV dtitvinfHashTableValueComparator(UHashTok val1, UHashTok val2) { + const UnicodeString* pattern2 = (UnicodeString*)val2.pointer; + UBool ret = true; + int8_t i; +- for ( i = 0; i < DateIntervalInfo::kMaxIntervalPatternIndex && ret == true; ++i ) { ++ for ( i = 0; i < DateIntervalInfo::kMaxIntervalPatternIndex && ret ; ++i ) { + ret = (pattern1[i] == pattern2[i]); + } + return ret; +diff --git a/intl/icu/source/i18n/gregocal.cpp b/intl/icu/source/i18n/gregocal.cpp +index 882d25b4a2a..0e00127e314 100644 +--- a/intl/icu/source/i18n/gregocal.cpp ++++ b/intl/icu/source/i18n/gregocal.cpp +@@ -487,7 +487,7 @@ int32_t GregorianCalendar::handleComputeJulianDay(UCalendarDateFields bestField) + // The following check handles portions of the cutover year BEFORE the + // cutover itself happens. + //if ((fIsGregorian==true) != (jd >= fCutoverJulianDay)) { /* cutoverJulianDay)) { */ +- if ((fIsGregorian==true) != (jd >= fCutoverJulianDay)) { /* cutoverJulianDay)) { */ ++ if ((fIsGregorian) != (jd >= fCutoverJulianDay)) { /* cutoverJulianDay)) { */ + #if defined (U_DEBUG_CAL) + fprintf(stderr, "%s:%d: jd [invert] %d\n", + __FILE__, __LINE__, jd); +diff --git a/intl/icu/source/i18n/regexcmp.cpp b/intl/icu/source/i18n/regexcmp.cpp +index 4b507002d63..adc8f700c7f 100644 +--- a/intl/icu/source/i18n/regexcmp.cpp ++++ b/intl/icu/source/i18n/regexcmp.cpp +@@ -4065,7 +4065,7 @@ void RegexCompile::nextChar(RegexPatternChar &c) { + if (c.fChar == (UChar32)-1) { + break; // End of Input + } +- if (c.fChar == chPound && fEOLComments == true) { ++ if (c.fChar == chPound && fEOLComments) { + // Start of a comment. Consume the rest of it, until EOF or a new line + for (;;) { + c.fChar = nextCharLL(); +diff --git a/intl/icu/source/i18n/search.cpp b/intl/icu/source/i18n/search.cpp +index 56d9b744098..d55902bfa7b 100644 +--- a/intl/icu/source/i18n/search.cpp ++++ b/intl/icu/source/i18n/search.cpp +@@ -81,10 +81,9 @@ USearchAttributeValue SearchIterator::getAttribute( + { + switch (attribute) { + case USEARCH_OVERLAP : +- return (m_search_->isOverlap == true ? USEARCH_ON : USEARCH_OFF); ++ return (m_search_->isOverlap ? USEARCH_ON : USEARCH_OFF); + case USEARCH_CANONICAL_MATCH : +- return (m_search_->isCanonicalMatch == true ? USEARCH_ON : +- USEARCH_OFF); ++ return (m_search_->isCanonicalMatch ? USEARCH_ON : USEARCH_OFF); + case USEARCH_ELEMENT_COMPARISON : + { + int16_t value = m_search_->elementComparisonType; +@@ -242,7 +241,7 @@ int32_t SearchIterator::next(UErrorCode &status) + int32_t matchindex = m_search_->matchedIndex; + int32_t matchlength = m_search_->matchedLength; + m_search_->reset = false; +- if (m_search_->isForwardSearching == true) { ++ if (m_search_->isForwardSearching) { + int32_t textlength = m_search_->textLength; + if (offset == textlength || matchindex == textlength || + (matchindex != USEARCH_DONE && +@@ -295,7 +294,7 @@ int32_t SearchIterator::previous(UErrorCode &status) + } + + int32_t matchindex = m_search_->matchedIndex; +- if (m_search_->isForwardSearching == true) { ++ if (m_search_->isForwardSearching) { + // switching direction. + // if matchedIndex == USEARCH_DONE, it means that either a + // setOffset has been called or that next ran off the text +diff --git a/intl/icu/source/i18n/usearch.cpp b/intl/icu/source/i18n/usearch.cpp +index 0fecd709e74..39f76a1b985 100644 +--- a/intl/icu/source/i18n/usearch.cpp ++++ b/intl/icu/source/i18n/usearch.cpp +@@ -819,11 +819,9 @@ U_CAPI USearchAttributeValue U_EXPORT2 usearch_getAttribute( + if (strsrch) { + switch (attribute) { + case USEARCH_OVERLAP : +- return (strsrch->search->isOverlap == true ? USEARCH_ON : +- USEARCH_OFF); ++ return (strsrch->search->isOverlap ? USEARCH_ON : USEARCH_OFF); + case USEARCH_CANONICAL_MATCH : +- return (strsrch->search->isCanonicalMatch == true ? USEARCH_ON : +- USEARCH_OFF); ++ return (strsrch->search->isCanonicalMatch ? USEARCH_ON : USEARCH_OFF); + case USEARCH_ELEMENT_COMPARISON : + { + int16_t value = strsrch->search->elementComparisonType; +@@ -1249,7 +1247,7 @@ U_CAPI int32_t U_EXPORT2 usearch_previous(UStringSearch *strsrch, + } + + int32_t matchedindex = search->matchedIndex; +- if (search->isForwardSearching == true) { ++ if (search->isForwardSearching) { + // switching direction. + // if matchedIndex == USEARCH_DONE, it means that either a + // setOffset has been called or that next ran off the text +diff --git a/intl/icu/source/i18n/uspoof_conf.cpp b/intl/icu/source/i18n/uspoof_conf.cpp +index 5ecc59c12a8..376ac64e3ce 100644 +--- a/intl/icu/source/i18n/uspoof_conf.cpp ++++ b/intl/icu/source/i18n/uspoof_conf.cpp +@@ -407,7 +407,7 @@ void ConfusabledataBuilder::build(const char * confusables, int32_t confusablesL + // + void ConfusabledataBuilder::outputData(UErrorCode &status) { + +- U_ASSERT(fSpoofImpl->fSpoofData->fDataOwned == true); ++ U_ASSERT(fSpoofImpl->fSpoofData->fDataOwned); + + // The Key Table + // While copying the keys to the runtime array, +diff --git a/intl/icu/source/io/uscanf_p.cpp b/intl/icu/source/io/uscanf_p.cpp +index 9b27e2ebf8d..26a790dd9b6 100644 +--- a/intl/icu/source/io/uscanf_p.cpp ++++ b/intl/icu/source/io/uscanf_p.cpp +@@ -323,7 +323,7 @@ u_scanf_skip_leading_ws(UFILE *input, + UBool isNotEOF; + + /* skip all leading ws in the input */ +- while( ((isNotEOF = ufile_getch(input, &c)) == true) && (c == pad || u_isWhitespace(c)) ) ++ while( ((isNotEOF = ufile_getch(input, &c))==(UBool)true) && (c == pad || u_isWhitespace(c)) ) + { + count++; + } +@@ -357,7 +357,7 @@ u_scanf_skip_leading_positive_sign(UFILE *input, + + if (U_SUCCESS(localStatus)) { + /* skip all leading ws in the input */ +- while( ((isNotEOF = ufile_getch(input, &c)) == true) && (count < symbolLen && c == plusSymbol[count]) ) ++ while( ((isNotEOF = ufile_getch(input, &c))==(UBool)true) && (count < symbolLen && c == plusSymbol[count]) ) + { + count++; + } +@@ -868,7 +868,7 @@ u_scanf_string_handler(UFILE *input, + return -1; + + while( (info->fWidth == -1 || count < info->fWidth) +- && ((isNotEOF = ufile_getch(input, &c)) == true) ++ && ((isNotEOF = ufile_getch(input, &c))==(UBool)true) + && (!info->fIsString || (c != info->fPadChar && !u_isWhitespace(c)))) + { + +@@ -959,7 +959,7 @@ u_scanf_ustring_handler(UFILE *input, + count = 0; + + while( (info->fWidth == -1 || count < info->fWidth) +- && ((isNotEOF = ufile_getch(input, &c)) == true) ++ && ((isNotEOF = ufile_getch(input, &c))==(UBool)true) + && (!info->fIsString || (c != info->fPadChar && !u_isWhitespace(c)))) + { + +@@ -1262,7 +1262,7 @@ u_scanf_scanset_handler(UFILE *input, + + /* grab characters one at a time and make sure they are in the scanset */ + while(chLeft > 0) { +- if ( ((isNotEOF = ufile_getch32(input, &c)) == true) && uset_contains(scanset, c) ) { ++ if ( ((isNotEOF = ufile_getch32(input, &c))==(UBool)true) && uset_contains(scanset, c) ) { + readCharacter = true; + if (!info->fSkipArg) { + int32_t idx = 0; diff --git a/intl/icu-patches/bug-915735 b/intl/icu-patches/bug-915735 new file mode 100644 index 0000000000..c713581f8e --- /dev/null +++ b/intl/icu-patches/bug-915735 @@ -0,0 +1,28 @@ +Bug 915735 - Fix linking the ICU libraries on Mac + +diff --git a/intl/icu/source/config/mh-darwin b/intl/icu/source/config/mh-darwin +--- a/intl/icu/source/config/mh-darwin ++++ b/intl/icu/source/config/mh-darwin +@@ -25,21 +25,17 @@ ARFLAGS += -c + COMPILE.c= $(CC) $(DEFS) $(CPPFLAGS) $(CFLAGS) -fno-common -c + COMPILE.cc= $(CXX) $(DEFS) $(CPPFLAGS) $(CXXFLAGS) -fno-common -c + + ## Commands to make a shared library + SHLIB.c= $(CC) -dynamiclib -dynamic $(CFLAGS) $(LDFLAGS) $(LD_SOOPTIONS) + SHLIB.cc= $(CXX) -dynamiclib -dynamic $(CXXFLAGS) $(LDFLAGS) $(LD_SOOPTIONS) + + ## Compiler switches to embed a library name and version information +-ifeq ($(ENABLE_RPATH),YES) +-LD_SONAME = -Wl,-compatibility_version -Wl,$(SO_TARGET_VERSION_MAJOR) -Wl,-current_version -Wl,$(SO_TARGET_VERSION) -install_name $(libdir)/$(notdir $(MIDDLE_SO_TARGET)) +-else +-LD_SONAME = -Wl,-compatibility_version -Wl,$(SO_TARGET_VERSION_MAJOR) -Wl,-current_version -Wl,$(SO_TARGET_VERSION) -install_name $(notdir $(MIDDLE_SO_TARGET)) $(PKGDATA_TRAILING_SPACE) +-endif ++LD_SONAME = -Wl,-compatibility_version -Wl,$(SO_TARGET_VERSION_MAJOR) -Wl,-current_version -Wl,$(SO_TARGET_VERSION) -install_name @executable_path/$(notdir $(MIDDLE_SO_TARGET)) $(PKGDATA_TRAILING_SPACE) + + ## Compiler switch to embed a runtime search path + LD_RPATH= + LD_RPATH_PRE= -Wl,-rpath, + + ## Environment variable to set a runtime search path + LDLIBRARYPATH_ENVVAR = DYLD_LIBRARY_PATH + diff --git a/intl/icu-patches/suppress-warnings.diff b/intl/icu-patches/suppress-warnings.diff new file mode 100644 index 0000000000..e124a1689d --- /dev/null +++ b/intl/icu-patches/suppress-warnings.diff @@ -0,0 +1,80 @@ +diff --git a/intl/icu/source/acinclude.m4 b/intl/icu/source/acinclude.m4 +--- a/intl/icu/source/acinclude.m4 ++++ b/intl/icu/source/acinclude.m4 +@@ -469,30 +469,36 @@ AC_DEFUN([AC_CHECK_STRICT_COMPILE], + *) + # Do not use -ansi. It limits us to C90, and it breaks some platforms. + # We use -std=c11 to disable the gnu99 defaults and its associated warnings + CFLAGS="$CFLAGS -std=c11" + ;; + esac + + CFLAGS="$CFLAGS -Wall -pedantic -Wshadow -Wpointer-arith -Wmissing-prototypes -Wwrite-strings" ++ ++ # Suppress clang C warnings: ++ CFLAGS="$CFLAGS -Wno-sign-compare -Wno-unused" + else + case "${host}" in + *-*-cygwin) + if test "`$CC /help 2>&1 | head -c9`" = "Microsoft" + then + CFLAGS="$CFLAGS /W4" + fi ;; + *-*-mingw*) + CFLAGS="$CFLAGS -W4" ;; + esac + fi + if test "$GXX" = yes + then + CXXFLAGS="$CXXFLAGS -W -Wall -pedantic -Wpointer-arith -Wwrite-strings -Wno-long-long" ++ ++ # Suppress clang C++ warnings: ++ CXXFLAGS="$CXXFLAGS -Wno-unused -Wno-unused-parameter" + else + case "${host}" in + *-*-cygwin) + if test "`$CXX /help 2>&1 | head -c9`" = "Microsoft" + then + CXXFLAGS="$CXXFLAGS /W4" + fi ;; + *-*-mingw*) +diff --git a/intl/icu/source/configure b/intl/icu/source/configure +--- a/intl/icu/source/configure ++++ b/intl/icu/source/configure +@@ -4359,30 +4359,36 @@ fi + *) + # Do not use -ansi. It limits us to C90, and it breaks some platforms. + # We use -std=c11 to disable the gnu99 defaults and its associated warnings + CFLAGS="$CFLAGS -std=c11" + ;; + esac + + CFLAGS="$CFLAGS -Wall -pedantic -Wshadow -Wpointer-arith -Wmissing-prototypes -Wwrite-strings" ++ ++ # Suppress clang C warnings: ++ CFLAGS="$CFLAGS -Wno-sign-compare -Wno-unused" + else + case "${host}" in + *-*-cygwin) + if test "`$CC /help 2>&1 | head -c9`" = "Microsoft" + then + CFLAGS="$CFLAGS /W4" + fi ;; + *-*-mingw*) + CFLAGS="$CFLAGS -W4" ;; + esac + fi + if test "$GXX" = yes + then + CXXFLAGS="$CXXFLAGS -W -Wall -pedantic -Wpointer-arith -Wwrite-strings -Wno-long-long" ++ ++ # Suppress clang C++ warnings: ++ CXXFLAGS="$CXXFLAGS -Wno-unused -Wno-unused-parameter" + else + case "${host}" in + *-*-cygwin) + if test "`$CXX /help 2>&1 | head -c9`" = "Microsoft" + then + CXXFLAGS="$CXXFLAGS /W4" + fi ;; + *-*-mingw*) |