diff --git a/libc/Android.mk b/libc/Android.mk index e4e58b77a..07a0735ef 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -142,6 +142,7 @@ libc_bionic_src_files := \ bionic/libc_logging.cpp \ bionic/libgen.cpp \ bionic/link.cpp \ + bionic/locale.cpp \ bionic/lstat.cpp \ bionic/mkdir.cpp \ bionic/mkfifo.cpp \ @@ -187,7 +188,6 @@ libc_bionic_src_files := \ bionic/setegid.cpp \ bionic/__set_errno.cpp \ bionic/seteuid.cpp \ - bionic/setlocale.cpp \ bionic/setpgrp.cpp \ bionic/sigaction.cpp \ bionic/sigaddset.cpp \ diff --git a/libc/arch-arm64/arm64.mk b/libc/arch-arm64/arm64.mk index 7b6b1c3c8..88da1f354 100644 --- a/libc/arch-arm64/arm64.mk +++ b/libc/arch-arm64/arm64.mk @@ -14,11 +14,6 @@ libc_common_src_files_arm64 := \ upstream-freebsd/lib/libc/string/wcslen.c \ upstream-freebsd/lib/libc/string/wcsrchr.c \ upstream-freebsd/lib/libc/string/wmemcmp.c \ - upstream-openbsd/lib/libc/locale/_def_numeric.c \ - upstream-openbsd/lib/libc/locale/_def_messages.c \ - upstream-openbsd/lib/libc/locale/_def_monetary.c \ - upstream-openbsd/lib/libc/locale/_def_time.c \ - upstream-openbsd/lib/libc/locale/localeconv.c \ upstream-openbsd/lib/libc/string/bcopy.c \ upstream-openbsd/lib/libc/string/strcat.c \ upstream-openbsd/lib/libc/string/strcpy.c \ diff --git a/libc/arch-mips64/mips64.mk b/libc/arch-mips64/mips64.mk index 9b29f0d01..28806e183 100644 --- a/libc/arch-mips64/mips64.mk +++ b/libc/arch-mips64/mips64.mk @@ -16,11 +16,6 @@ libc_common_src_files_mips64 := \ upstream-freebsd/lib/libc/string/wcslen.c \ upstream-freebsd/lib/libc/string/wcsrchr.c \ upstream-freebsd/lib/libc/string/wmemcmp.c \ - upstream-openbsd/lib/libc/locale/_def_numeric.c \ - upstream-openbsd/lib/libc/locale/_def_messages.c \ - upstream-openbsd/lib/libc/locale/_def_monetary.c \ - upstream-openbsd/lib/libc/locale/_def_time.c \ - upstream-openbsd/lib/libc/locale/localeconv.c \ upstream-openbsd/lib/libc/string/bcopy.c \ upstream-openbsd/lib/libc/string/strcat.c \ upstream-openbsd/lib/libc/string/strcmp.c \ diff --git a/libc/arch-x86_64/x86_64.mk b/libc/arch-x86_64/x86_64.mk index a3adaa4a2..9bce065b3 100644 --- a/libc/arch-x86_64/x86_64.mk +++ b/libc/arch-x86_64/x86_64.mk @@ -18,11 +18,6 @@ libc_common_src_files_x86_64 := \ upstream-freebsd/lib/libc/string/wcslen.c \ upstream-freebsd/lib/libc/string/wcsrchr.c \ upstream-freebsd/lib/libc/string/wmemcmp.c \ - upstream-openbsd/lib/libc/locale/_def_numeric.c \ - upstream-openbsd/lib/libc/locale/_def_messages.c \ - upstream-openbsd/lib/libc/locale/_def_monetary.c \ - upstream-openbsd/lib/libc/locale/_def_time.c \ - upstream-openbsd/lib/libc/locale/localeconv.c \ upstream-openbsd/lib/libc/string/bcopy.c \ upstream-openbsd/lib/libc/string/strcat.c \ upstream-openbsd/lib/libc/string/strcmp.c \ diff --git a/libc/bionic/setlocale.cpp b/libc/bionic/locale.cpp similarity index 56% rename from libc/bionic/setlocale.cpp rename to libc/bionic/locale.cpp index e8fdc9e89..e20a1de65 100644 --- a/libc/bionic/setlocale.cpp +++ b/libc/bionic/locale.cpp @@ -27,9 +27,48 @@ */ #include +#include #include +static pthread_once_t locale_once = PTHREAD_ONCE_INIT; +static lconv locale; + +static void __locale_init() { + locale.decimal_point = const_cast("."); + + char* not_available = const_cast(""); + locale.thousands_sep = not_available; + locale.grouping = not_available; + locale.int_curr_symbol = not_available; + locale.currency_symbol = not_available; + locale.mon_decimal_point = not_available; + locale.mon_thousands_sep = not_available; + locale.mon_grouping = not_available; + locale.positive_sign = not_available; + locale.negative_sign = not_available; + + locale.int_frac_digits = CHAR_MAX; + locale.frac_digits = CHAR_MAX; + locale.p_cs_precedes = CHAR_MAX; + locale.p_sep_by_space = CHAR_MAX; + locale.n_cs_precedes = CHAR_MAX; + locale.n_sep_by_space = CHAR_MAX; + locale.p_sign_posn = CHAR_MAX; + locale.n_sign_posn = CHAR_MAX; + locale.int_p_cs_precedes = CHAR_MAX; + locale.int_p_sep_by_space = CHAR_MAX; + locale.int_n_cs_precedes = CHAR_MAX; + locale.int_n_sep_by_space = CHAR_MAX; + locale.int_p_sign_posn = CHAR_MAX; + locale.int_n_sign_posn = CHAR_MAX; +} + +lconv* localeconv() { + pthread_once(&locale_once, __locale_init); + return &locale; +} + // setlocale(3) always fails on bionic. char* setlocale(int /*category*/, char const* /*locale*/) { - return NULL; + return NULL; } diff --git a/libc/include/locale.h b/libc/include/locale.h index 4efc5643b..aa6b4745e 100644 --- a/libc/include/locale.h +++ b/libc/include/locale.h @@ -49,9 +49,6 @@ enum { LC_IDENTIFICATION = 12 }; -extern char* setlocale(int, const char*); - -#if defined(__LP64__) struct lconv { char* decimal_point; char* thousands_sep; @@ -71,7 +68,6 @@ struct lconv { char n_sep_by_space; char p_sign_posn; char n_sign_posn; - /* ISO-C99 */ char int_p_cs_precedes; char int_p_sep_by_space; char int_n_cs_precedes; @@ -79,12 +75,9 @@ struct lconv { char int_p_sign_posn; char int_n_sign_posn; }; -#else -// Keep old declaration for ILP32 for compatibility -struct lconv { }; -#endif struct lconv* localeconv(void); +extern char* setlocale(int, const char*); __END_DECLS diff --git a/libc/include/sys/localedef.h b/libc/include/sys/localedef.h deleted file mode 100644 index b6b5eb1af..000000000 --- a/libc/include/sys/localedef.h +++ /dev/null @@ -1,101 +0,0 @@ -/* $OpenBSD: localedef.h,v 1.3 1996/04/21 22:31:47 deraadt Exp $ */ -/* $NetBSD: localedef.h,v 1.4 1996/04/09 20:55:31 cgd Exp $ */ - -/* - * Copyright (c) 1994 Winning Strategies, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Winning Strategies, Inc. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _SYS_LOCALEDEF_H_ -#define _SYS_LOCALEDEF_H_ - -#include -#include - -typedef struct -{ - char *yesexpr; - char *noexpr; - char *yesstr; - char *nostr; -} _MessagesLocale; - -extern const _MessagesLocale *_CurrentMessagesLocale; -extern const _MessagesLocale _DefaultMessagesLocale; - - -typedef struct -{ - char *int_curr_symbol; - char *currency_symbol; - char *mon_decimal_point; - char *mon_thousands_sep; - char *mon_grouping; - char *positive_sign; - char *negative_sign; - char int_frac_digits; - char frac_digits; - char p_cs_precedes; - char p_sep_by_space; - char n_cs_precedes; - char n_sep_by_space; - char p_sign_posn; - char n_sign_posn; -} _MonetaryLocale; - -extern const _MonetaryLocale *_CurrentMonetaryLocale; -extern const _MonetaryLocale _DefaultMonetaryLocale; - - -typedef struct -{ - const char *decimal_point; - const char *thousands_sep; - const char *grouping; -} _NumericLocale; - -extern const _NumericLocale *_CurrentNumericLocale; -extern const _NumericLocale _DefaultNumericLocale; - - -typedef struct { - const char *abday[7]; - const char *day[7]; - const char *abmon[12]; - const char *mon[12]; - const char *am_pm[2]; - const char *d_t_fmt; - const char *d_fmt; - const char *t_fmt; - const char *t_fmt_ampm; -} _TimeLocale; - -extern const _TimeLocale *_CurrentTimeLocale; -extern const _TimeLocale _DefaultTimeLocale; - -#endif /* !_SYS_LOCALEDEF_H_ */ diff --git a/libc/stdlib/strtod.c b/libc/stdlib/strtod.c index b39c90efa..95d0e1921 100644 --- a/libc/stdlib/strtod.c +++ b/libc/stdlib/strtod.c @@ -1332,15 +1332,11 @@ strtod Bigint *bb1, *bd0; Bigint *bb = NULL, *bd = NULL, *bs = NULL, *delta = NULL;/* pacify gcc */ -#if defined(__LP64__) /* BEGIN android-changed: no localeconv for ILP32. */ #ifndef KR_headers CONST char decimal_point = localeconv()->decimal_point[0]; #else CONST char decimal_point = '.'; #endif -#else - CONST char decimal_point = '.'; -#endif /* END android-changed */ sign = nz0 = nz = 0; value(rv) = 0.; diff --git a/libc/upstream-openbsd/lib/libc/locale/_def_messages.c b/libc/upstream-openbsd/lib/libc/locale/_def_messages.c deleted file mode 100644 index 1ed653a97..000000000 --- a/libc/upstream-openbsd/lib/libc/locale/_def_messages.c +++ /dev/null @@ -1,18 +0,0 @@ -/* $OpenBSD: _def_messages.c,v 1.5 2005/08/08 08:05:35 espie Exp $ */ -/* - * Written by J.T. Conklin . - * Public domain. - */ - -#include -#include - -const _MessagesLocale _DefaultMessagesLocale = -{ - "^[Yy]", - "^[Nn]", - "yes", - "no" -} ; - -const _MessagesLocale *_CurrentMessagesLocale = &_DefaultMessagesLocale; diff --git a/libc/upstream-openbsd/lib/libc/locale/_def_monetary.c b/libc/upstream-openbsd/lib/libc/locale/_def_monetary.c deleted file mode 100644 index aa92c75d1..000000000 --- a/libc/upstream-openbsd/lib/libc/locale/_def_monetary.c +++ /dev/null @@ -1,30 +0,0 @@ -/* $OpenBSD: _def_monetary.c,v 1.4 2005/08/08 08:05:35 espie Exp $ */ -/* - * Written by J.T. Conklin . - * Public domain. - */ - -#include -#include -#include - -const _MonetaryLocale _DefaultMonetaryLocale = -{ - "", - "", - "", - "", - "", - "", - "", - CHAR_MAX, - CHAR_MAX, - CHAR_MAX, - CHAR_MAX, - CHAR_MAX, - CHAR_MAX, - CHAR_MAX, - CHAR_MAX -}; - -const _MonetaryLocale *_CurrentMonetaryLocale = &_DefaultMonetaryLocale; diff --git a/libc/upstream-openbsd/lib/libc/locale/_def_numeric.c b/libc/upstream-openbsd/lib/libc/locale/_def_numeric.c deleted file mode 100644 index 6511254ac..000000000 --- a/libc/upstream-openbsd/lib/libc/locale/_def_numeric.c +++ /dev/null @@ -1,17 +0,0 @@ -/* $OpenBSD: _def_numeric.c,v 1.4 2005/08/08 08:05:35 espie Exp $ */ -/* - * Written by J.T. Conklin . - * Public domain. - */ - -#include -#include - -const _NumericLocale _DefaultNumericLocale = -{ - ".", - "", - "" -}; - -const _NumericLocale *_CurrentNumericLocale = &_DefaultNumericLocale; diff --git a/libc/upstream-openbsd/lib/libc/locale/_def_time.c b/libc/upstream-openbsd/lib/libc/locale/_def_time.c deleted file mode 100644 index 75179a605..000000000 --- a/libc/upstream-openbsd/lib/libc/locale/_def_time.c +++ /dev/null @@ -1,36 +0,0 @@ -/* $OpenBSD: _def_time.c,v 1.5 2011/10/09 06:39:53 ajacoutot Exp $ */ -/* - * Written by J.T. Conklin . - * Public domain. - */ - -#include -#include - -const _TimeLocale _DefaultTimeLocale = -{ - { - "Sun","Mon","Tue","Wed","Thu","Fri","Sat", - }, - { - "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", - "Friday", "Saturday" - }, - { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }, - { - "January", "February", "March", "April", "May", "June", "July", - "August", "September", "October", "November", "December" - }, - { - "AM", "PM" - }, - "%a %b %e %H:%M:%S %Y", - "%m/%d/%y", - "%H:%M:%S", - "%I:%M:%S %p" -}; - -const _TimeLocale *_CurrentTimeLocale = &_DefaultTimeLocale; diff --git a/libc/upstream-openbsd/lib/libc/locale/localeconv.c b/libc/upstream-openbsd/lib/libc/locale/localeconv.c deleted file mode 100644 index 989eb4bca..000000000 --- a/libc/upstream-openbsd/lib/libc/locale/localeconv.c +++ /dev/null @@ -1,59 +0,0 @@ -/* $OpenBSD: localeconv.c,v 1.5 2005/08/08 08:05:35 espie Exp $ */ -/* - * Written by J.T. Conklin . - * Public domain. - */ - -#include -#include - -/* - * The localeconv() function constructs a struct lconv from the current - * monetary and numeric locales. - * - * Because localeconv() may be called many times (especially by library - * routines like printf() & strtod()), the approprate members of the - * lconv structure are computed only when the monetary or numeric - * locale has been changed. - */ -int __mlocale_changed = 1; -int __nlocale_changed = 1; - -/* - * Return the current locale conversion. - */ -struct lconv * -localeconv(void) -{ - static struct lconv ret; - - if (__mlocale_changed) { - /* LC_MONETARY */ - ret.int_curr_symbol = _CurrentMonetaryLocale->int_curr_symbol; - ret.currency_symbol = _CurrentMonetaryLocale->currency_symbol; - ret.mon_decimal_point = _CurrentMonetaryLocale->mon_decimal_point; - ret.mon_thousands_sep = _CurrentMonetaryLocale->mon_thousands_sep; - ret.mon_grouping = _CurrentMonetaryLocale->mon_grouping; - ret.positive_sign = _CurrentMonetaryLocale->positive_sign; - ret.negative_sign = _CurrentMonetaryLocale->negative_sign; - ret.int_frac_digits = _CurrentMonetaryLocale->int_frac_digits; - ret.frac_digits = _CurrentMonetaryLocale->frac_digits; - ret.p_cs_precedes = _CurrentMonetaryLocale->p_cs_precedes; - ret.p_sep_by_space = _CurrentMonetaryLocale->p_sep_by_space; - ret.n_cs_precedes = _CurrentMonetaryLocale->n_cs_precedes; - ret.n_sep_by_space = _CurrentMonetaryLocale->n_sep_by_space; - ret.p_sign_posn = _CurrentMonetaryLocale->p_sign_posn; - ret.n_sign_posn = _CurrentMonetaryLocale->n_sign_posn; - __mlocale_changed = 0; - } - - if (__nlocale_changed) { - /* LC_NUMERIC */ - ret.decimal_point = (char *) _CurrentNumericLocale->decimal_point; - ret.thousands_sep = (char *) _CurrentNumericLocale->thousands_sep; - ret.grouping = (char *) _CurrentNumericLocale->grouping; - __nlocale_changed = 0; - } - - return (&ret); -} diff --git a/tests/locale_test.cpp b/tests/locale_test.cpp index df58a70df..87dd63197 100644 --- a/tests/locale_test.cpp +++ b/tests/locale_test.cpp @@ -16,13 +16,32 @@ #include +#include #include TEST(locale, localeconv) { -#ifdef __LP64__ - ASSERT_STREQ(".", localeconv()->decimal_point); - ASSERT_STREQ("", localeconv()->currency_symbol); -#else - GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif + EXPECT_STREQ(".", localeconv()->decimal_point); + EXPECT_STREQ("", localeconv()->thousands_sep); + EXPECT_STREQ("", localeconv()->grouping); + EXPECT_STREQ("", localeconv()->int_curr_symbol); + EXPECT_STREQ("", localeconv()->currency_symbol); + EXPECT_STREQ("", localeconv()->mon_decimal_point); + EXPECT_STREQ("", localeconv()->mon_thousands_sep); + EXPECT_STREQ("", localeconv()->mon_grouping); + EXPECT_STREQ("", localeconv()->positive_sign); + EXPECT_STREQ("", localeconv()->negative_sign); + EXPECT_EQ(CHAR_MAX, localeconv()->int_frac_digits); + EXPECT_EQ(CHAR_MAX, localeconv()->frac_digits); + EXPECT_EQ(CHAR_MAX, localeconv()->p_cs_precedes); + EXPECT_EQ(CHAR_MAX, localeconv()->p_sep_by_space); + EXPECT_EQ(CHAR_MAX, localeconv()->n_cs_precedes); + EXPECT_EQ(CHAR_MAX, localeconv()->n_sep_by_space); + EXPECT_EQ(CHAR_MAX, localeconv()->p_sign_posn); + EXPECT_EQ(CHAR_MAX, localeconv()->n_sign_posn); + EXPECT_EQ(CHAR_MAX, localeconv()->int_p_cs_precedes); + EXPECT_EQ(CHAR_MAX, localeconv()->int_p_sep_by_space); + EXPECT_EQ(CHAR_MAX, localeconv()->int_n_cs_precedes); + EXPECT_EQ(CHAR_MAX, localeconv()->int_n_sep_by_space); + EXPECT_EQ(CHAR_MAX, localeconv()->int_p_sign_posn); + EXPECT_EQ(CHAR_MAX, localeconv()->int_n_sign_posn); }