From cd6f9b2d790867a86d482cc9a8ac12a0549a8dd2 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Tue, 14 Jan 2020 21:57:38 +0000 Subject: [PATCH] check if host provides fcvt() and ecvt(), use copies from musl libc if not available Signed-off-by: Ivailo Monev --- CMakeLists.txt | 3 ++ src/core/tools/qlocale.cpp | 12 ++++++-- src/core/tools/qlocale_tools.cpp | 65 ++++++++++++++++++++++++++++++++++++++++ src/core/tools/qlocale_tools_p.h | 5 ++++ 4 files changed, 83 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e499e4e50..9356c9fb7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -234,6 +234,9 @@ katie_check_function(strerror_r "string.h") # SUSv2 katie_check_function(localtime_r "time.h") katie_check_function(gmtime_r "time.h") +# SVr2, removed in POSIX.1-2008 +katie_check_function(fcvt "stdlib.h") +katie_check_function(ecvt "stdlib.h") if(KATIE_COMPILER MATCHES "(gcc|clang)") set(QT_VISIBILITY_AVAILABLE TRUE) diff --git a/src/core/tools/qlocale.cpp b/src/core/tools/qlocale.cpp index 99f81fb91..cd8aebb0f 100644 --- a/src/core/tools/qlocale.cpp +++ b/src/core/tools/qlocale.cpp @@ -2254,14 +2254,22 @@ QString QLocalePrivate::doubleToString(const QChar _zero, const QChar plus, cons // NOT thread safe! if (form == DFDecimal) { - digits = QLatin1String(fcvt(d, precision, &decpt, &sign)); +#ifdef QT_HAVE_FCVT + digits = QLatin1String(::fcvt(d, precision, &decpt, &sign)); +#else + digits = QLatin1String(qfcvt(d, precision, &decpt, &sign)); +#endif } else { int pr = precision; if (form == DFExponent) ++pr; else if (form == DFSignificantDigits && pr == 0) pr = 1; - digits = QLatin1String(ecvt(d, pr, &decpt, &sign)); +#ifdef QT_HAVE_ECVT + digits = QLatin1String(::ecvt(d, pr, &decpt, &sign)); +#else + digits = QLatin1String(qecvt(d, pr, &decpt, &sign)); +#endif // Chop trailing zeros if (digits.length() > 0) { diff --git a/src/core/tools/qlocale_tools.cpp b/src/core/tools/qlocale_tools.cpp index 5a19d1eaa..0000b31c5 100644 --- a/src/core/tools/qlocale_tools.cpp +++ b/src/core/tools/qlocale_tools.cpp @@ -359,4 +359,69 @@ bool qt_u_strToLower(const QString &str, QString *out, const QLocale &locale) return true; } + +/* +---------------------------------------------------------------------- +Copyright © 2005-2020 Rich Felker, et al. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +---------------------------------------------------------------------- +*/ +#if !defined(QT_HAVE_FCVT) || !defined(QT_HAVE_ECVT) +char *qfcvt(double x, int n, int *dp, int *sign) +{ + char tmp[1500]; + int i, lz; + + if (n > 1400U) n = 1400; + sprintf(tmp, "%.*f", n, x); + i = (tmp[0] == '-'); + if (tmp[i] == '0') lz = strspn(tmp+i+2, "0"); + else lz = -(int)strcspn(tmp+i, "."); + + if (n<=lz) { + *sign = i; + *dp = 1; + if (n>14U) n = 14; + return (char*)"000000000000000"+14-n; + } + + return qecvt(x, n-lz, dp, sign); +} + +char *qecvt(double x, int n, int *dp, int *sign) +{ + static char buf[16]; + char tmp[32]; + int i, j; + + if (n-1U > 15) n = 15; + sprintf(tmp, "%.*e", n-1, x); + i = *sign = (tmp[0]=='-'); + for (j=0; tmp[i]!='e'; j+=(tmp[i++]!='.')) + buf[j] = tmp[i]; + buf[j] = 0; + *dp = atoi(tmp+i+1)+1; + + return buf; +} +#endif // QT_HAVE_ECVT + QT_END_NAMESPACE diff --git a/src/core/tools/qlocale_tools_p.h b/src/core/tools/qlocale_tools_p.h index 5e0e8823d..f89e97b84 100644 --- a/src/core/tools/qlocale_tools_p.h +++ b/src/core/tools/qlocale_tools_p.h @@ -119,6 +119,11 @@ bool qt_ucol_strcoll(const QChar *source, int sourceLength, const QChar *target, bool qt_u_strToUpper(const QString &str, QString *out, const QLocale &locale); bool qt_u_strToLower(const QString &str, QString *out, const QLocale &locale); +#if !defined(QT_HAVE_FCVT) || !defined(QT_HAVE_ECVT) +char *qfcvt(double x, int n, int *dp, int *sign); +char *qecvt(double x, int n, int *dp, int *sign); +#endif // QT_HAVE_ECVT + QT_END_NAMESPACE #endif -- 2.11.0