[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: android bionc has dummy lconv
From: |
Bruno Haible |
Subject: |
Re: android bionc has dummy lconv |
Date: |
Sun, 25 Mar 2012 13:30:34 +0200 |
User-agent: |
KMail/4.7.4 (Linux/3.1.0-1.2-desktop; KDE/4.7.4; x86_64; ; ) |
Gianluigi Tiesi wrote:
> sorry (sent the first email by mistake)
>
> #if 1 /* MISSING FROM BIONIC - DEFINED TO MAKE libstdc++-v3 happy */
> struct lconv { };
> struct lconv *localeconv(void);
> #endif /* MISSING */
> ...
> android bionic hasn't locale support by design)
Thanks for the info.
> the only problem is in gnulib nl_langinfo.c at 154
>
> case RADIXCHAR:
> return localeconv () ->decimal_point;
> case THOUSEP:
> return localeconv () ->thousands_sep;
> /* nl_langinfo items of the LC_TIME category.
> TODO: Really use the locale. */
There are more uses, also in human.c and vasnprintf.c.
> disable the module at all
The gnulib philosophy is that the developer can program according to POSIX
and Glibc APIs, even on deficient platforms.
Here's the first part of a supposed fix.
2012-03-25 Bruno Haible <address@hidden>
locale: Provide a working 'struct lconv'.
* lib/locale.in.h (lconv): Override if REPLACE_STRUCT_LCONV is 1.
* m4/locale_h.m4 (gl_LOCALE_H): Set REPLACE_STRUCT_LCONV to 1 if
'struct lconv' does not even contain decimal_point.
(gl_LOCALE_H_DEFAULTS): Initialize REPLACE_STRUCT_LCONV.
* modules/locale (Makefile.am): Substitute REPLACE_STRUCT_LCONV.
* tests/test-locale.c (main): Check that 'struct lconv' is complete.
* doc/posix-headers/locale.texi: Mention the problems with
'struct lconv'.
Reported by Gianluigi Tiesi <address@hidden>.
--- doc/posix-headers/locale.texi.orig Sun Mar 25 13:20:43 2012
+++ doc/posix-headers/locale.texi Sun Mar 25 13:13:08 2012
@@ -16,6 +16,17 @@
glibc 2.11, MacOS X 10.5.
@item
+The @code{struct lconv} type does not contain any members on some platforms:
+Android.
+
address@hidden
+The @code{struct lconv} type does not contain the members
address@hidden, @code{int_p_sign_posn}, @code{int_p_sep_by_space},
address@hidden, @code{int_n_sign_posn}, @code{int_n_sep_by_space}
+on some platforms:
+glibc.
+
address@hidden
Some platforms provide a @code{NULL} macro that cannot be used in arbitrary
expressions:
NetBSD 5.0
@@ -23,4 +34,10 @@
Portability problems not fixed by Gnulib:
@itemize
address@hidden
+The @code{struct lconv} type does not contain the members
address@hidden, @code{int_p_sign_posn}, @code{int_p_sep_by_space},
address@hidden, @code{int_n_sign_posn}, @code{int_n_sep_by_space}
+on some platforms:
+OpenBSD 4.9, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 11 2011-11, Cygwin 1.5.x,
mingw, MSVC 9.
@end itemize
--- lib/locale.in.h.orig Sun Mar 25 13:20:43 2012
+++ lib/locale.in.h Sun Mar 25 13:15:06 2012
@@ -47,6 +47,87 @@
# define LC_MESSAGES 1729
#endif
+/* Bionic libc's 'struct lconv' is just a dummy. */
+#if @REPLACE_STRUCT_LCONV@
+# define lconv rpl_lconv
+struct lconv
+{
+ /* All 'char *' are actually 'const char *'. */
+
+ /* Members that depend on the LC_NUMERIC category of the locale. See
+
<http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_04>
*/
+
+ /* Symbol used as decimal point. */
+ char *decimal_point;
+ /* Symbol used to separate groups of digits to the left of the decimal
+ point. */
+ char *thousands_sep;
+ /* Definition of the size of groups of digits to the left of the decimal
+ point. */
+ char *grouping;
+
+ /* Members that depend on the LC_MONETARY category of the locale. See
+
<http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_03>
*/
+
+ /* Symbol used as decimal point. */
+ char *mon_decimal_point;
+ /* Symbol used to separate groups of digits to the left of the decimal
+ point. */
+ char *mon_thousands_sep;
+ /* Definition of the size of groups of digits to the left of the decimal
+ point. */
+ char *mon_grouping;
+ /* Sign used to indicate a value >= 0. */
+ char *positive_sign;
+ /* Sign used to indicate a value < 0. */
+ char *negative_sign;
+
+ /* For formatting local currency. */
+ /* Currency symbol (3 characters) followed by separator (1 character). */
+ char *currency_symbol;
+ /* Number of digits after the decimal point. */
+ char frac_digits;
+ /* For values >= 0: 1 if the currency symbol precedes the number, 0 if it
+ comes after the number. */
+ char p_cs_precedes;
+ /* For values >= 0: Position of the sign. */
+ char p_sign_posn;
+ /* For values >= 0: Placement of spaces between currency symbol, sign, and
+ number. */
+ char p_sep_by_space;
+ /* For values < 0: 1 if the currency symbol precedes the number, 0 if it
+ comes after the number. */
+ char n_cs_precedes;
+ /* For values < 0: Position of the sign. */
+ char n_sign_posn;
+ /* For values < 0: Placement of spaces between currency symbol, sign, and
+ number. */
+ char n_sep_by_space;
+
+ /* For formatting international currency. */
+ /* Currency symbol (3 characters) followed by separator (1 character). */
+ char *int_curr_symbol;
+ /* Number of digits after the decimal point. */
+ char int_frac_digits;
+ /* For values >= 0: 1 if the currency symbol precedes the number, 0 if it
+ comes after the number. */
+ char int_p_cs_precedes;
+ /* For values >= 0: Position of the sign. */
+ char int_p_sign_posn;
+ /* For values >= 0: Placement of spaces between currency symbol, sign, and
+ number. */
+ char int_p_sep_by_space;
+ /* For values < 0: 1 if the currency symbol precedes the number, 0 if it
+ comes after the number. */
+ char int_n_cs_precedes;
+ /* For values < 0: Position of the sign. */
+ char int_n_sign_posn;
+ /* For values < 0: Placement of spaces between currency symbol, sign, and
+ number. */
+ char int_n_sep_by_space;
+};
+#endif
+
#if @GNULIB_SETLOCALE@
# if @REPLACE_SETLOCALE@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
--- m4/locale_h.m4.orig Sun Mar 25 13:20:43 2012
+++ m4/locale_h.m4 Sun Mar 25 13:13:49 2012
@@ -1,4 +1,4 @@
-# locale_h.m4 serial 14
+# locale_h.m4 serial 15
dnl Copyright (C) 2007, 2009-2012 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -10,7 +10,8 @@
dnl once only, before all statements that occur in other macros.
AC_REQUIRE([gl_LOCALE_H_DEFAULTS])
- dnl Persuade glibc <locale.h> to define locale_t.
+ dnl Persuade glibc <locale.h> to define locale_t and the int_p_*, int_n_*
+ dnl members of 'struct lconv'.
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
dnl If <stddef.h> is replaced, then <locale.h> must also be replaced.
@@ -21,7 +22,8 @@
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#include <locale.h>
- int x = LC_MESSAGES;]],
+ int x = LC_MESSAGES;
+ int y = sizeof (((struct lconv *) 0)->decimal_point);]],
[[]])],
[gl_cv_header_locale_h_posix2001=yes],
[gl_cv_header_locale_h_posix2001=no])])
@@ -54,6 +56,23 @@
fi
AC_SUBST([HAVE_XLOCALE_H])
+ dnl Check whether 'struct lconv' is well-defined.
+ dnl Bionic libc's 'struct lconv' is just a dummy.
+ AC_CACHE_CHECK([whether struct lconv is properly defined],
+ [gl_cv_sys_struct_lconv_ok],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <locale.h>
+ struct lconv l;
+ int x = sizeof (l.decimal_point);]],
+ [[]])],
+ [gl_cv_sys_struct_lconv_ok=yes],
+ [gl_cv_sys_struct_lconv_ok=no])
+ ])
+ if test $gl_cv_sys_struct_lconv_ok = no; then
+ REPLACE_STRUCT_LCONV=1
+ fi
+
dnl <locale.h> is always overridden, because of GNULIB_POSIXCHECK.
gl_NEXT_HEADERS([locale.h])
@@ -82,7 +101,8 @@
GNULIB_SETLOCALE=0; AC_SUBST([GNULIB_SETLOCALE])
GNULIB_DUPLOCALE=0; AC_SUBST([GNULIB_DUPLOCALE])
dnl Assume proper GNU behavior unless another module says otherwise.
- HAVE_DUPLOCALE=1; AC_SUBST([HAVE_DUPLOCALE])
- REPLACE_SETLOCALE=0; AC_SUBST([REPLACE_SETLOCALE])
- REPLACE_DUPLOCALE=0; AC_SUBST([REPLACE_DUPLOCALE])
+ HAVE_DUPLOCALE=1; AC_SUBST([HAVE_DUPLOCALE])
+ REPLACE_SETLOCALE=0; AC_SUBST([REPLACE_SETLOCALE])
+ REPLACE_DUPLOCALE=0; AC_SUBST([REPLACE_DUPLOCALE])
+ REPLACE_STRUCT_LCONV=0; AC_SUBST([REPLACE_STRUCT_LCONV])
])
--- modules/locale.orig Sun Mar 25 13:20:43 2012
+++ modules/locale Sun Mar 25 12:46:54 2012
@@ -35,6 +35,7 @@
-e 's|@''HAVE_XLOCALE_H''@|$(HAVE_XLOCALE_H)|g' \
-e 's|@''REPLACE_SETLOCALE''@|$(REPLACE_SETLOCALE)|g' \
-e 's|@''REPLACE_DUPLOCALE''@|$(REPLACE_DUPLOCALE)|g' \
+ -e 's|@''REPLACE_STRUCT_LCONV''@|$(REPLACE_STRUCT_LCONV)|g' \
-e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
-e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
-e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
--- tests/test-locale.c.orig Sun Mar 25 13:20:44 2012
+++ tests/test-locale.c Sun Mar 25 13:19:10 2012
@@ -38,6 +38,10 @@
locale_t b = LC_GLOBAL_LOCALE;
#endif
+/* Check that the 'struct lconv' type is defined. */
+struct lconv l;
+int ls;
+
/* Check that NULL can be passed through varargs as a pointer type,
per POSIX 2008. */
verify (sizeof NULL == sizeof (void *));
@@ -45,5 +49,33 @@
int
main ()
{
+ /* Check that 'struct lconv' has the ISO C and POSIX specified members. */
+ ls += sizeof (*l.decimal_point);
+ ls += sizeof (*l.thousands_sep);
+ ls += sizeof (*l.grouping);
+ ls += sizeof (*l.mon_decimal_point);
+ ls += sizeof (*l.mon_thousands_sep);
+ ls += sizeof (*l.mon_grouping);
+ ls += sizeof (*l.positive_sign);
+ ls += sizeof (*l.negative_sign);
+ ls += sizeof (*l.currency_symbol);
+ ls += sizeof (l.frac_digits);
+ ls += sizeof (l.p_cs_precedes);
+ ls += sizeof (l.p_sign_posn);
+ ls += sizeof (l.p_sep_by_space);
+ ls += sizeof (l.n_cs_precedes);
+ ls += sizeof (l.n_sign_posn);
+ ls += sizeof (l.n_sep_by_space);
+ ls += sizeof (*l.int_curr_symbol);
+ ls += sizeof (l.int_frac_digits);
+#if 0
+ ls += sizeof (l.int_p_cs_precedes);
+ ls += sizeof (l.int_p_sign_posn);
+ ls += sizeof (l.int_p_sep_by_space);
+ ls += sizeof (l.int_n_cs_precedes);
+ ls += sizeof (l.int_n_sign_posn);
+ ls += sizeof (l.int_n_sep_by_space);
+#endif
+
return 0;
}