OSDN Git Service

Add lconv declaration and localeconv(3)
authorPavel Chupin <pavel.v.chupin@intel.com>
Tue, 25 Mar 2014 09:43:04 +0000 (13:43 +0400)
committerCalin Juravle <calin@google.com>
Fri, 28 Mar 2014 11:15:03 +0000 (11:15 +0000)
lconv is taken from ndk/sources/android/support/include/locale.h and
matches
bsd/glibc upstream.
Keep old declaration for 32-bits for compatibility.
localeconv.c and deps are taken from openbsd upstream.
Changed strtod.c accordingly.

Change-Id: I9fcc4d15f5674d192950d80edf26f36006cd31b4
Signed-off-by: Pavel Chupin <pavel.v.chupin@intel.com>
13 files changed:
libc/arch-arm64/arm64.mk
libc/arch-mips64/mips64.mk
libc/arch-x86_64/x86_64.mk
libc/include/locale.h
libc/include/sys/localedef.h [new file with mode: 0644]
libc/stdlib/strtod.c
libc/upstream-openbsd/lib/libc/locale/_def_messages.c [new file with mode: 0644]
libc/upstream-openbsd/lib/libc/locale/_def_monetary.c [new file with mode: 0644]
libc/upstream-openbsd/lib/libc/locale/_def_numeric.c [new file with mode: 0644]
libc/upstream-openbsd/lib/libc/locale/_def_time.c [new file with mode: 0644]
libc/upstream-openbsd/lib/libc/locale/localeconv.c [new file with mode: 0644]
tests/Android.mk
tests/locale_test.cpp [new file with mode: 0644]

index 88da1f3..7b6b1c3 100644 (file)
@@ -14,6 +14,11 @@ 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 \
index 28806e1..9b29f0d 100644 (file)
@@ -16,6 +16,11 @@ 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 \
index 9bce065..a3adaa4 100644 (file)
@@ -18,6 +18,11 @@ 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 \
index b6dbfdb..4efc564 100644 (file)
@@ -51,12 +51,41 @@ enum {
 
 extern char* setlocale(int, const char*);
 
-#if !defined(__LP64__)
-// TODO: LP32 had these bogus declarations but LP64 should have a real struct lconv and localeconv(3).
+#if defined(__LP64__)
+struct lconv {
+    char* decimal_point;
+    char* thousands_sep;
+    char* grouping;
+    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;
+    /* ISO-C99 */
+    char  int_p_cs_precedes;
+    char  int_p_sep_by_space;
+    char  int_n_cs_precedes;
+    char  int_n_sep_by_space;
+    char  int_p_sign_posn;
+    char  int_n_sign_posn;
+};
+#else
+// Keep old declaration for ILP32 for compatibility
 struct lconv { };
-struct lconv* localeconv(void);
 #endif
 
+struct lconv* localeconv(void);
+
 __END_DECLS
 
 #endif /* _LOCALE_H_ */
diff --git a/libc/include/sys/localedef.h b/libc/include/sys/localedef.h
new file mode 100644 (file)
index 0000000..b6b5eb1
--- /dev/null
@@ -0,0 +1,101 @@
+/*     $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 <sys/param.h>
+#include <sys/types.h>
+
+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_ */
index 0a19446..b39c90e 100644 (file)
@@ -1332,13 +1332,14 @@ strtod
        Bigint *bb1, *bd0;
        Bigint *bb = NULL, *bd = NULL, *bs = NULL, *delta = NULL;/* pacify gcc */
 
-       CONST char decimal_point = '.';
-#if 0 /* BEGIN android-changed: no localeconv. */
+#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;
diff --git a/libc/upstream-openbsd/lib/libc/locale/_def_messages.c b/libc/upstream-openbsd/lib/libc/locale/_def_messages.c
new file mode 100644 (file)
index 0000000..1ed653a
--- /dev/null
@@ -0,0 +1,18 @@
+/*     $OpenBSD: _def_messages.c,v 1.5 2005/08/08 08:05:35 espie Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/localedef.h>
+#include <locale.h>
+
+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
new file mode 100644 (file)
index 0000000..aa92c75
--- /dev/null
@@ -0,0 +1,30 @@
+/*     $OpenBSD: _def_monetary.c,v 1.4 2005/08/08 08:05:35 espie Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/localedef.h>
+#include <limits.h>
+#include <locale.h>
+
+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
new file mode 100644 (file)
index 0000000..6511254
--- /dev/null
@@ -0,0 +1,17 @@
+/*     $OpenBSD: _def_numeric.c,v 1.4 2005/08/08 08:05:35 espie Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/localedef.h>
+#include <locale.h>
+
+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
new file mode 100644 (file)
index 0000000..75179a6
--- /dev/null
@@ -0,0 +1,36 @@
+/*     $OpenBSD: _def_time.c,v 1.5 2011/10/09 06:39:53 ajacoutot Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/localedef.h>
+#include <locale.h>
+
+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
new file mode 100644 (file)
index 0000000..989eb4b
--- /dev/null
@@ -0,0 +1,59 @@
+/*     $OpenBSD: localeconv.c,v 1.5 2005/08/08 08:05:35 espie Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/localedef.h>
+#include <locale.h>
+
+/*
+ * 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);
+}
index a37ea4a..788dbcf 100644 (file)
@@ -50,6 +50,7 @@ libBionicStandardTests_src_files := \
     inttypes_test.cpp \
     libc_logging_test.cpp \
     libgen_test.cpp \
+    locale_test.cpp \
     malloc_test.cpp \
     math_test.cpp \
     netdb_test.cpp \
diff --git a/tests/locale_test.cpp b/tests/locale_test.cpp
new file mode 100644 (file)
index 0000000..df58a70
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <locale.h>
+
+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
+}