mirror of
https://codeberg.org/guix/guix.git
synced 2026-01-25 03:55:08 -06:00
gnu: Add icu4c-78.
* gnu/packages/icu4c.scm (icu4c-78): New variable. * gnu/local.mk (dist_patch_DATA): Add icu4c patches. * gnu/packages/patches/icu4c-78-double-conversion.patch: New file. * gnu/packages/patches/icu4c-bug-1706949-wasi-workaround.patch: New file. * gnu/packages/patches/icu4c-bug-1790071-ICU-22132-standardize-vtzone-output.patch: New file. * gnu/packages/patches/icu4c-bug-1856290-ICU-20548-dateinterval-timezone.patch: New file. * gnu/packages/patches/icu4c-bug-1954138-dtitvfmt-adopt-calendar.patch: New file. * gnu/packages/patches/icu4c-bug-1972781-chinese-based-calendar.patch: New file. * gnu/packages/patches/icu4c-bug-2000225-ICU-23264-increase-measure-unit-capacity.patch: New file. * gnu/packages/patches/icu4c-bug-2002735-ICU-23277-coptic-single-era.patch: New file. * gnu/packages/patches/icu4c-suppress-warnings.patch: New file.
This commit is contained in:
parent
1c1c9e1398
commit
fee676c728
11 changed files with 1575 additions and 8 deletions
25
gnu/local.mk
25
gnu/local.mk
|
|
@ -1610,15 +1610,24 @@ dist_patch_DATA = \
|
|||
%D%/packages/patches/icedove-observer-fix.patch \
|
||||
%D%/packages/patches/icedtea-7-hotspot-aarch64-use-c++98.patch \
|
||||
%D%/packages/patches/icedtea-7-hotspot-pointer-comparison.patch \
|
||||
%D%/packages/patches/icu4c-icu-22132-fix-vtimezone.patch \
|
||||
%D%/packages/patches/icu4c-20548-dateinterval-timezone.patch \
|
||||
%D%/packages/patches/icu4c-22132-standardize-vtzone-output.patch \
|
||||
%D%/packages/patches/icu4c-23069-rosh-hashanah-postponement.patch \
|
||||
%D%/packages/patches/icu4c-dayperiod-fractional-seconds.patch \
|
||||
%D%/packages/patches/icu4c-double-conversion.patch \
|
||||
%D%/packages/patches/icu4c-dtitvfmt-adopt-calendar.patch \
|
||||
%D%/packages/patches/icu4c-20548-dateinterval-timezone.patch \
|
||||
%D%/packages/patches/icu4c-22132-standardize-vtzone-output.patch \
|
||||
%D%/packages/patches/icu4c-23069-rosh-hashanah-postponement.patch \
|
||||
%D%/packages/patches/icu4c-78-double-conversion.patch \
|
||||
%D%/packages/patches/icu4c-bug-1706949-wasi-workaround.patch \
|
||||
%D%/packages/patches/icu4c-bug-1790071-ICU-22132-standardize-vtzone-output.patch \
|
||||
%D%/packages/patches/icu4c-bug-1856290-ICU-20548-dateinterval-timezone.patch \
|
||||
%D%/packages/patches/icu4c-bug-1954138-dtitvfmt-adopt-calendar.patch \
|
||||
%D%/packages/patches/icu4c-bug-1972781-chinese-based-calendar.patch \
|
||||
%D%/packages/patches/icu4c-bug-2000225-ICU-23264-increase-measure-unit-capacity.patch \
|
||||
%D%/packages/patches/icu4c-bug-2002735-ICU-23277-coptic-single-era.patch \
|
||||
%D%/packages/patches/icu4c-dayperiod-fractional-seconds.patch \
|
||||
%D%/packages/patches/icu4c-double-conversion.patch \
|
||||
%D%/packages/patches/icu4c-dtitvfmt-adopt-calendar.patch \
|
||||
%D%/packages/patches/icu4c-fix-TestHebrewCalendarInTemporalLeapYear.patch \
|
||||
%D%/packages/patches/icu4c-wasi-workaround.patch \
|
||||
%D%/packages/patches/icu4c-icu-22132-fix-vtimezone.patch \
|
||||
%D%/packages/patches/icu4c-suppress-warnings.patch \
|
||||
%D%/packages/patches/icu4c-wasi-workaround.patch \
|
||||
%D%/packages/patches/id3lib-CVE-2007-4460.patch \
|
||||
%D%/packages/patches/id3lib-UTF16-writing-bug.patch \
|
||||
%D%/packages/patches/ilmbase-fix-tests.patch \
|
||||
|
|
|
|||
|
|
@ -52,6 +52,12 @@
|
|||
(string-map (lambda (x) (if (char=? x #\.) #\_ x)) version)
|
||||
"-src.tgz"))
|
||||
|
||||
;; The URI format has changed starting with 78.1.
|
||||
(define (icu4c-uri->=78 version)
|
||||
(string-append
|
||||
"https://github.com/unicode-org/icu/releases/download/release-"
|
||||
version "/icu4c-" version "-sources.tgz"))
|
||||
|
||||
(define-public icu4c-73
|
||||
(package
|
||||
(name "icu4c")
|
||||
|
|
@ -201,6 +207,27 @@ C/C++ part.")
|
|||
"icu4c-dtitvfmt-adopt-calendar.patch"
|
||||
"icu4c-wasi-workaround.patch"))))))
|
||||
|
||||
(define-public icu4c-78
|
||||
(package
|
||||
(inherit icu4c-77)
|
||||
(name "icu4c")
|
||||
(version "78.2")
|
||||
(source
|
||||
(origin
|
||||
(inherit (package-source icu4c-77))
|
||||
(uri (icu4c-uri->=78 version))
|
||||
(sha256 (base32 "0dfzi4yf0wmng1866y2yd22cj1lrnzmx5qihjqh4npa3bixni69y"))
|
||||
(patches
|
||||
(search-patches
|
||||
"icu4c-bug-1706949-wasi-workaround.patch"
|
||||
"icu4c-bug-1790071-ICU-22132-standardize-vtzone-output.patch"
|
||||
"icu4c-bug-1856290-ICU-20548-dateinterval-timezone.patch"
|
||||
"icu4c-bug-1954138-dtitvfmt-adopt-calendar.patch"
|
||||
"icu4c-bug-1972781-chinese-based-calendar.patch"
|
||||
"icu4c-bug-2000225-ICU-23264-increase-measure-unit-capacity.patch"
|
||||
"icu4c-78-double-conversion.patch"
|
||||
"icu4c-suppress-warnings.patch"))))))
|
||||
|
||||
(define-public icu4c-build-root
|
||||
(package
|
||||
(inherit icu4c)
|
||||
|
|
|
|||
198
gnu/packages/patches/icu4c-78-double-conversion.patch
Normal file
198
gnu/packages/patches/icu4c-78-double-conversion.patch
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
diff --git a/source/i18n/measunit_extra.cpp b/source/i18n/measunit_extra.cpp
|
||||
--- a/source/i18n/measunit_extra.cpp
|
||||
+++ b/source/i18n/measunit_extra.cpp
|
||||
@@ -10,17 +10,21 @@
|
||||
|
||||
// Allow implicit conversion from char16_t* to UnicodeString for this file:
|
||||
// Helpful in toString methods and elsewhere.
|
||||
#define UNISTR_FROM_STRING_EXPLICIT
|
||||
|
||||
#include "charstr.h"
|
||||
#include "cmemory.h"
|
||||
#include "cstring.h"
|
||||
+#ifdef JS_HAS_INTL_API
|
||||
+#include "double-conversion/string-to-double.h"
|
||||
+#else
|
||||
#include "double-conversion-string-to-double.h"
|
||||
+#endif
|
||||
#include "measunit_impl.h"
|
||||
#include "resource.h"
|
||||
#include "uarrsort.h"
|
||||
#include "uassert.h"
|
||||
#include "ucln_in.h"
|
||||
#include "umutex.h"
|
||||
#include "unicode/bytestrie.h"
|
||||
#include "unicode/bytestriebuilder.h"
|
||||
@@ -33,17 +37,21 @@
|
||||
#include "util.h"
|
||||
#include <limits.h>
|
||||
#include <cstdlib>
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
+#ifdef JS_HAS_INTL_API
|
||||
+using double_conversion::StringToDoubleConverter;
|
||||
+#else
|
||||
using icu::double_conversion::StringToDoubleConverter;
|
||||
+#endif
|
||||
|
||||
// TODO: Propose a new error code for this?
|
||||
constexpr UErrorCode kUnitIdentifierSyntaxError = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
|
||||
// Trie value offset for SI or binary prefixes. This is big enough to ensure we only
|
||||
// insert positive integers into the trie.
|
||||
constexpr int32_t kPrefixOffset = 64;
|
||||
static_assert(kPrefixOffset + UMEASURE_PREFIX_INTERNAL_MIN_BIN > 0,
|
||||
diff --git a/source/i18n/number_decimalquantity.cpp b/source/i18n/number_decimalquantity.cpp
|
||||
--- a/source/i18n/number_decimalquantity.cpp
|
||||
+++ b/source/i18n/number_decimalquantity.cpp
|
||||
@@ -11,28 +11,37 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "unicode/plurrule.h"
|
||||
#include "cmemory.h"
|
||||
#include "number_decnum.h"
|
||||
#include "putilimp.h"
|
||||
#include "number_decimalquantity.h"
|
||||
#include "number_roundingutils.h"
|
||||
+#ifdef JS_HAS_INTL_API
|
||||
+#include "double-conversion/double-conversion.h"
|
||||
+#else
|
||||
#include "double-conversion.h"
|
||||
+#endif
|
||||
#include "charstr.h"
|
||||
#include "number_utils.h"
|
||||
#include "uassert.h"
|
||||
#include "util.h"
|
||||
|
||||
using namespace icu;
|
||||
using namespace icu::number;
|
||||
using namespace icu::number::impl;
|
||||
|
||||
+#ifdef JS_HAS_INTL_API
|
||||
+using double_conversion::DoubleToStringConverter;
|
||||
+using double_conversion::StringToDoubleConverter;
|
||||
+#else
|
||||
using icu::double_conversion::DoubleToStringConverter;
|
||||
using icu::double_conversion::StringToDoubleConverter;
|
||||
+#endif
|
||||
|
||||
namespace {
|
||||
|
||||
int8_t NEGATIVE_FLAG = 1;
|
||||
int8_t INFINITY_FLAG = 2;
|
||||
int8_t NAN_FLAG = 4;
|
||||
|
||||
/** Helper function for safe subtraction (no overflow). */
|
||||
diff --git a/source/i18n/number_rounding.cpp b/source/i18n/number_rounding.cpp
|
||||
--- a/source/i18n/number_rounding.cpp
|
||||
+++ b/source/i18n/number_rounding.cpp
|
||||
@@ -5,17 +5,21 @@
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "charstr.h"
|
||||
#include "uassert.h"
|
||||
#include "unicode/numberformatter.h"
|
||||
#include "number_types.h"
|
||||
#include "number_decimalquantity.h"
|
||||
+#ifdef JS_HAS_INTL_API
|
||||
+#include "double-conversion/double-conversion.h"
|
||||
+#else
|
||||
#include "double-conversion.h"
|
||||
+#endif
|
||||
#include "number_roundingutils.h"
|
||||
#include "number_skeletons.h"
|
||||
#include "number_decnum.h"
|
||||
#include "putilimp.h"
|
||||
#include "string_segment.h"
|
||||
|
||||
using namespace icu;
|
||||
using namespace icu::number;
|
||||
diff --git a/source/i18n/number_utils.cpp b/source/i18n/number_utils.cpp
|
||||
--- a/source/i18n/number_utils.cpp
|
||||
+++ b/source/i18n/number_utils.cpp
|
||||
@@ -12,26 +12,34 @@
|
||||
#include <stdlib.h>
|
||||
#include <cmath>
|
||||
#include "number_decnum.h"
|
||||
#include "number_types.h"
|
||||
#include "number_utils.h"
|
||||
#include "charstr.h"
|
||||
#include "decContext.h"
|
||||
#include "decNumber.h"
|
||||
+#ifdef JS_HAS_INTL_API
|
||||
+#include "double-conversion/double-conversion.h"
|
||||
+#else
|
||||
#include "double-conversion.h"
|
||||
+#endif
|
||||
#include "fphdlimp.h"
|
||||
#include "uresimp.h"
|
||||
#include "ureslocs.h"
|
||||
|
||||
using namespace icu;
|
||||
using namespace icu::number;
|
||||
using namespace icu::number::impl;
|
||||
|
||||
+#ifdef JS_HAS_INTL_API
|
||||
+using double_conversion::DoubleToStringConverter;
|
||||
+#else
|
||||
using icu::double_conversion::DoubleToStringConverter;
|
||||
+#endif
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
const char16_t*
|
||||
doGetPattern(UResourceBundle* res, const char* nsName, const char* patternKey, UErrorCode& publicStatus,
|
||||
UErrorCode& localStatus) {
|
||||
// Construct the path into the resource bundle
|
||||
diff --git a/source/i18n/units_converter.cpp b/source/i18n/units_converter.cpp
|
||||
--- a/source/i18n/units_converter.cpp
|
||||
+++ b/source/i18n/units_converter.cpp
|
||||
@@ -3,17 +3,21 @@
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "charstr.h"
|
||||
#include "cmemory.h"
|
||||
#include "cstring.h"
|
||||
+#ifdef JS_HAS_INTL_API
|
||||
+#include "double-conversion/string-to-double.h"
|
||||
+#else
|
||||
#include "double-conversion-string-to-double.h"
|
||||
+#endif
|
||||
#include "measunit_impl.h"
|
||||
#include "putilimp.h"
|
||||
#include "uassert.h"
|
||||
#include "unicode/errorcode.h"
|
||||
#include "unicode/localpointer.h"
|
||||
#include "unicode/stringpiece.h"
|
||||
#include "units_converter.h"
|
||||
#include <algorithm>
|
||||
@@ -105,17 +109,21 @@ void Factor::substituteConstants() {
|
||||
this->constantExponents[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/* Helpers */
|
||||
|
||||
+#ifdef JS_HAS_INTL_API
|
||||
+using double_conversion::StringToDoubleConverter;
|
||||
+#else
|
||||
using icu::double_conversion::StringToDoubleConverter;
|
||||
+#endif
|
||||
|
||||
// TODO: Make this a shared-utility function.
|
||||
// Returns `double` from a scientific number(i.e. "1", "2.01" or "3.09E+4")
|
||||
double strToDouble(StringPiece strNum, UErrorCode &status) {
|
||||
// We are processing well-formed input, so we don't need any special options to
|
||||
// StringToDoubleConverter.
|
||||
StringToDoubleConverter converter(0, 0, 0, "", "");
|
||||
int32_t count;
|
||||
832
gnu/packages/patches/icu4c-bug-1706949-wasi-workaround.patch
Normal file
832
gnu/packages/patches/icu4c-bug-1706949-wasi-workaround.patch
Normal file
|
|
@ -0,0 +1,832 @@
|
|||
# Handle WASI lack of support for <thread> and <atomic>.
|
||||
#
|
||||
# WASI issue: https://github.com/WebAssembly/wasi-sdk/issues/180
|
||||
|
||||
diff --git a/source/common/putilimp.h b/source/common/putilimp.h
|
||||
--- a/source/common/putilimp.h
|
||||
+++ b/source/common/putilimp.h
|
||||
@@ -105,10 +105,12 @@ typedef size_t uintptr_t;
|
||||
#endif
|
||||
#elif U_PLATFORM == U_PF_OS400
|
||||
/* not defined */
|
||||
#elif U_PLATFORM == U_PF_HAIKU
|
||||
/* not defined */
|
||||
+#elif defined(__wasi__)
|
||||
+ /* not defined */
|
||||
#else
|
||||
# define U_TZSET tzset
|
||||
#endif
|
||||
|
||||
#if defined(U_TIMEZONE) || defined(U_HAVE_TIMEZONE)
|
||||
@@ -130,10 +132,12 @@ typedef size_t uintptr_t;
|
||||
/* not defined */
|
||||
#elif U_PLATFORM == U_PF_OS400
|
||||
/* not defined */
|
||||
#elif U_PLATFORM == U_PF_IPHONE
|
||||
/* not defined */
|
||||
+#elif defined(__wasi__)
|
||||
+ /* not defined */
|
||||
#else
|
||||
# define U_TIMEZONE timezone
|
||||
#endif
|
||||
|
||||
#if defined(U_TZNAME) || defined(U_HAVE_TZNAME)
|
||||
@@ -145,10 +149,12 @@ typedef size_t uintptr_t;
|
||||
#endif
|
||||
#elif U_PLATFORM == U_PF_OS400
|
||||
/* not defined */
|
||||
#elif U_PLATFORM == U_PF_HAIKU
|
||||
/* not defined, (well it is but a loop back to icu) */
|
||||
+#elif defined(__wasi__)
|
||||
+ /* not defined */
|
||||
#else
|
||||
# define U_TZNAME tzname
|
||||
#endif
|
||||
|
||||
#ifdef U_HAVE_MMAP
|
||||
diff --git a/source/common/umapfile.h b/source/common/umapfile.h
|
||||
--- a/source/common/umapfile.h
|
||||
+++ b/source/common/umapfile.h
|
||||
@@ -38,10 +38,12 @@ U_CFUNC void uprv_unmapFile(UDataMemory
|
||||
#define MAP_POSIX 2
|
||||
#define MAP_STDIO 3
|
||||
|
||||
#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
|
||||
# define MAP_IMPLEMENTATION MAP_POSIX
|
||||
#else /* unknown platform, no memory map implementation: use stdio.h and uprv_malloc() instead */
|
||||
diff --git a/source/common/umutex.cpp b/source/common/umutex.cpp
|
||||
--- a/source/common/umutex.cpp
|
||||
+++ b/source/common/umutex.cpp
|
||||
@@ -41,10 +41,11 @@ U_NAMESPACE_BEGIN
|
||||
*
|
||||
* ICU Mutex wrappers.
|
||||
*
|
||||
*************************************************************************************************/
|
||||
|
||||
+#ifndef __wasi__
|
||||
namespace {
|
||||
std::mutex *initMutex;
|
||||
std::condition_variable *initCondition;
|
||||
|
||||
// The ICU global mutex.
|
||||
@@ -53,32 +54,38 @@ UMutex globalMutex;
|
||||
|
||||
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();
|
||||
|
||||
// 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();
|
||||
+#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) {
|
||||
std::call_once(*pInitFlag, umtx_init);
|
||||
std::lock_guard<std::mutex> guard(*initMutex);
|
||||
@@ -91,41 +98,48 @@ 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;
|
||||
}
|
||||
gListHead = nullptr;
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************************************
|
||||
*
|
||||
@@ -141,22 +155,26 @@ umtx_unlock(UMutex* mutex)
|
||||
// that knows the C++ types involved. This function returns true if
|
||||
// the caller needs to call the Init function.
|
||||
//
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -166,15 +184,17 @@ umtx_initImplPreInit(UInitOnce &uio) {
|
||||
// Some threads may be racing to test the fState variable outside of the mutex,
|
||||
// requiring the use of store/release when changing its value.
|
||||
|
||||
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/source/common/umutex.h b/source/common/umutex.h
|
||||
--- a/source/common/umutex.h
|
||||
+++ b/source/common/umutex.h
|
||||
@@ -18,13 +18,16 @@
|
||||
*/
|
||||
|
||||
#ifndef UMUTEX_H
|
||||
#define UMUTEX_H
|
||||
|
||||
+#ifndef __wasi__
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
+#endif
|
||||
+
|
||||
#include <type_traits>
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "unicode/uclean.h"
|
||||
#include "unicode/uobject.h"
|
||||
@@ -43,10 +46,12 @@ U_NAMESPACE_BEGIN
|
||||
*
|
||||
* Low Level Atomic Operations, ICU wrappers for.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
+#ifndef __wasi__
|
||||
+
|
||||
typedef std::atomic<int32_t> u_atomic_int32_t;
|
||||
|
||||
inline int32_t umtx_loadAcquire(u_atomic_int32_t &var) {
|
||||
return var.load(std::memory_order_acquire);
|
||||
}
|
||||
@@ -61,10 +66,31 @@ inline int32_t umtx_atomic_inc(u_atomic_
|
||||
|
||||
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;
|
||||
+
|
||||
+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
|
||||
|
||||
/*************************************************************************************************
|
||||
*
|
||||
* UInitOnce Definitions.
|
||||
*
|
||||
@@ -211,21 +237,29 @@ public:
|
||||
U_COMMON_API UMutex& operator=(const UMutex& other) = delete;
|
||||
U_COMMON_API void* operator new(size_t) = delete;
|
||||
|
||||
// requirements for C++ BasicLockable, allows UMutex to work with std::lock_guard
|
||||
U_COMMON_API void lock() {
|
||||
+#ifndef __wasi__
|
||||
std::mutex *m = fMutex.load(std::memory_order_acquire);
|
||||
if (m == nullptr) { m = getMutex(); }
|
||||
m->lock();
|
||||
+#endif
|
||||
}
|
||||
- U_COMMON_API void unlock() { fMutex.load(std::memory_order_relaxed)->unlock(); }
|
||||
+ U_COMMON_API void unlock() {
|
||||
+#ifndef __wasi__
|
||||
+ fMutex.load(std::memory_order_relaxed)->unlock();
|
||||
+#endif
|
||||
+ }
|
||||
|
||||
U_COMMON_API 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().
|
||||
*/
|
||||
UMutex *fListLink { nullptr };
|
||||
@@ -233,11 +267,13 @@ private:
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
+#ifndef __wasi__
|
||||
std::mutex *getMutex();
|
||||
+#endif
|
||||
};
|
||||
|
||||
|
||||
/* Lock a mutex.
|
||||
* @param mutex The given mutex to be locked. Pass NULL to specify
|
||||
diff --git a/source/common/unifiedcache.cpp b/source/common/unifiedcache.cpp
|
||||
--- a/source/common/unifiedcache.cpp
|
||||
+++ b/source/common/unifiedcache.cpp
|
||||
@@ -11,19 +11,23 @@
|
||||
*/
|
||||
|
||||
#include "unifiedcache.h"
|
||||
|
||||
#include <algorithm> // For std::max()
|
||||
+#ifndef __wasi__
|
||||
#include <mutex>
|
||||
+#endif
|
||||
|
||||
#include "uassert.h"
|
||||
#include "uhash.h"
|
||||
#include "ucln_cmn.h"
|
||||
|
||||
static icu::UnifiedCache *gCache = nullptr;
|
||||
+#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_
|
||||
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 == nullptr);
|
||||
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 == nullptr) {
|
||||
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 != nullptr && !_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 == nullptr);
|
||||
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 != nullptr && _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/source/i18n/decContext.h b/source/i18n/decContext.h
|
||||
--- a/source/i18n/decContext.h
|
||||
+++ b/source/i18n/decContext.h
|
||||
@@ -59,11 +59,13 @@
|
||||
|
||||
#if !defined(int32_t)
|
||||
/* #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)
|
||||
#define DECEXTFLAG 1 /* 1=enable extended flags */
|
||||
#endif
|
||||
diff --git a/source/i18n/decimfmt.cpp b/source/i18n/decimfmt.cpp
|
||||
--- a/source/i18n/decimfmt.cpp
|
||||
+++ b/source/i18n/decimfmt.cpp
|
||||
@@ -478,12 +478,17 @@ DecimalFormat& DecimalFormat::operator=(
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
DecimalFormat* DecimalFormat::clone() const {
|
||||
// can only clone valid objects.
|
||||
@@ -1635,12 +1640,17 @@ void DecimalFormat::touch(UErrorCode& st
|
||||
|
||||
// Do this after fields->exportedProperties are set up
|
||||
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);
|
||||
NumberFormat::setMaximumIntegerDigits(fields->exportedProperties.maximumIntegerDigits);
|
||||
NumberFormat::setMinimumIntegerDigits(fields->exportedProperties.minimumIntegerDigits);
|
||||
@@ -1671,11 +1681,15 @@ const numparse::impl::NumberParserImpl*
|
||||
if (U_FAILURE(status)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Try computing the parser on our own
|
||||
@@ -1690,25 +1704,34 @@ const numparse::impl::NumberParserImpl*
|
||||
|
||||
// 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->atomicParser.compare_exchange_strong(ptr, temp)) {
|
||||
// Another thread beat us to computing the parser
|
||||
delete temp;
|
||||
return ptr;
|
||||
} else {
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Try computing the parser on our own
|
||||
@@ -1719,18 +1742,23 @@ const numparse::impl::NumberParserImpl*
|
||||
}
|
||||
|
||||
// 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;
|
||||
return ptr;
|
||||
} else {
|
||||
// Our copy of the parser got stored in the atomic
|
||||
return temp;
|
||||
}
|
||||
+#else
|
||||
+ nonConstThis->fields->atomicCurrencyParser = temp;
|
||||
+ return temp;
|
||||
+#endif
|
||||
}
|
||||
|
||||
void
|
||||
DecimalFormat::fieldPositionHelper(
|
||||
const UFormattedNumberData& formatted,
|
||||
diff --git a/source/i18n/number_mapper.h b/source/i18n/number_mapper.h
|
||||
--- a/source/i18n/number_mapper.h
|
||||
+++ b/source/i18n/number_mapper.h
|
||||
@@ -5,18 +5,21 @@
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
#ifndef __NUMBER_MAPPER_H__
|
||||
#define __NUMBER_MAPPER_H__
|
||||
|
||||
-#include <atomic>
|
||||
#include "number_types.h"
|
||||
#include "unicode/currpinf.h"
|
||||
#include "standardplural.h"
|
||||
#include "number_patternstring.h"
|
||||
#include "number_currencysymbols.h"
|
||||
#include "numparse_impl.h"
|
||||
|
||||
+#ifndef __wasi__
|
||||
+#include <atomic>
|
||||
+#endif
|
||||
+
|
||||
U_NAMESPACE_BEGIN
|
||||
namespace number::impl {
|
||||
|
||||
class AutoAffixPatternProvider;
|
||||
class CurrencyPluralInfoAffixProvider;
|
||||
@@ -194,14 +197,22 @@ struct DecimalFormatFields : public UMem
|
||||
* #format} method uses the formatter directly without needing to synchronize.
|
||||
*/
|
||||
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;
|
||||
|
||||
/** The effective properties as exported from the formatter object. Used by some getters. */
|
||||
diff --git a/source/i18n/numrange_fluent.cpp b/source/i18n/numrange_fluent.cpp
|
||||
--- a/source/i18n/numrange_fluent.cpp
|
||||
+++ b/source/i18n/numrange_fluent.cpp
|
||||
@@ -246,33 +246,53 @@ LocalizedNumberRangeFormatter::Localized
|
||||
|
||||
LocalizedNumberRangeFormatter::LocalizedNumberRangeFormatter(NFS<LNF>&& src) noexcept
|
||||
: 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) 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) {
|
||||
fMacros = macros;
|
||||
fMacros.locale = locale;
|
||||
@@ -363,11 +383,15 @@ LocalizedNumberRangeFormatter::getFormat
|
||||
if (U_FAILURE(status)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// First try to get the pre-computed formatter
|
||||
+#ifndef __wasi__
|
||||
auto* ptr = fAtomicFormatter.load();
|
||||
+#else
|
||||
+ auto* ptr = fAtomicFormatter;
|
||||
+#endif
|
||||
if (ptr != nullptr) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// Try computing the formatter on our own
|
||||
@@ -378,17 +402,22 @@ LocalizedNumberRangeFormatter::getFormat
|
||||
|
||||
// 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 formatter object.
|
||||
auto* nonConstThis = const_cast<LocalizedNumberRangeFormatter*>(this);
|
||||
+#ifndef __wasi__
|
||||
if (!nonConstThis->fAtomicFormatter.compare_exchange_strong(ptr, temp.getAlias())) {
|
||||
// Another thread beat us to computing the formatter
|
||||
return ptr;
|
||||
} else {
|
||||
// Our copy of the formatter got stored in the atomic
|
||||
return temp.orphan();
|
||||
}
|
||||
+#else
|
||||
+ nonConstThis->fAtomicFormatter = temp.getAlias();
|
||||
+ return temp.orphan();
|
||||
+#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
diff --git a/source/i18n/unicode/numberrangeformatter.h b/source/i18n/unicode/numberrangeformatter.h
|
||||
--- a/source/i18n/unicode/numberrangeformatter.h
|
||||
+++ b/source/i18n/unicode/numberrangeformatter.h
|
||||
@@ -8,18 +8,21 @@
|
||||
|
||||
#if U_SHOW_CPLUSPLUS_API
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
-#include <atomic>
|
||||
#include "unicode/appendable.h"
|
||||
#include "unicode/fieldpos.h"
|
||||
#include "unicode/formattedvalue.h"
|
||||
#include "unicode/fpositer.h"
|
||||
#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.
|
||||
*
|
||||
* The main entrypoint to the formatting of ranges of numbers, including currencies and other units of measurement.
|
||||
@@ -559,11 +562,15 @@ class U_I18N_API_CLASS LocalizedNumberRa
|
||||
* @stable ICU 63
|
||||
*/
|
||||
U_I18N_API ~LocalizedNumberRangeFormatter();
|
||||
|
||||
private:
|
||||
+#ifndef __wasi__
|
||||
std::atomic<impl::NumberRangeFormatterImpl*> fAtomicFormatter = {};
|
||||
+#else
|
||||
+ impl::NumberRangeFormatterImpl* fAtomicFormatter = nullptr;
|
||||
+#endif
|
||||
|
||||
const impl::NumberRangeFormatterImpl* getFormatter(UErrorCode& stauts) const;
|
||||
|
||||
explicit LocalizedNumberRangeFormatter(
|
||||
const NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>& other);
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
diff --git a/source/i18n/vtzone.cpp b/source/i18n/vtzone.cpp
|
||||
--- a/source/i18n/vtzone.cpp
|
||||
+++ b/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);
|
||||
}
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
# Handle 'O' time zone skeleton in DateIntervalFormat.
|
||||
# Keep time zone skeleton field widths in DateIntervalFormat.
|
||||
#
|
||||
# ICU bug: https://unicode-org.atlassian.net/browse/ICU-20548
|
||||
|
||||
diff --git a/source/i18n/dtitv_impl.h b/source/i18n/dtitv_impl.h
|
||||
--- a/source/i18n/dtitv_impl.h
|
||||
+++ b/source/i18n/dtitv_impl.h
|
||||
@@ -84,16 +84,19 @@
|
||||
#define CAP_W ((char16_t)0x0057)
|
||||
#define CAP_Y ((char16_t)0x0059)
|
||||
#define CAP_Z ((char16_t)0x005A)
|
||||
|
||||
//#define MINIMUM_SUPPORTED_CALENDAR_FIELD UCAL_MINUTE
|
||||
|
||||
#define MAX_E_COUNT 5
|
||||
#define MAX_M_COUNT 5
|
||||
+#define MAX_z_COUNT 4
|
||||
+#define MAX_v_COUNT 4
|
||||
+#define MAX_O_COUNT 4
|
||||
//#define MAX_INTERVAL_INDEX 4
|
||||
#define MAX_POSITIVE_INT 56632
|
||||
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
||||
#endif
|
||||
//eof
|
||||
diff --git a/source/i18n/dtitvfmt.cpp b/source/i18n/dtitvfmt.cpp
|
||||
--- a/source/i18n/dtitvfmt.cpp
|
||||
+++ b/source/i18n/dtitvfmt.cpp
|
||||
@@ -1061,16 +1061,17 @@ DateIntervalFormat::getDateTimeSkeleton(
|
||||
// timeSkeleton follows the sequence of hm*[v|z]?
|
||||
int32_t ECount = 0;
|
||||
int32_t dCount = 0;
|
||||
int32_t MCount = 0;
|
||||
int32_t yCount = 0;
|
||||
int32_t mCount = 0;
|
||||
int32_t vCount = 0;
|
||||
int32_t zCount = 0;
|
||||
+ int32_t OCount = 0;
|
||||
char16_t hourChar = u'\0';
|
||||
int32_t i;
|
||||
|
||||
for (i = 0; i < skeleton.length(); ++i) {
|
||||
char16_t ch = skeleton[i];
|
||||
switch ( ch ) {
|
||||
case CAP_E:
|
||||
dateSkeleton.append(ch);
|
||||
@@ -1123,16 +1124,20 @@ DateIntervalFormat::getDateTimeSkeleton(
|
||||
case LOW_Z:
|
||||
++zCount;
|
||||
timeSkeleton.append(ch);
|
||||
break;
|
||||
case LOW_V:
|
||||
++vCount;
|
||||
timeSkeleton.append(ch);
|
||||
break;
|
||||
+ case CAP_O:
|
||||
+ ++OCount;
|
||||
+ timeSkeleton.append(ch);
|
||||
+ break;
|
||||
case LOW_A:
|
||||
case CAP_V:
|
||||
case CAP_Z:
|
||||
case LOW_J:
|
||||
case LOW_S:
|
||||
case CAP_S:
|
||||
case CAP_A:
|
||||
case LOW_B:
|
||||
@@ -1174,20 +1179,41 @@ DateIntervalFormat::getDateTimeSkeleton(
|
||||
/* generate normalized form for time */
|
||||
if ( hourChar != u'\0' ) {
|
||||
normalizedTimeSkeleton.append(hourChar);
|
||||
}
|
||||
if ( mCount != 0 ) {
|
||||
normalizedTimeSkeleton.append(LOW_M);
|
||||
}
|
||||
if ( zCount != 0 ) {
|
||||
- normalizedTimeSkeleton.append(LOW_Z);
|
||||
+ if ( zCount <= 3 ) {
|
||||
+ normalizedTimeSkeleton.append(LOW_Z);
|
||||
+ } else {
|
||||
+ for ( int32_t j = 0; j < zCount && j < MAX_z_COUNT; ++j ) {
|
||||
+ normalizedTimeSkeleton.append(LOW_Z);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
if ( vCount != 0 ) {
|
||||
- normalizedTimeSkeleton.append(LOW_V);
|
||||
+ if ( vCount <= 3 ) {
|
||||
+ normalizedTimeSkeleton.append(LOW_V);
|
||||
+ } else {
|
||||
+ for ( int32_t j = 0; j < vCount && j < MAX_v_COUNT; ++j ) {
|
||||
+ normalizedTimeSkeleton.append(LOW_V);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if ( OCount != 0 ) {
|
||||
+ if ( OCount <= 3 ) {
|
||||
+ normalizedTimeSkeleton.append(CAP_O);
|
||||
+ } else {
|
||||
+ for ( int32_t j = 0; j < OCount && j < MAX_O_COUNT; ++j ) {
|
||||
+ normalizedTimeSkeleton.append(CAP_O);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate date or time interval pattern from resource,
|
||||
* and set them into the interval pattern locale to this formatter.
|
||||
*
|
||||
@@ -1732,18 +1758,23 @@ DateIntervalFormat::adjustFieldWidth(con
|
||||
findReplaceInPattern(adjustedPtn, UnicodeString(u"a\u202F",-1), UnicodeString());
|
||||
findReplaceInPattern(adjustedPtn, UnicodeString(LOW_A), UnicodeString());
|
||||
// adjust interior double spaces, remove exterior whitespace
|
||||
findReplaceInPattern(adjustedPtn, UnicodeString(" "), UnicodeString(" "));
|
||||
adjustedPtn.trim();
|
||||
}
|
||||
if ( differenceInfo == 2 ) {
|
||||
if (inputSkeleton.indexOf(LOW_Z) != -1) {
|
||||
+ bestMatchSkeletonFieldWidth[(int)(LOW_Z - PATTERN_CHAR_BASE)] = bestMatchSkeletonFieldWidth[(int)(LOW_V - PATTERN_CHAR_BASE)];
|
||||
findReplaceInPattern(adjustedPtn, UnicodeString(LOW_V), UnicodeString(LOW_Z));
|
||||
}
|
||||
+ if (inputSkeleton.indexOf(CAP_O) != -1) {
|
||||
+ bestMatchSkeletonFieldWidth[(int)(CAP_O - PATTERN_CHAR_BASE)] = bestMatchSkeletonFieldWidth[(int)(LOW_V - PATTERN_CHAR_BASE)];
|
||||
+ findReplaceInPattern(adjustedPtn, UnicodeString(LOW_V), UnicodeString(CAP_O));
|
||||
+ }
|
||||
if (inputSkeleton.indexOf(CAP_K) != -1) {
|
||||
findReplaceInPattern(adjustedPtn, UnicodeString(LOW_H), UnicodeString(CAP_K));
|
||||
}
|
||||
if (inputSkeleton.indexOf(LOW_K) != -1) {
|
||||
findReplaceInPattern(adjustedPtn, UnicodeString(CAP_H), UnicodeString(LOW_K));
|
||||
}
|
||||
if (inputSkeleton.indexOf(LOW_B) != -1) {
|
||||
findReplaceInPattern(adjustedPtn, UnicodeString(LOW_A), UnicodeString(LOW_B));
|
||||
diff --git a/source/i18n/dtitvinf.cpp b/source/i18n/dtitvinf.cpp
|
||||
--- a/source/i18n/dtitvinf.cpp
|
||||
+++ b/source/i18n/dtitvinf.cpp
|
||||
@@ -582,19 +582,20 @@ DateIntervalInfo::getBestSkeleton(const
|
||||
|
||||
// hack for certain alternate characters
|
||||
// resource bundles only have time skeletons containing 'v', 'h', and 'H'
|
||||
// but not time skeletons containing 'z', 'K', or 'k'
|
||||
// the skeleton may also include 'a' or 'b', which never occur in the resource bundles, so strip them out too
|
||||
UBool replacedAlternateChars = false;
|
||||
const UnicodeString* inputSkeleton = &skeleton;
|
||||
UnicodeString copySkeleton;
|
||||
- if ( skeleton.indexOf(LOW_Z) != -1 || skeleton.indexOf(LOW_K) != -1 || skeleton.indexOf(CAP_K) != -1 || skeleton.indexOf(LOW_A) != -1 || skeleton.indexOf(LOW_B) != -1 ) {
|
||||
+ if ( skeleton.indexOf(LOW_Z) != -1 || skeleton.indexOf(CAP_O) != -1 || skeleton.indexOf(LOW_K) != -1 || skeleton.indexOf(CAP_K) != -1 || skeleton.indexOf(LOW_A) != -1 || skeleton.indexOf(LOW_B) != -1 ) {
|
||||
copySkeleton = skeleton;
|
||||
copySkeleton.findAndReplace(UnicodeString(LOW_Z), UnicodeString(LOW_V));
|
||||
+ copySkeleton.findAndReplace(UnicodeString(CAP_O), UnicodeString(LOW_V));
|
||||
copySkeleton.findAndReplace(UnicodeString(LOW_K), UnicodeString(CAP_H));
|
||||
copySkeleton.findAndReplace(UnicodeString(CAP_K), UnicodeString(LOW_H));
|
||||
copySkeleton.findAndReplace(UnicodeString(LOW_A), UnicodeString());
|
||||
copySkeleton.findAndReplace(UnicodeString(LOW_B), UnicodeString());
|
||||
inputSkeleton = ©Skeleton;
|
||||
replacedAlternateChars = true;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
diff --git a/source/i18n/dtitvfmt.cpp b/source/i18n/dtitvfmt.cpp
|
||||
--- a/source/i18n/dtitvfmt.cpp
|
||||
+++ b/source/i18n/dtitvfmt.cpp
|
||||
@@ -630,16 +630,38 @@ DateIntervalFormat::getTimeZone() const
|
||||
{
|
||||
if (fDateFormat != nullptr) {
|
||||
Mutex lock(&gFormatterMutex);
|
||||
return fDateFormat->getTimeZone();
|
||||
}
|
||||
// If fDateFormat is nullptr (unexpected), create default timezone.
|
||||
return *(TimeZone::createDefault());
|
||||
}
|
||||
+
|
||||
+void DateIntervalFormat::adoptCalendar(Calendar *calendarToAdopt) {
|
||||
+ if (fDateFormat != nullptr) {
|
||||
+ fDateFormat->adoptCalendar(calendarToAdopt);
|
||||
+ }
|
||||
+
|
||||
+ // The fDateFormat has the primary calendar for the DateIntervalFormat and has
|
||||
+ // ownership of any adopted Calendar; fFromCalendar and fToCalendar are internal
|
||||
+ // work clones of that calendar.
|
||||
+
|
||||
+ delete fFromCalendar;
|
||||
+ fFromCalendar = nullptr;
|
||||
+
|
||||
+ delete fToCalendar;
|
||||
+ fToCalendar = nullptr;
|
||||
+
|
||||
+ const Calendar *calendar = fDateFormat->getCalendar();
|
||||
+ if (calendar != nullptr) {
|
||||
+ fFromCalendar = calendar->clone();
|
||||
+ fToCalendar = calendar->clone();
|
||||
+ }
|
||||
+}
|
||||
|
||||
void
|
||||
DateIntervalFormat::setContext(UDisplayContext value, UErrorCode& status)
|
||||
{
|
||||
if (U_FAILURE(status))
|
||||
return;
|
||||
if (static_cast<UDisplayContextType>(static_cast<uint32_t>(value) >> 8) == UDISPCTX_TYPE_CAPITALIZATION) {
|
||||
fCapitalizationContext = value;
|
||||
diff --git a/source/i18n/unicode/dtitvfmt.h b/source/i18n/unicode/dtitvfmt.h
|
||||
--- a/source/i18n/unicode/dtitvfmt.h
|
||||
+++ b/source/i18n/unicode/dtitvfmt.h
|
||||
@@ -625,16 +625,23 @@ public:
|
||||
/**
|
||||
* Sets the time zone for the calendar used by this DateIntervalFormat object.
|
||||
* @param zone the new time zone.
|
||||
* @stable ICU 4.8
|
||||
*/
|
||||
U_I18N_API virtual void setTimeZone(const TimeZone& zone);
|
||||
|
||||
/**
|
||||
+ * Sets the calendar used by this DateIntervalFormat object. The caller no longer owns
|
||||
+ * the Calendar object and should not delete it after this call.
|
||||
+ * @param calendarToAdopt the Calendar to be adopted.
|
||||
+ */
|
||||
+ U_I18N_API virtual void adoptCalendar(Calendar *calendarToAdopt);
|
||||
+
|
||||
+ /**
|
||||
* Set a particular UDisplayContext value in the formatter, such as
|
||||
* UDISPCTX_CAPITALIZATION_FOR_STANDALONE. This causes the formatted
|
||||
* result to be capitalized appropriately for the context in which
|
||||
* it is intended to be used, considering both the locale and the
|
||||
* type of field at the beginning of the formatted result.
|
||||
* @param value The UDisplayContext value to set.
|
||||
* @param status Input/output status. If at entry this indicates a failure
|
||||
* status, the function will do nothing; otherwise this will be
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
diff --git a/source/i18n/smpdtfmt.cpp b/source/i18n/smpdtfmt.cpp
|
||||
--- a/source/i18n/smpdtfmt.cpp
|
||||
+++ b/source/i18n/smpdtfmt.cpp
|
||||
@@ -1523,18 +1523,19 @@ SimpleDateFormat::subFormat(UnicodeStrin
|
||||
}
|
||||
|
||||
switch (patternCharIndex) {
|
||||
|
||||
// for any "G" symbol, write out the appropriate era string
|
||||
// "GGGG" is wide era name, "GGGGG" is narrow era name, anything else is abbreviated name
|
||||
case UDAT_ERA_FIELD:
|
||||
{
|
||||
- if (typeid(cal) == typeid(ChineseCalendar) ||
|
||||
- typeid(cal) == typeid(DangiCalendar)) {
|
||||
+ const char* type = cal.getType();
|
||||
+ if (strcmp(type, "chinese") == 0 ||
|
||||
+ strcmp(type, "dangi") == 0) {
|
||||
zeroPaddingNumber(currentNumberFormat,appendTo, value, 1, 9); // as in ICU4J
|
||||
} else {
|
||||
if (count == 5) {
|
||||
_appendSymbol(appendTo, value, fSymbols->fNarrowEras, fSymbols->fNarrowErasCount);
|
||||
capContextUsageType = DateFormatSymbols::kCapContextUsageEraNarrow;
|
||||
} else if (count == 4) {
|
||||
_appendSymbol(appendTo, value, fSymbols->fEraNames, fSymbols->fEraNamesCount);
|
||||
capContextUsageType = DateFormatSymbols::kCapContextUsageEraWide;
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
# Increase measure unit capacity for ICU 78.
|
||||
#
|
||||
# ICU bug: https://unicode-org.atlassian.net/browse/ICU-23264
|
||||
|
||||
diff --git a/source/i18n/number_skeletons.cpp b/source/i18n/number_skeletons.cpp
|
||||
--- a/source/i18n/number_skeletons.cpp
|
||||
+++ b/source/i18n/number_skeletons.cpp
|
||||
@@ -1067,18 +1067,17 @@ void blueprint_helpers::parseMeasureUnit
|
||||
}
|
||||
|
||||
// Need to do char <-> char16_t conversion...
|
||||
CharString type;
|
||||
SKELETON_UCHAR_TO_CHAR(type, stemString, 0, firstHyphen, status);
|
||||
CharString subType;
|
||||
SKELETON_UCHAR_TO_CHAR(subType, stemString, firstHyphen + 1, stemString.length(), status);
|
||||
|
||||
- // Note: the largest type as of this writing (Aug 2020) is "volume", which has 33 units.
|
||||
- static constexpr int32_t CAPACITY = 40;
|
||||
+ static constexpr int32_t CAPACITY = 50;
|
||||
MeasureUnit units[CAPACITY];
|
||||
UErrorCode localStatus = U_ZERO_ERROR;
|
||||
int32_t numUnits = MeasureUnit::getAvailable(type.data(), units, CAPACITY, localStatus);
|
||||
if (U_FAILURE(localStatus)) {
|
||||
// More than 30 units in this type?
|
||||
status = U_INTERNAL_PROGRAM_ERROR;
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
diff --git a/source/i18n/coptccal.cpp b/source/i18n/coptccal.cpp
|
||||
--- a/source/i18n/coptccal.cpp
|
||||
+++ b/source/i18n/coptccal.cpp
|
||||
@@ -61,46 +61,43 @@ int32_t
|
||||
CopticCalendar::handleGetExtendedYear(UErrorCode& status)
|
||||
{
|
||||
if (U_FAILURE(status)) {
|
||||
return 0;
|
||||
}
|
||||
if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR) {
|
||||
return internalGet(UCAL_EXTENDED_YEAR, 1); // Default to year 1
|
||||
}
|
||||
- // The year defaults to the epoch start, the era to CE
|
||||
- int32_t era = internalGet(UCAL_ERA, CE);
|
||||
- if (era == BCE) {
|
||||
- return 1 - internalGet(UCAL_YEAR, 1); // Convert to extended year
|
||||
- }
|
||||
- if (era == CE){
|
||||
- return internalGet(UCAL_YEAR, 1); // Default to year 1
|
||||
- }
|
||||
- status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
- return 0;
|
||||
+ // The year defaults to the epoch start
|
||||
+ return internalGet(UCAL_YEAR, 1); // Default to year 1
|
||||
}
|
||||
|
||||
IMPL_SYSTEM_DEFAULT_CENTURY(CopticCalendar, "@calendar=coptic")
|
||||
|
||||
int32_t
|
||||
CopticCalendar::getJDEpochOffset() const
|
||||
{
|
||||
return COPTIC_JD_EPOCH_OFFSET;
|
||||
}
|
||||
|
||||
int32_t CopticCalendar::extendedYearToEra(int32_t extendedYear) const {
|
||||
- return extendedYear <= 0 ? BCE : CE;
|
||||
+ return CE;
|
||||
}
|
||||
|
||||
int32_t CopticCalendar::extendedYearToYear(int32_t extendedYear) const {
|
||||
- return extendedYear <= 0 ? 1 - extendedYear : extendedYear;
|
||||
+ return extendedYear;
|
||||
}
|
||||
|
||||
-bool CopticCalendar::isEra0CountingBackward() const {
|
||||
- return true;
|
||||
+int32_t
|
||||
+CopticCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const
|
||||
+{
|
||||
+ if (field == UCAL_ERA) {
|
||||
+ return 1; // Only one era, era is always 1
|
||||
+ }
|
||||
+ return CECalendar::handleGetLimit(field, limitType);
|
||||
}
|
||||
|
||||
int32_t
|
||||
CopticCalendar::getRelatedYearDifference() const {
|
||||
constexpr int32_t kCopticCalendarRelatedYearDifference = 284;
|
||||
return kCopticCalendarRelatedYearDifference;
|
||||
}
|
||||
|
||||
diff --git a/source/i18n/coptccal.h b/source/i18n/coptccal.h
|
||||
--- a/source/i18n/coptccal.h
|
||||
+++ b/source/i18n/coptccal.h
|
||||
@@ -165,16 +165,22 @@ protected:
|
||||
int32_t getRelatedYearDifference() const override;
|
||||
|
||||
/**
|
||||
* Return the extended year defined by the current fields.
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t handleGetExtendedYear(UErrorCode& status) override;
|
||||
|
||||
+ /**
|
||||
+ * Calculate the limit for a specified type of limit and field
|
||||
+ * @internal
|
||||
+ */
|
||||
+ virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const override;
|
||||
+
|
||||
DECLARE_OVERRIDE_SYSTEM_DEFAULT_CENTURY
|
||||
|
||||
/**
|
||||
* Return the date offset from Julian
|
||||
* @internal
|
||||
*/
|
||||
int32_t getJDEpochOffset() const override;
|
||||
|
||||
@@ -184,21 +190,16 @@ protected:
|
||||
*/
|
||||
int32_t extendedYearToEra(int32_t extendedYear) const override;
|
||||
|
||||
/**
|
||||
* Compute the year from extended year.
|
||||
* @internal
|
||||
*/
|
||||
int32_t extendedYearToYear(int32_t extendedYear) const override;
|
||||
-
|
||||
- /**
|
||||
- * @internal
|
||||
- */
|
||||
- bool isEra0CountingBackward() const override;
|
||||
public:
|
||||
/**
|
||||
* Override Calendar Returns a unique class ID POLYMORPHICALLY. Pure virtual
|
||||
* override. This method is to implement a simple version of RTTI, since not all C++
|
||||
* compilers support genuine RTTI. Polymorphic operator==() and clone() methods call
|
||||
* this method.
|
||||
*
|
||||
* @return The class ID for this object. All objects of a given class have the
|
||||
80
gnu/packages/patches/icu4c-suppress-warnings.patch
Normal file
80
gnu/packages/patches/icu4c-suppress-warnings.patch
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
diff --git a/source/acinclude.m4 b/source/acinclude.m4
|
||||
--- a/source/acinclude.m4
|
||||
+++ b/source/acinclude.m4
|
||||
@@ -459,30 +459,36 @@ AC_DEFUN([AC_CHECK_STRICT_COMPILE],
|
||||
], [ac_use_strict_options=yes])
|
||||
AC_MSG_RESULT($ac_use_strict_options)
|
||||
|
||||
if test "$ac_use_strict_options" = yes
|
||||
then
|
||||
if test "$GCC" = yes
|
||||
then
|
||||
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/source/configure b/source/configure
|
||||
--- a/source/configure
|
||||
+++ b/source/configure
|
||||
@@ -5227,30 +5227,36 @@ fi
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_use_strict_options" >&5
|
||||
printf "%s\n" "$ac_use_strict_options" >&6; }
|
||||
|
||||
if test "$ac_use_strict_options" = yes
|
||||
then
|
||||
if test "$GCC" = yes
|
||||
then
|
||||
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*)
|
||||
Loading…
Add table
Reference in a new issue