mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 09:30:24 +00:00
Ports: Add port for libicu
I was trying to port openttd which I ultimately gave up on because too much of the C++ standard library's functionality is missing at this point. The libicu library was a dependency for that. In its current state the libicu port is not thread-safe because of missing functionality in the C++ standard library (mainly std::mutex, std::condition_variable, etc.).
This commit is contained in:
parent
28b3c8bc1d
commit
6a808d96b5
Notes:
sideshowbarker
2024-07-18 20:21:50 +09:00
Author: https://github.com/gunnarbeutner Commit: https://github.com/SerenityOS/serenity/commit/6a808d96b5e Pull-request: https://github.com/SerenityOS/serenity/pull/6253
3 changed files with 567 additions and 0 deletions
|
@ -49,6 +49,7 @@ Please make sure to keep this list up to date when adding and updating ports. :^
|
|||
| [`libgcrypt`](libgcrypt/) | libgcrypt | 1.9.2 | https://gnupg.org/software/libgcrypt/index.html |
|
||||
| [`libgpg-error`](libgpg-error/)| libgpg-error | 1.42 | https://gnupg.org/software/libgpg-error/index.html |
|
||||
| [`libiconv`](libiconv/) | GNU libiconv | 1.16 | https://www.gnu.org/software/libiconv/ |
|
||||
| [`libicu`](libicu/) | ICU | 69.1 | http://site.icu-project.org/ |
|
||||
| [`libksba`](libksba/) | libksba | 1.5.1 | https://gnupg.org/software/libksba/index.html |
|
||||
| [`libjpeg`](libjpeg/) | libjpeg | 9d | https://ijg.org/ |
|
||||
| [`libogg`](libogg/) | libogg | 1.3.4 | https://github.com/xiph/ogg |
|
||||
|
|
18
Ports/libicu/package.sh
Executable file
18
Ports/libicu/package.sh
Executable file
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env -S bash ../.port_include.sh
|
||||
port=libicu
|
||||
version=69_1
|
||||
useconfigure=true
|
||||
workdir=icu/source
|
||||
configopts=--with-cross-build=$(pwd)/${workdir}/../host-build
|
||||
files="https://github.com/unicode-org/icu/releases/download/release-${version//_/-}/icu4c-${version}-src.tgz icu4c-${version}-src.tgz"
|
||||
|
||||
configure() {
|
||||
host_env
|
||||
run mkdir -p ../host-build
|
||||
run sh -c "cd ../host-build && ../source/configure && make $makeopts"
|
||||
target_env
|
||||
run ./configure --host="${SERENITY_ARCH}-pc-serenity" $configopts
|
||||
}
|
||||
|
||||
export CFLAGS="-DU_HAVE_NL_LANGINFO_CODESET=0 -DLC_MESSAGES=1"
|
||||
export CXXFLAGS="-DU_HAVE_NL_LANGINFO_CODESET=0 -DLC_MESSAGES=1"
|
548
Ports/libicu/patches/icu.patch
Normal file
548
Ports/libicu/patches/icu.patch
Normal file
|
@ -0,0 +1,548 @@
|
|||
diff -ur source/config/mh-serenity source.serenity/config/mh-serenity
|
||||
--- source/config/mh-serenity 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ source.serenity/config/mh-serenity 2021-04-11 09:20:23.857575570 +0200
|
||||
@@ -0,0 +1,87 @@
|
||||
+## -*-makefile-*-
|
||||
+## Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
+## License & terms of use: http://www.unicode.org/copyright.html
|
||||
+## Linux-specific setup
|
||||
+## Copyright (c) 1999-2013, International Business Machines Corporation and
|
||||
+## others. All Rights Reserved.
|
||||
+
|
||||
+## Commands to generate dependency files
|
||||
+GEN_DEPS.c= $(CC) -E -MM $(DEFS) $(CPPFLAGS)
|
||||
+GEN_DEPS.cc= $(CXX) -E -MM $(DEFS) $(CPPFLAGS) $(CXXFLAGS)
|
||||
+
|
||||
+## Flags for position independent code
|
||||
+SHAREDLIBCFLAGS = -fPIC
|
||||
+SHAREDLIBCXXFLAGS = -fPIC
|
||||
+SHAREDLIBCPPFLAGS = -DPIC
|
||||
+
|
||||
+## Additional flags when building libraries and with threads
|
||||
+THREADSCPPFLAGS = -D_REENTRANT
|
||||
+LIBCPPFLAGS =
|
||||
+
|
||||
+## Compiler switch to embed a runtime search path
|
||||
+LD_RPATH= -Wl,-zorigin,-rpath,'$$'ORIGIN
|
||||
+LD_RPATH_PRE = -Wl,-rpath,
|
||||
+
|
||||
+## These are the library specific LDFLAGS
|
||||
+LDFLAGSICUDT=-nodefaultlibs -nostdlib
|
||||
+
|
||||
+## Compiler switch to embed a library name
|
||||
+# The initial tab in the next line is to prevent icu-config from reading it.
|
||||
+ LD_SONAME = -Wl,-soname -Wl,$(notdir $(MIDDLE_SO_TARGET))
|
||||
+#SH# # We can't depend on MIDDLE_SO_TARGET being set.
|
||||
+#SH# LD_SONAME=
|
||||
+
|
||||
+## Shared library options
|
||||
+LD_SOOPTIONS= -Wl,-Bsymbolic
|
||||
+
|
||||
+## Shared object suffix
|
||||
+SO = so
|
||||
+## Non-shared intermediate object suffix
|
||||
+STATIC_O = ao
|
||||
+
|
||||
+## Compilation rules
|
||||
+%.$(STATIC_O): $(srcdir)/%.c
|
||||
+ $(call SILENT_COMPILE,$(strip $(COMPILE.c) $(STATICCPPFLAGS) $(STATICCFLAGS)) -o $@ $<)
|
||||
+%.o: $(srcdir)/%.c
|
||||
+ $(call SILENT_COMPILE,$(strip $(COMPILE.c) $(DYNAMICCPPFLAGS) $(DYNAMICCFLAGS)) -o $@ $<)
|
||||
+
|
||||
+%.$(STATIC_O): $(srcdir)/%.cpp
|
||||
+ $(call SILENT_COMPILE,$(strip $(COMPILE.cc) $(STATICCPPFLAGS) $(STATICCXXFLAGS)) -o $@ $<)
|
||||
+%.o: $(srcdir)/%.cpp
|
||||
+ $(call SILENT_COMPILE,$(strip $(COMPILE.cc) $(DYNAMICCPPFLAGS) $(DYNAMICCXXFLAGS)) -o $@ $<)
|
||||
+
|
||||
+
|
||||
+## Dependency rules
|
||||
+%.d: $(srcdir)/%.c
|
||||
+ $(call ICU_MSG,(deps)) $<
|
||||
+ @$(SHELL) -ec '$(GEN_DEPS.c) $< \
|
||||
+ | sed '\''s%\($*\)\.o[ :]*%\1.o $@ : %g'\'' > $@; \
|
||||
+ [ -s $@ ] || rm -f $@'
|
||||
+
|
||||
+%.d: $(srcdir)/%.cpp
|
||||
+ $(call ICU_MSG,(deps)) $<
|
||||
+ @$(SHELL) -ec '$(GEN_DEPS.cc) $< \
|
||||
+ | sed '\''s%\($*\)\.o[ :]*%\1.o $@ : %g'\'' > $@; \
|
||||
+ [ -s $@ ] || rm -f $@'
|
||||
+
|
||||
+## Versioned libraries rules
|
||||
+
|
||||
+%.$(SO).$(SO_TARGET_VERSION_MAJOR): %.$(SO).$(SO_TARGET_VERSION)
|
||||
+ $(RM) $@ && ln -s ${<F} $@
|
||||
+%.$(SO): %.$(SO).$(SO_TARGET_VERSION_MAJOR)
|
||||
+ $(RM) $@ && ln -s ${*F}.$(SO).$(SO_TARGET_VERSION) $@
|
||||
+
|
||||
+## Bind internal references
|
||||
+
|
||||
+# LDflags that pkgdata will use
|
||||
+BIR_LDFLAGS= -Wl,-Bsymbolic
|
||||
+
|
||||
+# Dependencies [i.e. map files] for the final library
|
||||
+BIR_DEPS=
|
||||
+
|
||||
+## Remove shared library 's'
|
||||
+STATIC_PREFIX_WHEN_USED =
|
||||
+STATIC_PREFIX =
|
||||
+
|
||||
+## End Linux-specific setup
|
||||
+
|
||||
diff -ur source/common/umutex.cpp source.serenity/common/umutex.cpp
|
||||
--- source/common/umutex.cpp 2021-04-08 02:10:27.000000000 +0200
|
||||
+++ source.serenity/common/umutex.cpp 2021-04-11 09:45:50.785341646 +0200
|
||||
@@ -44,40 +44,56 @@
|
||||
*************************************************************************************************/
|
||||
|
||||
namespace {
|
||||
+#ifndef __serenity__
|
||||
std::mutex *initMutex;
|
||||
std::condition_variable *initCondition;
|
||||
+#endif
|
||||
|
||||
// The ICU global mutex.
|
||||
// Used when ICU implementation code passes nullptr for the mutex pointer.
|
||||
UMutex globalMutex;
|
||||
|
||||
+#ifndef __serenity__
|
||||
std::once_flag initFlag;
|
||||
std::once_flag *pInitFlag = &initFlag;
|
||||
+#endif
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
U_CDECL_BEGIN
|
||||
static UBool U_CALLCONV umtx_cleanup() {
|
||||
+#ifndef __serenity__
|
||||
initMutex->~mutex();
|
||||
initCondition->~condition_variable();
|
||||
+#endif
|
||||
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().
|
||||
+#ifndef __serenity__
|
||||
pInitFlag->~once_flag();
|
||||
pInitFlag = new(&initFlag) std::once_flag();
|
||||
+#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
static void U_CALLCONV umtx_init() {
|
||||
+#ifndef __serenity__
|
||||
initMutex = STATIC_NEW(std::mutex);
|
||||
initCondition = STATIC_NEW(std::condition_variable);
|
||||
+#endif
|
||||
ucln_common_registerCleanup(UCLN_COMMON_MUTEX, umtx_cleanup);
|
||||
}
|
||||
U_CDECL_END
|
||||
|
||||
|
||||
-std::mutex *UMutex::getMutex() {
|
||||
+#ifndef __serenity__
|
||||
+std::mutex
|
||||
+#else
|
||||
+void
|
||||
+#endif
|
||||
+*UMutex::getMutex() {
|
||||
+#ifndef __serenity__
|
||||
std::mutex *retPtr = fMutex.load(std::memory_order_acquire);
|
||||
if (retPtr == nullptr) {
|
||||
std::call_once(*pInitFlag, umtx_init);
|
||||
@@ -92,6 +108,9 @@
|
||||
}
|
||||
U_ASSERT(retPtr != nullptr);
|
||||
return retPtr;
|
||||
+#else
|
||||
+ return this;
|
||||
+#endif
|
||||
}
|
||||
|
||||
UMutex *UMutex::gListHead = nullptr;
|
||||
@@ -99,8 +118,10 @@
|
||||
void UMutex::cleanup() {
|
||||
UMutex *next = nullptr;
|
||||
for (UMutex *m = gListHead; m != nullptr; m = next) {
|
||||
+#ifndef __serenity__
|
||||
(*m->fMutex).~mutex();
|
||||
m->fMutex = nullptr;
|
||||
+#endif
|
||||
next = m->fListLink;
|
||||
m->fListLink = nullptr;
|
||||
}
|
||||
@@ -143,8 +164,12 @@
|
||||
//
|
||||
U_COMMON_API UBool U_EXPORT2
|
||||
umtx_initImplPreInit(UInitOnce &uio) {
|
||||
+#ifndef __serenity__
|
||||
std::call_once(*pInitFlag, umtx_init);
|
||||
std::unique_lock<std::mutex> lock(*initMutex);
|
||||
+#else
|
||||
+ umtx_init();
|
||||
+#endif
|
||||
if (umtx_loadAcquire(uio.fState) == 0) {
|
||||
umtx_storeRelease(uio.fState, 1);
|
||||
return true; // Caller will next call the init function.
|
||||
@@ -152,7 +177,9 @@
|
||||
while (umtx_loadAcquire(uio.fState) == 1) {
|
||||
// Another thread is currently running the initialization.
|
||||
// Wait until it completes.
|
||||
+#ifndef __serenity__
|
||||
initCondition->wait(lock);
|
||||
+#endif
|
||||
}
|
||||
U_ASSERT(uio.fState == 2);
|
||||
return false;
|
||||
@@ -169,10 +196,14 @@
|
||||
U_COMMON_API void U_EXPORT2
|
||||
umtx_initImplPostInit(UInitOnce &uio) {
|
||||
{
|
||||
+#ifndef __serenity__
|
||||
std::unique_lock<std::mutex> lock(*initMutex);
|
||||
+#endif
|
||||
umtx_storeRelease(uio.fState, 2);
|
||||
}
|
||||
+#ifndef __serenity__
|
||||
initCondition->notify_all();
|
||||
+#endif
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
diff -ur source/common/umutex.h source.serenity/common/umutex.h
|
||||
--- source/common/umutex.h 2021-04-08 02:10:27.000000000 +0200
|
||||
+++ source.serenity/common/umutex.h 2021-04-11 09:33:17.301246150 +0200
|
||||
@@ -231,17 +231,25 @@
|
||||
|
||||
// requirements for C++ BasicLockable, allows UMutex to work with std::lock_guard
|
||||
void lock() {
|
||||
+#ifndef __serenity__
|
||||
std::mutex *m = fMutex.load(std::memory_order_acquire);
|
||||
if (m == nullptr) { m = getMutex(); }
|
||||
m->lock();
|
||||
+#endif
|
||||
+ }
|
||||
+ void unlock() {
|
||||
+#ifndef __serenity__
|
||||
+ fMutex.load(std::memory_order_relaxed)->unlock();
|
||||
+#endif
|
||||
}
|
||||
- void unlock() { fMutex.load(std::memory_order_relaxed)->unlock(); }
|
||||
|
||||
static void cleanup();
|
||||
|
||||
private:
|
||||
+#ifndef __serenity__
|
||||
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 +261,12 @@
|
||||
* Initial fast check is inline, in lock(). The returned value may never
|
||||
* be nullptr.
|
||||
*/
|
||||
- std::mutex *getMutex();
|
||||
+#ifndef __serenity__
|
||||
+ std::mutex
|
||||
+#else
|
||||
+ void
|
||||
+#endif
|
||||
+ *getMutex();
|
||||
};
|
||||
|
||||
|
||||
diff -ur source/common/unifiedcache.cpp source.serenity/common/unifiedcache.cpp
|
||||
--- source/common/unifiedcache.cpp 2021-04-08 02:10:27.000000000 +0200
|
||||
+++ source.serenity/common/unifiedcache.cpp 2021-04-11 09:44:51.810895675 +0200
|
||||
@@ -13,16 +13,20 @@
|
||||
#include "unifiedcache.h"
|
||||
|
||||
#include <algorithm> // For std::max()
|
||||
+#ifndef __serenity__
|
||||
#include <mutex>
|
||||
+#endif
|
||||
|
||||
#include "uassert.h"
|
||||
#include "uhash.h"
|
||||
#include "ucln_cmn.h"
|
||||
|
||||
static icu::UnifiedCache *gCache = NULL;
|
||||
+#ifndef __serenity__
|
||||
static std::mutex *gCacheMutex = nullptr;
|
||||
static std::condition_variable *gInProgressValueAddedCond;
|
||||
static icu::UInitOnce gCacheInitOnce = U_INITONCE_INITIALIZER;
|
||||
+#endif
|
||||
|
||||
static const int32_t MAX_EVICT_ITERATIONS = 10;
|
||||
static const int32_t DEFAULT_MAX_UNUSED = 1000;
|
||||
@@ -31,13 +35,17 @@
|
||||
|
||||
U_CDECL_BEGIN
|
||||
static UBool U_CALLCONV unifiedcache_cleanup() {
|
||||
+#ifndef __serenity__
|
||||
gCacheInitOnce.reset();
|
||||
+#endif
|
||||
delete gCache;
|
||||
gCache = nullptr;
|
||||
+#ifndef __serenity__
|
||||
gCacheMutex->~mutex();
|
||||
gCacheMutex = nullptr;
|
||||
gInProgressValueAddedCond->~condition_variable();
|
||||
gInProgressValueAddedCond = nullptr;
|
||||
+#endif
|
||||
return TRUE;
|
||||
}
|
||||
U_CDECL_END
|
||||
@@ -72,8 +80,10 @@
|
||||
ucln_common_registerCleanup(
|
||||
UCLN_COMMON_UNIFIED_CACHE, unifiedcache_cleanup);
|
||||
|
||||
+#ifndef __serenity__
|
||||
gCacheMutex = STATIC_NEW(std::mutex);
|
||||
gInProgressValueAddedCond = STATIC_NEW(std::condition_variable);
|
||||
+#endif
|
||||
gCache = new UnifiedCache(status);
|
||||
if (gCache == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
@@ -86,7 +96,11 @@
|
||||
}
|
||||
|
||||
UnifiedCache *UnifiedCache::getInstance(UErrorCode &status) {
|
||||
+#ifndef __serenity__
|
||||
umtx_initOnce(gCacheInitOnce, &cacheInit, status);
|
||||
+#else
|
||||
+ cacheInit(status);
|
||||
+#endif
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -135,28 +149,38 @@
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
+#ifndef __serenity__
|
||||
std::lock_guard<std::mutex> lock(*gCacheMutex);
|
||||
+#endif
|
||||
fMaxUnused = count;
|
||||
fMaxPercentageOfInUse = percentageOfInUseItems;
|
||||
}
|
||||
|
||||
int32_t UnifiedCache::unusedCount() const {
|
||||
+#ifndef __serenity__
|
||||
std::lock_guard<std::mutex> lock(*gCacheMutex);
|
||||
+#endif
|
||||
return uhash_count(fHashtable) - fNumValuesInUse;
|
||||
}
|
||||
|
||||
int64_t UnifiedCache::autoEvictedCount() const {
|
||||
+#ifndef __serenity__
|
||||
std::lock_guard<std::mutex> lock(*gCacheMutex);
|
||||
+#endif
|
||||
return fAutoEvictedCount;
|
||||
}
|
||||
|
||||
int32_t UnifiedCache::keyCount() const {
|
||||
+#ifndef __serenity__
|
||||
std::lock_guard<std::mutex> lock(*gCacheMutex);
|
||||
+#endif
|
||||
return uhash_count(fHashtable);
|
||||
}
|
||||
|
||||
void UnifiedCache::flush() const {
|
||||
+#ifndef __serenity__
|
||||
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
|
||||
@@ -165,7 +189,9 @@
|
||||
}
|
||||
|
||||
void UnifiedCache::handleUnreferencedObject() const {
|
||||
+#ifndef __serenity__
|
||||
std::lock_guard<std::mutex> lock(*gCacheMutex);
|
||||
+#endif
|
||||
--fNumValuesInUse;
|
||||
_runEvictionSlice();
|
||||
}
|
||||
@@ -184,7 +210,9 @@
|
||||
}
|
||||
|
||||
void UnifiedCache::dumpContents() const {
|
||||
+#ifndef __serenity__
|
||||
std::lock_guard<std::mutex> lock(*gCacheMutex);
|
||||
+#endif
|
||||
_dumpContents();
|
||||
}
|
||||
|
||||
@@ -224,7 +252,9 @@
|
||||
// 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 __serenity__
|
||||
std::lock_guard<std::mutex> lock(*gCacheMutex);
|
||||
+#endif
|
||||
_flush(TRUE);
|
||||
}
|
||||
uhash_close(fHashtable);
|
||||
@@ -325,7 +355,9 @@
|
||||
const CacheKeyBase &key,
|
||||
const SharedObject *&value,
|
||||
UErrorCode &status) const {
|
||||
+#ifndef __serenity__
|
||||
std::lock_guard<std::mutex> lock(*gCacheMutex);
|
||||
+#endif
|
||||
const UHashElement *element = uhash_find(fHashtable, &key);
|
||||
if (element != NULL && !_inProgress(element)) {
|
||||
_fetch(element, value, status);
|
||||
@@ -350,14 +382,18 @@
|
||||
UErrorCode &status) const {
|
||||
U_ASSERT(value == NULL);
|
||||
U_ASSERT(status == U_ZERO_ERROR);
|
||||
+#ifndef __serenity__
|
||||
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 __serenity__
|
||||
gInProgressValueAddedCond->wait(lock);
|
||||
+#endif
|
||||
element = uhash_find(fHashtable, &key);
|
||||
}
|
||||
|
||||
@@ -430,7 +466,9 @@
|
||||
|
||||
// Tell waiting threads that we replace in-progress status with
|
||||
// an error.
|
||||
+#ifndef __serenity__
|
||||
gInProgressValueAddedCond->notify_all();
|
||||
+#endif
|
||||
}
|
||||
|
||||
void UnifiedCache::_fetch(
|
||||
diff -ur source/config.sub source.serenity/config.sub
|
||||
--- source/config.sub 2021-04-08 02:10:27.000000000 +0200
|
||||
+++ source.serenity/config.sub 2021-04-11 07:59:52.531086431 +0200
|
||||
@@ -1416,7 +1416,7 @@
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
|
||||
- | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*)
|
||||
+ | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -serenity*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
diff -ur source/configure source.serenity/configure
|
||||
--- source/configure 2021-04-08 02:10:27.000000000 +0200
|
||||
+++ source.serenity/configure 2021-04-11 09:24:04.971314734 +0200
|
||||
@@ -5274,6 +5274,8 @@
|
||||
else
|
||||
icu_cv_host_frag=mh-cygwin-msvc
|
||||
fi ;;
|
||||
+*-serenity*)
|
||||
+ icu_cv_host_frag=mh-serenity ;;
|
||||
*-*-mingw*)
|
||||
if test "$GCC" = yes; then
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
diff -ur source/i18n/decimfmt.cpp source.serenity/i18n/decimfmt.cpp
|
||||
--- source/i18n/decimfmt.cpp 2021-04-08 02:10:27.000000000 +0200
|
||||
+++ source.serenity/i18n/decimfmt.cpp 2021-04-11 09:58:25.946465400 +0200
|
||||
@@ -1827,13 +1827,21 @@
|
||||
if (!fields->canUseFastFormat) {
|
||||
return false;
|
||||
}
|
||||
+#ifndef __serenity__
|
||||
if (std::isnan(input)
|
||||
+#else
|
||||
+ if (isnan(input)
|
||||
+#endif
|
||||
|| uprv_trunc(input) != input
|
||||
|| input <= INT32_MIN
|
||||
|| input > INT32_MAX) {
|
||||
return false;
|
||||
}
|
||||
+#ifndef __serenity__
|
||||
doFastFormatInt32(static_cast<int32_t>(input), std::signbit(input), output);
|
||||
+#else
|
||||
+ doFastFormatInt32(static_cast<int32_t>(input), signbit(input), output);
|
||||
+#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
diff -ur source/i18n/number_decimalquantity.cpp source.serenity/i18n/number_decimalquantity.cpp
|
||||
--- source/i18n/number_decimalquantity.cpp 2021-04-08 02:10:27.000000000 +0200
|
||||
+++ source.serenity/i18n/number_decimalquantity.cpp 2021-04-11 10:00:59.729454484 +0200
|
||||
@@ -419,13 +419,25 @@
|
||||
setBcdToZero();
|
||||
flags = 0;
|
||||
// signbit() from <math.h> handles +0.0 vs -0.0
|
||||
+#ifndef __serenity__
|
||||
if (std::signbit(n)) {
|
||||
+#else
|
||||
+ if (signbit(n)) {
|
||||
+#endif
|
||||
flags |= NEGATIVE_FLAG;
|
||||
n = -n;
|
||||
}
|
||||
+#ifndef __serenity__
|
||||
if (std::isnan(n) != 0) {
|
||||
+#else
|
||||
+ if (isnan(n) != 0) {
|
||||
+#endif
|
||||
flags |= NAN_FLAG;
|
||||
+#ifndef __serenity__
|
||||
} else if (std::isfinite(n) == 0) {
|
||||
+#else
|
||||
+ } else if (isfinite(n) == 0) {
|
||||
+#endif
|
||||
flags |= INFINITY_FLAG;
|
||||
} else if (n != 0) {
|
||||
_setToDoubleFast(n);
|
||||
diff -ur source/i18n/number_utils.cpp source.serenity/i18n/number_utils.cpp
|
||||
--- source/i18n/number_utils.cpp 2021-04-08 02:10:27.000000000 +0200
|
||||
+++ source.serenity/i18n/number_utils.cpp 2021-04-11 09:59:55.181535153 +0200
|
||||
@@ -130,7 +130,11 @@
|
||||
|
||||
void DecNum::setTo(double d, UErrorCode& status) {
|
||||
// Need to check for NaN and Infinity before going into DoubleToStringConverter
|
||||
+#ifndef __serenity__
|
||||
if (std::isnan(d) != 0 || std::isfinite(d) == 0) {
|
||||
+#else
|
||||
+ if (isnan(d) != 0 || isfinite(d) == 0) {
|
||||
+#endif
|
||||
status = U_UNSUPPORTED_ERROR;
|
||||
return;
|
||||
}
|
||||
@@ -157,7 +161,11 @@
|
||||
|
||||
// Set exponent and bitmask. Note that DoubleToStringConverter does not do negatives.
|
||||
fData.getAlias()->exponent += point - length;
|
||||
+#ifndef __serenity__
|
||||
fData.getAlias()->bits |= static_cast<uint8_t>(std::signbit(d) ? DECNEG : 0);
|
||||
+#else
|
||||
+ fData.getAlias()->bits |= static_cast<uint8_t>(signbit(d) ? DECNEG : 0);
|
||||
+#endif
|
||||
}
|
||||
|
||||
void DecNum::_setTo(const char* str, int32_t maxDigits, UErrorCode& status) {
|
||||
diff -ur source/i18n/reldatefmt.cpp source.serenity/i18n/reldatefmt.cpp
|
||||
--- source/i18n/reldatefmt.cpp 2021-04-08 02:10:27.000000000 +0200
|
||||
+++ source.serenity/i18n/reldatefmt.cpp 2021-04-11 09:55:40.409893218 +0200
|
||||
@@ -1008,7 +1008,11 @@
|
||||
return;
|
||||
}
|
||||
UDateDirection direction = UDAT_DIRECTION_NEXT;
|
||||
+#ifndef __serenity__
|
||||
if (std::signbit(offset)) { // needed to handle -0.0
|
||||
+#else
|
||||
+ if (signbit(offset)) {
|
||||
+#endif
|
||||
direction = UDAT_DIRECTION_LAST;
|
||||
offset = -offset;
|
||||
}
|
Loading…
Reference in a new issue