Mercurial > hg > octave-lyh > gnulib-hg
changeset 16717:474c0712e7aa
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 <sherpya@netfarm.it>.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Sun, 25 Mar 2012 13:22:41 +0200 |
parents | 079fb1e73828 |
children | e4aad6f843ed |
files | ChangeLog doc/posix-headers/locale.texi lib/locale.in.h m4/locale_h.m4 modules/locale tests/test-locale.c |
diffstat | 6 files changed, 170 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2012-03-25 Bruno Haible <bruno@clisp.org> + + 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 <sherpya@netfarm.it>. + 2012-03-24 Bruno Haible <bruno@clisp.org> Enable common subexpression optimization in GCC.
--- a/doc/posix-headers/locale.texi +++ b/doc/posix-headers/locale.texi @@ -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. + +@item +The @code{struct lconv} type does not contain the members +@code{int_p_cs_precedes}, @code{int_p_sign_posn}, @code{int_p_sep_by_space}, +@code{int_n_cs_precedes}, @code{int_n_sign_posn}, @code{int_n_sep_by_space} +on some platforms: +glibc. + +@item 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 +@item +The @code{struct lconv} type does not contain the members +@code{int_p_cs_precedes}, @code{int_p_sign_posn}, @code{int_p_sep_by_space}, +@code{int_n_cs_precedes}, @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
--- a/lib/locale.in.h +++ b/lib/locale.in.h @@ -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)
--- a/m4/locale_h.m4 +++ b/m4/locale_h.m4 @@ -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]) ])
--- a/modules/locale +++ b/modules/locale @@ -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)' \
--- a/tests/test-locale.c +++ b/tests/test-locale.c @@ -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; }