quadmath-printf.c: Also check __GLIBC__ when checking whether workarounds for printf...
authorJakub Jelinek <jakub@redhat.com>
Wed, 16 Feb 2011 13:54:30 +0000 (14:54 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 16 Feb 2011 13:54:30 +0000 (14:54 +0100)
* printf/quadmath-printf.c: Also check __GLIBC__ when checking
whether workarounds for printf hook handling should be added.

* configure.ac: Check for locale.h too.
(USE_LOCALE_SUPPORT): Remove check.
(USE_NL_LANGINFO, USE_NL_LANGINFO_WC, USE_LOCALECONV): New checks.
(USE_I18_NUMBER_H): Check also for _NL_CTYPE_MB_CUR_MAX.
* printf/printf_fphex.c (__quadmath_printf_fphex): Use nl_langinfo
or localeconv for narrow version and nl_langinfo if USE_NL_LANGINFO_WC
for wide version.
* printf/quadmath-printf.h: Include locale.h if HAVE_LOCALE_H.
* printf/printf_fp.c (USE_I18N_NUMBER_H): Don't define to 0.
(__quadmath_printf_fp): Use nl_langinfo or localeconv for narrow
version and nl_langinfo if USE_NL_LANGINFO_WC for wide version.
Guard nl_langinfo (_NL_CTYPE_MB_CUR_MAX) use with
USE_I18N_NUMBER_H #ifdef.
* configure: Regenerated.
* config.h.in: Regenerated.

From-SVN: r170211

libquadmath/ChangeLog
libquadmath/config.h.in
libquadmath/configure
libquadmath/configure.ac
libquadmath/printf/printf_fp.c
libquadmath/printf/printf_fphex.c
libquadmath/printf/quadmath-printf.c
libquadmath/printf/quadmath-printf.h

index c451c8fd86b79e9046fdabb781fefb698f5c2da3..b8706ae676a655b06d603004f0aa15ed5a0c869a 100644 (file)
@@ -1,3 +1,24 @@
+2011-02-16  Jakub Jelinek  <jakub@redhat.com>
+
+       * printf/quadmath-printf.c: Also check __GLIBC__ when checking
+       whether workarounds for printf hook handling should be added.
+
+       * configure.ac: Check for locale.h too.
+       (USE_LOCALE_SUPPORT): Remove check.
+       (USE_NL_LANGINFO, USE_NL_LANGINFO_WC, USE_LOCALECONV): New checks.
+       (USE_I18_NUMBER_H): Check also for _NL_CTYPE_MB_CUR_MAX.
+       * printf/printf_fphex.c (__quadmath_printf_fphex): Use nl_langinfo
+       or localeconv for narrow version and nl_langinfo if USE_NL_LANGINFO_WC
+       for wide version.
+       * printf/quadmath-printf.h: Include locale.h if HAVE_LOCALE_H.
+       * printf/printf_fp.c (USE_I18N_NUMBER_H): Don't define to 0.
+       (__quadmath_printf_fp): Use nl_langinfo or localeconv for narrow
+       version and nl_langinfo if USE_NL_LANGINFO_WC for wide version.
+       Guard nl_langinfo (_NL_CTYPE_MB_CUR_MAX) use with
+       USE_I18N_NUMBER_H #ifdef.
+       * configure: Regenerated.
+       * config.h.in: Regenerated.
+
 2011-02-14  Jakub Jelinek  <jakub@redhat.com>
 
        PR bootstrap/47736
index 307da27df4914c1bbc11dd76fa9a93798ae326ad..38e08c03366abe407fc01f0f3fafdff0d03759d2 100644 (file)
@@ -42,6 +42,9 @@
 /* Define to 1 if you have the <limits.h> header file. */
 #undef HAVE_LIMITS_H
 
+/* Define to 1 if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
 /* whether i18n number rewriting can be supported */
 #undef USE_I18N_NUMBER_H
 
-/* whether nl_langinfo is sufficiently supported */
-#undef USE_LOCALE_SUPPORT
+/* whether localeconv should be used */
+#undef USE_LOCALECONV
+
+/* whether nl_langinfo should be used */
+#undef USE_NL_LANGINFO
+
+/* whether nl_langinfo should be used for wide char locale info */
+#undef USE_NL_LANGINFO_WC
 
 /* Enable extensions on AIX 3, Interix.  */
 #ifndef _ALL_SOURCE
index 47021ff49ec8caa99f1d8f095cf66a7c89330772..612d56c7ccbc7f3b7c42c58205a306e0916cbda0 100755 (executable)
@@ -11922,7 +11922,7 @@ esac
 
 
 
-for ac_header in fenv.h langinfo.h wchar.h wctype.h limits.h ctype.h printf.h errno.h
+for ac_header in fenv.h langinfo.h locale.h wchar.h wctype.h limits.h ctype.h printf.h errno.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -12577,8 +12577,8 @@ fi
 
 # Check for whether locale support for quadmath_snprintf or Q printf hooks
 # should be provided.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether locale support for quadmath_snprintf should be added" >&5
-$as_echo_n "checking whether locale support for quadmath_snprintf should be added... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether nl_langinfo should be used" >&5
+$as_echo_n "checking whether nl_langinfo should be used... " >&6; }
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <langinfo.h>
@@ -12593,11 +12593,40 @@ s = nl_langinfo (GROUPING);
 s = nl_langinfo (MON_GROUPING);
 s = nl_langinfo (THOUSANDS_SEP);
 s = nl_langinfo (MON_THOUSANDS_SEP);
+(void) s;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  quadmath_use_nl_langinfo=yes
+else
+  quadmath_use_nl_langinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $quadmath_use_nl_langinfo" >&5
+$as_echo "$quadmath_use_nl_langinfo" >&6; }
+if test x$quadmath_use_nl_langinfo = xyes; then
+
+$as_echo "#define USE_NL_LANGINFO 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether nl_langinfo should be used for wide char locale info" >&5
+$as_echo_n "checking whether nl_langinfo should be used for wide char locale info... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <langinfo.h>
+int
+main ()
+{
+
+const char *s;
 s = nl_langinfo (_NL_NUMERIC_DECIMAL_POINT_WC);
 s = nl_langinfo (_NL_MONETARY_DECIMAL_POINT_WC);
 s = nl_langinfo (_NL_NUMERIC_THOUSANDS_SEP_WC);
 s = nl_langinfo (_NL_MONETARY_THOUSANDS_SEP_WC);
-s = nl_langinfo (_NL_CTYPE_MB_CUR_MAX);
 (void) s;
 
   ;
@@ -12605,16 +12634,53 @@ s = nl_langinfo (_NL_CTYPE_MB_CUR_MAX);
 }
 _ACEOF
 if ac_fn_c_try_compile "$LINENO"; then :
-  quadmath_use_locale_support=yes
+  quadmath_use_nl_langinfo_wc=yes
 else
-  quadmath_use_locale_support=no
+  quadmath_use_nl_langinfo_wc=no
 fi
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $quadmath_use_locale_support" >&5
-$as_echo "$quadmath_use_locale_support" >&6; }
-if test x$quadmath_use_locale_support = xyes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $quadmath_use_nl_langinfo_wc" >&5
+$as_echo "$quadmath_use_nl_langinfo_wc" >&6; }
+if test x$quadmath_use_nl_langinfo_wc = xyes; then
 
-$as_echo "#define USE_LOCALE_SUPPORT 1" >>confdefs.h
+$as_echo "#define USE_NL_LANGINFO_WC 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether localeconv should be used" >&5
+$as_echo_n "checking whether localeconv should be used... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <locale.h>
+int
+main ()
+{
+
+const struct lconv *l = localeconv ();
+const char *s;
+s = l->decimal_point;
+s = l->mon_decimal_point;
+s = l->grouping;
+s = l->mon_grouping;
+s = l->thousands_sep;
+s = l->mon_thousands_sep;
+(void) s;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  quadmath_use_localeconv=yes
+else
+  quadmath_use_localeconv=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $quadmath_use_localeconv" >&5
+$as_echo "$quadmath_use_localeconv" >&6; }
+if test x$quadmath_use_localeconv = xyes; then
+
+$as_echo "#define USE_LOCALECONV 1" >>confdefs.h
 
 fi
 
@@ -12642,6 +12708,7 @@ memset (&state, '\0', sizeof (state));
 wcrtomb (decimal, wdecimal, &state);
 s = nl_langinfo (_NL_CTYPE_OUTDIGIT0_MB);
 s = nl_langinfo (_NL_CTYPE_OUTDIGIT0_WC);
+s = nl_langinfo (_NL_CTYPE_MB_CUR_MAX);
 (void) s;
 
   ;
index 04a6e4a3076b95ab9906dc9d08e4dddff045ceda..0cd675fb2fc245d18aa2851bf33842c9a46c9873 100644 (file)
@@ -112,7 +112,7 @@ esac
 AC_SUBST(toolexecdir)
 AC_SUBST(toolexeclibdir)
 
-AC_CHECK_HEADERS(fenv.h langinfo.h wchar.h wctype.h limits.h ctype.h printf.h errno.h)
+AC_CHECK_HEADERS(fenv.h langinfo.h locale.h wchar.h wctype.h limits.h ctype.h printf.h errno.h)
 
 # If available, sqrtl and cbrtl speed up the calculation -
 # but they are not required
@@ -251,7 +251,7 @@ fi
 
 # Check for whether locale support for quadmath_snprintf or Q printf hooks
 # should be provided.
-AC_MSG_CHECKING([whether locale support for quadmath_snprintf should be added])
+AC_MSG_CHECKING([whether nl_langinfo should be used])
 AC_TRY_COMPILE([#include <langinfo.h>],[
 const char *s;
 s = nl_langinfo (DECIMAL_POINT);
@@ -260,17 +260,45 @@ s = nl_langinfo (GROUPING);
 s = nl_langinfo (MON_GROUPING);
 s = nl_langinfo (THOUSANDS_SEP);
 s = nl_langinfo (MON_THOUSANDS_SEP);
+(void) s;
+],
+[quadmath_use_nl_langinfo=yes],[quadmath_use_nl_langinfo=no])
+AC_MSG_RESULT($quadmath_use_nl_langinfo)
+if test x$quadmath_use_nl_langinfo = xyes; then
+  AC_DEFINE([USE_NL_LANGINFO],[1],[whether nl_langinfo should be used])
+fi
+
+AC_MSG_CHECKING([whether nl_langinfo should be used for wide char locale info])
+AC_TRY_COMPILE([#include <langinfo.h>],[
+const char *s;
 s = nl_langinfo (_NL_NUMERIC_DECIMAL_POINT_WC);
 s = nl_langinfo (_NL_MONETARY_DECIMAL_POINT_WC);
 s = nl_langinfo (_NL_NUMERIC_THOUSANDS_SEP_WC);
 s = nl_langinfo (_NL_MONETARY_THOUSANDS_SEP_WC);
-s = nl_langinfo (_NL_CTYPE_MB_CUR_MAX);
 (void) s;
 ],
-[quadmath_use_locale_support=yes],[quadmath_use_locale_support=no])
-AC_MSG_RESULT($quadmath_use_locale_support)
-if test x$quadmath_use_locale_support = xyes; then
-  AC_DEFINE([USE_LOCALE_SUPPORT],[1],[whether nl_langinfo is sufficiently supported])
+[quadmath_use_nl_langinfo_wc=yes],[quadmath_use_nl_langinfo_wc=no])
+AC_MSG_RESULT($quadmath_use_nl_langinfo_wc)
+if test x$quadmath_use_nl_langinfo_wc = xyes; then
+  AC_DEFINE([USE_NL_LANGINFO_WC],[1],[whether nl_langinfo should be used for wide char locale info])
+fi
+
+AC_MSG_CHECKING([whether localeconv should be used])
+AC_TRY_COMPILE([#include <locale.h>],[
+const struct lconv *l = localeconv ();
+const char *s;
+s = l->decimal_point;
+s = l->mon_decimal_point;
+s = l->grouping;
+s = l->mon_grouping;
+s = l->thousands_sep;
+s = l->mon_thousands_sep;
+(void) s;
+],
+[quadmath_use_localeconv=yes],[quadmath_use_localeconv=no])
+AC_MSG_RESULT($quadmath_use_localeconv)
+if test x$quadmath_use_localeconv = xyes; then
+  AC_DEFINE([USE_LOCALECONV],[1],[whether localeconv should be used])
 fi
 
 # Check for whether i18n number rewriting support for quadmath_snprintf
@@ -290,6 +318,7 @@ memset (&state, '\0', sizeof (state));
 wcrtomb (decimal, wdecimal, &state);
 s = nl_langinfo (_NL_CTYPE_OUTDIGIT0_MB);
 s = nl_langinfo (_NL_CTYPE_OUTDIGIT0_WC);
+s = nl_langinfo (_NL_CTYPE_MB_CUR_MAX);
 (void) s;
 ],
 [quadmath_use_i18n_number_h=yes],[quadmath_use_i18n_number_h=no])
index 4d0bf18ce488f4d6e53add2439b7b7b588a10597..4a63be9f8a34a4f62247acdbbd4a972b439a5c34 100644 (file)
@@ -37,8 +37,6 @@
 
 #ifdef USE_I18N_NUMBER_H
 #include "_i18n_number.h"
-#else
-#define USE_I18N_NUMBER_H 0
 #endif
 
 \f
@@ -227,30 +225,48 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
     }
 
   /* Figure out the decimal point character.  */
-#ifdef USE_LOCALE_SUPPORT
+#ifdef USE_NL_LANGINFO
   if (info->extra == 0)
-    {
-      decimal = nl_langinfo (DECIMAL_POINT);
-      decimalwc = nl_langinfo_wc (_NL_NUMERIC_DECIMAL_POINT_WC);
-    }
+    decimal = nl_langinfo (DECIMAL_POINT);
   else
     {
       decimal = nl_langinfo (MON_DECIMAL_POINT);
       if (*decimal == '\0')
        decimal = nl_langinfo (DECIMAL_POINT);
+    }
+  /* The decimal point character must never be zero.  */
+  assert (*decimal != '\0');
+#elif defined USE_LOCALECONV
+  const struct lconv *lc = localeconv ();
+  if (info->extra == 0)
+    decimal = lc->decimal_point;
+  else
+    {
+      decimal = lc->mon_decimal_point;
+      if (decimal == NULL || *decimal == '\0')
+       decimal = lc->decimal_point;
+    }
+  if (decimal == NULL || *decimal == '\0')
+    decimal = ".";
+#else
+  decimal = ".";
+#endif
+#ifdef USE_NL_LANGINFO_WC
+  if (info->extra == 0)
+    decimalwc = nl_langinfo_wc (_NL_NUMERIC_DECIMAL_POINT_WC);
+  else
+    {
       decimalwc = nl_langinfo_wc (_NL_MONETARY_DECIMAL_POINT_WC);
       if (decimalwc == L_('\0'))
        decimalwc = nl_langinfo_wc (_NL_NUMERIC_DECIMAL_POINT_WC);
     }
-  /* The decimal point character must not be zero.  */
-  assert (*decimal != '\0');
+  /* The decimal point character must never be zero.  */
   assert (decimalwc != L_('\0'));
 #else
-  decimal = ".";
   decimalwc = L_('.');
 #endif
 
-#ifdef USE_LOCALE_SUPPORT
+#if defined USE_NL_LANGINFO && defined USE_NL_LANGINFO_WC
   if (info->group)
     {
       if (info->extra == 0)
@@ -269,6 +285,9 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
                thousands_sepwc = nl_langinfo_wc (_NL_NUMERIC_THOUSANDS_SEP_WC);
              else
                thousands_sepwc = nl_langinfo_wc (_NL_MONETARY_THOUSANDS_SEP_WC);
+
+             if (thousands_sepwc == L_('\0'))
+               grouping = NULL;
            }
          else
            {
@@ -276,22 +295,66 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
                thousands_sep = nl_langinfo (THOUSANDS_SEP);
              else
                thousands_sep = nl_langinfo (MON_THOUSANDS_SEP);
+             if (*thousands_sep == '\0')
+               grouping = NULL;
            }
+       }
+    }
+  else
+#elif defined USE_NL_LANGINFO
+  if (info->group && !wide)
+    {
+      if (info->extra == 0)
+       grouping = nl_langinfo (GROUPING);
+      else
+       grouping = nl_langinfo (MON_GROUPING);
+
+      if (*grouping <= 0 || *grouping == CHAR_MAX)
+       grouping = NULL;
+      else
+       {
+         /* Figure out the thousands separator character.  */
+         if (info->extra == 0)
+           thousands_sep = nl_langinfo (THOUSANDS_SEP);
+         else
+           thousands_sep = nl_langinfo (MON_THOUSANDS_SEP);
+
+         if (*thousands_sep == '\0')
+           grouping = NULL;
+       }
+    }
+  else
+#elif defined USE_LOCALECONV
+  if (info->group && !wide)
+    {
+      if (info->extra == 0)
+       grouping = lc->grouping;
+      else
+       grouping = lc->mon_grouping;
+
+      if (grouping == NULL || *grouping <= 0 || *grouping == CHAR_MAX)
+       grouping = NULL;
+      else
+       {
+         /* Figure out the thousands separator character.  */
+         if (info->extra == 0)
+           thousands_sep = lc->thousands_sep;
+         else
+           thousands_sep = lc->mon_thousands_sep;
 
-         if ((wide && thousands_sepwc == L_('\0'))
-             || (! wide && *thousands_sep == '\0'))
+         if (thousands_sep == NULL || *thousands_sep == '\0')
            grouping = NULL;
-         else if (thousands_sepwc == L_('\0'))
-           /* If we are printing multibyte characters and there is a
-              multibyte representation for the thousands separator,
-              we must ensure the wide character thousands separator
-              is available, even if it is fake.  */
-           thousands_sepwc = (wchar_t) 0xfffffffe;
        }
     }
   else
 #endif
     grouping = NULL;
+  if (grouping != NULL && !wide)
+    /* If we are printing multibyte characters and there is a
+       multibyte representation for the thousands separator,
+       we must ensure the wide character thousands separator
+       is available, even if it is fake.  */
+    thousands_sepwc = (wchar_t) 0xfffffffe;
 
   /* Fetch the argument value. */
     {
@@ -1095,8 +1158,8 @@ __quadmath_printf_fp (struct __quadmath_printf_file *fp,
          size_t decimal_len;
          size_t thousands_sep_len;
          wchar_t *copywc;
-#ifdef USE_LOCALE_SUPPORT
-         size_t factor = ((info->i18n && USE_I18N_NUMBER_H)
+#ifdef USE_I18N_NUMBER_H
+         size_t factor = (info->i18n
                           ? nl_langinfo_wc (_NL_CTYPE_MB_CUR_MAX)
                           : 1);
 #else
index 44900f49cc5dfa91400ec4d7cd2ff3cb35d1e7ee..941e93307e06d258c1263774b34c037e400981fc 100644 (file)
@@ -117,25 +117,44 @@ __quadmath_printf_fphex (struct __quadmath_printf_file *fp,
   int wide = info->wide;
 
   /* Figure out the decimal point character.  */
-#ifdef USE_LOCALE_SUPPORT
+#ifdef USE_NL_LANGINFO
   if (info->extra == 0)
-    {
-      decimal = nl_langinfo (DECIMAL_POINT);
-      decimalwc = nl_langinfo_wc (_NL_NUMERIC_DECIMAL_POINT_WC);
-    }
+    decimal = nl_langinfo (DECIMAL_POINT);
   else
     {
       decimal = nl_langinfo (MON_DECIMAL_POINT);
       if (*decimal == '\0')
        decimal = nl_langinfo (DECIMAL_POINT);
+    }
+  /* The decimal point character must never be zero.  */
+  assert (*decimal != '\0');
+#elif defined USE_LOCALECONV
+  const struct lconv *lc = localeconv ();
+  if (info->extra == 0)
+    decimal = lc->decimal_point;
+  else
+    {
+      decimal = lc->mon_decimal_point;
+      if (decimal == NULL || *decimal == '\0')
+       decimal = lc->decimal_point;
+    }
+  if (decimal == NULL || *decimal == '\0')
+    decimal = ".";
+#else
+  decimal = ".";
+#endif
+#ifdef USE_NL_LANGINFO_WC
+  if (info->extra == 0)
+    decimalwc = nl_langinfo_wc (_NL_NUMERIC_DECIMAL_POINT_WC);
+  else
+    {
       decimalwc = nl_langinfo_wc (_NL_MONETARY_DECIMAL_POINT_WC);
-      if (decimalwc == L'\0')
+      if (decimalwc == L_('\0'))
        decimalwc = nl_langinfo_wc (_NL_NUMERIC_DECIMAL_POINT_WC);
     }
   /* The decimal point character must never be zero.  */
-  assert (*decimal != '\0' && decimalwc != L'\0');
+  assert (decimalwc != L_('\0'));
 #else
-  decimal = ".";
   decimalwc = L_('.');
 #endif
 
index 4f5305edee4cedb2e3a18e74c4584ab43b32d9f0..750dc246fcc885e0842041743d757a7ab109322c 100644 (file)
@@ -292,7 +292,7 @@ flt128_ais (const struct printf_info *info, size_t n __attribute__ ((unused)),
       size[0] = sizeof (__float128);
       return 1;
     }
-#if __GLIBC_MINOR__ <= 13
+#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 13)
   /* Workaround bug in glibc printf hook handling.  */
   size[0] = -1;
   switch (info->spec)
index 796df200027db495855a4ca9bf5b15abd53511b0..05fed7aaf078322ae83171bdb575ff492ad7f269 100644 (file)
@@ -38,6 +38,9 @@ Boston, MA 02110-1301, USA.  */
 #ifdef HAVE_PRINTF_HOOKS
 #include <printf.h>
 #endif
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
 #include "quadmath-imp.h"
 #include "gmp-impl.h"