EXTRAS_TRUE
U_HAVE_WCSCPY
U_HAVE_WCHAR_H
+U_HAVE_STRTOD_L
U_TIMEZONE
U_HAVE_TIMEZONE
U_TZNAME
docdir
oldincludedir
includedir
+runstatedir
localstatedir
sharedstatedir
sysconfdir
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
+ -runstatedir | --runstatedir | --runstatedi | --runstated \
+ | --runstate | --runstat | --runsta | --runst | --runs \
+ | --run | --ru | --r)
+ ac_prev=runstatedir ;;
+ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+ | --run=* | --ru=* | --r=*)
+ runstatedir=$ac_optarg ;;
+
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir
+ libdir localedir mandir runstatedir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
+ac_fn_c_check_func "$LINENO" "strtod_l" "ac_cv_func_strtod_l"
+if test "x$ac_cv_func_strtod_l" = xyes; then :
+
+fi
+
+if test x$ac_cv_func_strtod_l = xyes
+then
+ U_HAVE_STRTOD_L=1
+else
+ CONFIG_CPPFLAGS="${CONFIG_CPPFLAGS} -DU_HAVE_STRTOD_L=0"
+ U_HAVE_STRTOD_L=0
+fi
+
+
# Checks for typedefs
ac_fn_c_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "$ac_includes_default"
if test "x$ac_cv_type_int8_t" = xyes; then :
#include "putilimp.h"
#include "uassert.h"
#include "digitinterval.h"
+#include "ucln_in.h"
+#include "umutex.h"
#include <stdlib.h>
#include <limits.h>
#include <string.h>
internalClear();
}
-char DigitList::getStrtodDecimalSeparator() {
- // TODO: maybe use andy's pthread once.
- static char gDecimal = 0;
- char result;
- {
- Mutex mutex;
- result = gDecimal;;
- if (result == 0) {
- // We need to know the decimal separator character that will be used with strtod().
- // Depends on the C runtime global locale.
- // Most commonly is '.'
- // TODO: caching could fail if the global locale is changed on the fly.
- char rep[MAX_DIGITS];
- sprintf(rep, "%+1.1f", 1.0);
- result = rep[2];
- gDecimal = result;;
- }
- }
- return result;
-}
-
// -------------------------------------
/**
double
DigitList::getDouble() const
{
- static char gDecimal = 0;
- char decimalSeparator;
{
Mutex mutex;
if (fHave == kDouble) {
return fUnion.fDouble;
}
- decimalSeparator = gDecimal;
- }
-
- if (decimalSeparator == 0) {
- // We need to know the decimal separator character that will be used with strtod().
- // Depends on the C runtime global locale.
- // Most commonly is '.'
- // TODO: caching could fail if the global locale is changed on the fly.
- char rep[MAX_DIGITS];
- sprintf(rep, "%+1.1f", 1.0);
- decimalSeparator = rep[2];
}
double tDouble = 0.0;
uprv_decNumberToString(this->fDecNumber, s.getAlias());
}
U_ASSERT(uprv_strlen(&s[0]) < MAX_DBL_DIGITS+18);
-
- if (decimalSeparator != '.') {
- char *decimalPt = strchr(s.getAlias(), '.');
- if (decimalPt != NULL) {
- *decimalPt = decimalSeparator;
- }
- }
+
char *end = NULL;
- tDouble = uprv_strtod(s.getAlias(), &end);
+ tDouble = decimalStrToDouble(s.getAlias(), &end);
}
{
Mutex mutex;
DigitList *nonConstThis = const_cast<DigitList *>(this);
nonConstThis->internalSetDouble(tDouble);
- gDecimal = decimalSeparator;
}
return tDouble;
}
+#if !defined(U_HAVE_STRTOD_L)
+# if U_PLATFORM_IS_DARWIN_BASED || U_PLATFORM_IS_LINUX_BASED || U_PLATFORM == U_PF_BSD || U_PLATFORM_HAS_WIN32_API
+# define U_HAVE_STRTOD_L 1
+# else
+# define U_HAVE_STRTOD_L 0
+# endif
+#endif
+
+#if U_HAVE_STRTOD_L && U_PLATFORM_HAS_WIN32_API
+#define locale_t _locale_t
+#define newlocale(cat, loc, base) _create_locale(cat, loc)
+#define freelocale _free_locale
+#define strtod_l _strtod_l
+#endif
+
+#if U_HAVE_STRTOD_L
+static locale_t gCLocale = (locale_t)0;
+#endif
+static icu::UInitOnce gCLocaleInitOnce = U_INITONCE_INITIALIZER;
+
+U_CDECL_BEGIN
+// Cleanup callback func
+static UBool U_CALLCONV digitList_cleanup(void)
+{
+#if U_HAVE_STRTOD_L
+ if (gCLocale != (locale_t)0) {
+ freelocale(gCLocale);
+ }
+#endif
+ return TRUE;
+}
+// C Locale initialization func
+static void U_CALLCONV initCLocale(void) {
+ ucln_i18n_registerCleanup(UCLN_I18N_DIGITLIST, digitList_cleanup);
+#if U_HAVE_STRTOD_L
+ gCLocale = newlocale(LC_ALL, "C", (locale_t)0);
+#endif
+}
+U_CDECL_END
+
+double
+DigitList::decimalStrToDouble(char *decstr, char **end) {
+ umtx_initOnce(gCLocaleInitOnce, &initCLocale);
+#if U_HAVE_STRTOD_L
+ return strtod_l(decstr, end, gCLocale);
+#else
+ char *decimalPt = strchr(decstr, '.');
+ if (decimalPt) {
+ // We need to know the decimal separator character that will be used with strtod().
+ // Depends on the C runtime global locale.
+ // Most commonly is '.'
+ char rep[MAX_DIGITS];
+ sprintf(rep, "%+1.1f", 1.0);
+ *decimalPt = rep[2];
+ }
+ return uprv_strtod(decstr, end);
+#endif
+}
+
// -------------------------------------
/**