This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch] libstdc++/26970
- From: Paolo Carlini <pcarlini at suse dot de>
- To: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Cc: Jakub Jelinek <jakub at redhat dot com>
- Date: Sun, 11 Jun 2006 21:40:50 +0200
- Subject: [Patch] libstdc++/26970
Hi,
the below started noticing that __convert_from_v was not exported and
that -Wformat-nonliteral is happy with variadic functions. Overall, in
my opinion the code is not less clean than before...
I would ask Benjamin and Jakub to help me double checking that
everything is still fine wrt long double on powerpc... I will wait until
tomorrow, in any case.
Tested x86-linux, --enable-clocale=generic too.
Paolo.
////////////////////
||
2006-06-12 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/26970
* config/locale/gnu/c_locale.h (__convert_from_v<>): Change to
variadic function, instead of template function.
* config/locale/generic/c_locale.h (__convert_from_v<>): Likewise.
* include/bits/locale_facets.tcc (num_put<>::_M_insert_float):
Adjust.
(money_put<>::do_put(long double)): Likewise.
* src/locale-misc-inst.cc: Remove.
* src/Makefile.am: Adjust.
* src/Makefile.in: Regenerate.
Index: include/bits/locale_facets.tcc
===================================================================
--- include/bits/locale_facets.tcc (revision 114548)
+++ include/bits/locale_facets.tcc (working copy)
@@ -1135,7 +1135,7 @@
__len = __newlen;
}
- // The following code uses snprintf (or sprintf(), when
+ // The following code uses vsnprintf (or vsprintf(), when
// _GLIBCXX_USE_C99 is not defined) to convert floating point values
// for insertion into a stream. An optimization would be to replace
// them with code that works directly on a wide buffer and then use
@@ -1176,16 +1176,16 @@
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
__num_base::_S_format_float(__io, __fbuf, __mod);
- __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v,
- _S_get_c_locale(), __prec);
+ __len = std::__convert_from_v(__cs, __cs_size, _S_get_c_locale(),
+ __fbuf, __prec, __v);
// If the buffer was not large enough, try again with the correct size.
if (__len >= __cs_size)
{
__cs_size = __len + 1;
__cs = static_cast<char*>(__builtin_alloca(__cs_size));
- __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v,
- _S_get_c_locale(), __prec);
+ __len = std::__convert_from_v(__cs, __cs_size, _S_get_c_locale(),
+ __fbuf, __prec, __v);
}
#else
// Consider the possibility of long ios_base::fixed outputs
@@ -1203,8 +1203,8 @@
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
__num_base::_S_format_float(__io, __fbuf, __mod);
- __len = std::__convert_from_v(__cs, 0, __fbuf, __v,
- _S_get_c_locale(), __prec);
+ __len = std::__convert_from_v(__cs, 0, _S_get_c_locale(), __fbuf,
+ __prec, __v);
#endif
// [22.2.2.2.2] Stage 2, convert to char_type, using correct
@@ -1834,22 +1834,22 @@
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 328. Bad sprintf format modifier in money_put<>::do_put()
- int __len = std::__convert_from_v(__cs, __cs_size, "%.*Lf", __units,
- _S_get_c_locale(), 0);
+ int __len = std::__convert_from_v(__cs, __cs_size, _S_get_c_locale(),
+ "%.*Lf", 0, __units);
// If the buffer was not large enough, try again with the correct size.
if (__len >= __cs_size)
{
__cs_size = __len + 1;
__cs = static_cast<char*>(__builtin_alloca(__cs_size));
- __len = std::__convert_from_v(__cs, __cs_size, "%.*Lf", __units,
- _S_get_c_locale(), 0);
+ __len = std::__convert_from_v(__cs, __cs_size, _S_get_c_locale(),
+ "%.*Lf", 0, __units);
}
#else
// max_exponent10 + 1 for the integer part, + 2 for sign and '\0'.
const int __cs_size = numeric_limits<long double>::max_exponent10 + 3;
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
- int __len = std::__convert_from_v(__cs, 0, "%.*Lf", __units,
- _S_get_c_locale(), 0);
+ int __len = std::__convert_from_v(__cs, 0, __get_c_locale(), "%.*Lf",
+ 0, __units);
#endif
_CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
* __cs_size));
Index: src/locale-misc-inst.cc
===================================================================
--- src/locale-misc-inst.cc (revision 114548)
+++ src/locale-misc-inst.cc (working copy)
@@ -1,65 +0,0 @@
-// Locale support -*- C++ -*-
-
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006
-// Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction. Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License. This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
-
-//
-// ISO C++ 14882: 22.1 Locales
-//
-
-#include <locale>
-
-_GLIBCXX_BEGIN_NAMESPACE(std)
-
- template
- int
- __convert_from_v(char*, const int, const char*, double,
- const __c_locale&, int);
-
- template
- int
- __convert_from_v(char*, const int, const char*, long double,
- const __c_locale&, int);
-
-_GLIBCXX_END_NAMESPACE
-
-// XXX GLIBCXX_ABI Deprecated
-#if defined _GLIBCXX_LONG_DOUBLE_COMPAT
-
-#define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \
- extern "C" void ldbl (void) __attribute__ ((alias (#dbl), weak))
-
-# if _GLIBCXX_C_LOCALE_GNU
-_GLIBCXX_LDBL_COMPAT(_ZSt16__convert_from_vIdEiPciPKcT_RKP15__locale_structi,
- _ZSt16__convert_from_vIeEiPciPKcT_RKP15__locale_structi);
-# else
-_GLIBCXX_LDBL_COMPAT(_ZSt16__convert_from_vIdEiPciPKcT_RKPii,
- _ZSt16__convert_from_vIeEiPciPKcT_RKPii);
-# endif
-
-#endif // _GLIBCXX_LONG_DOUBLE_COMPAT
Index: src/Makefile.am
===================================================================
--- src/Makefile.am (revision 114548)
+++ src/Makefile.am (working copy)
@@ -162,7 +162,6 @@
istream-inst.cc \
istream.cc \
locale-inst.cc \
- locale-misc-inst.cc \
misc-inst.cc \
ostream-inst.cc \
sstream-inst.cc \
Index: config/locale/gnu/c_locale.h
===================================================================
--- config/locale/gnu/c_locale.h (revision 114548)
+++ config/locale/gnu/c_locale.h (working copy)
@@ -1,6 +1,7 @@
// Wrapper for underlying C-language localization -*- C++ -*-
-// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -44,6 +45,7 @@
#include <langinfo.h> // For codecvt
#include <iconv.h> // For codecvt using iconv, iconv_t
#include <libintl.h> // For messages
+#include <cstdarg>
#define _GLIBCXX_C_LOCALE_GNU 1
@@ -61,42 +63,42 @@
typedef __locale_t __c_locale;
- // Convert numeric value of type _Tv to string and return length of
- // string. If snprintf is available use it, otherwise fall back to
- // the unsafe sprintf which, in general, can be dangerous and should
- // be avoided.
- template<typename _Tv>
- int
- __convert_from_v(char* __out,
- const int __size __attribute__ ((__unused__)),
- const char* __fmt,
+ // Convert numeric value of type float/double/long double to string and
+ // return length of string. If vsnprintf is available use it, otherwise
+ // fall back to the unsafe vsprintf which, in general, can be dangerous
+ // and should be avoided.
+ inline int
+ __convert_from_v(char* __out,
+ const int __size __attribute__ ((__unused__)),
+ const __c_locale& __cloc __attribute__ ((__unused__)),
+ const char* __fmt, ...)
+ {
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
- _Tv __v, const __c_locale& __cloc, int __prec)
- {
- __c_locale __old = __gnu_cxx::__uselocale(__cloc);
+ __c_locale __old = __gnu_cxx::__uselocale(__cloc);
#else
- _Tv __v, const __c_locale&, int __prec)
- {
- char* __old = std::setlocale(LC_ALL, NULL);
- char* __sav = new char[std::strlen(__old) + 1];
- std::strcpy(__sav, __old);
- std::setlocale(LC_ALL, "C");
+ char* __old = std::setlocale(LC_ALL, NULL);
+ char* __sav = new char[std::strlen(__old) + 1];
+ std::strcpy(__sav, __old);
+ std::setlocale(LC_ALL, "C");
#endif
+ va_list __args;
+ va_start(__args, __fmt);
+
#ifdef _GLIBCXX_USE_C99
- const int __ret = std::snprintf(__out, __size, __fmt, __prec, __v);
+ const int __ret = std::vsnprintf(__out, __size, __fmt, __args);
#else
- const int __ret = std::sprintf(__out, __fmt, __prec, __v);
+ const int __ret = std::vsprintf(__out, __fmt, __args);
#endif
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
- __gnu_cxx::__uselocale(__old);
+ __gnu_cxx::__uselocale(__old);
#else
- std::setlocale(LC_ALL, __sav);
- delete [] __sav;
+ std::setlocale(LC_ALL, __sav);
+ delete [] __sav;
#endif
- return __ret;
- }
+ return __ret;
+ }
_GLIBCXX_END_NAMESPACE
Index: config/locale/generic/c_locale.h
===================================================================
--- config/locale/generic/c_locale.h (revision 114548)
+++ config/locale/generic/c_locale.h (working copy)
@@ -1,6 +1,7 @@
// Wrapper for underlying C-language localization -*- C++ -*-
-// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -40,7 +41,8 @@
#include <clocale>
#include <cstring> // get std::strlen
-#include <cstdio> // get std::snprintf or std::sprintf
+#include <cstdio> // get std::vsnprintf or std::vsprintf
+#include <cstdarg>
#define _GLIBCXX_NUM_CATEGORIES 0
@@ -48,39 +50,40 @@
typedef int* __c_locale;
- // Convert numeric value of type _Tv to string and return length of
- // string. If snprintf is available use it, otherwise fall back to
- // the unsafe sprintf which, in general, can be dangerous and should
- // be avoided.
- template<typename _Tv>
- int
- __convert_from_v(char* __out,
- const int __size __attribute__((__unused__)),
- const char* __fmt,
- _Tv __v, const __c_locale&, int __prec)
- {
- char* __old = std::setlocale(LC_NUMERIC, NULL);
- char* __sav = NULL;
- if (std::strcmp(__old, "C"))
- {
- __sav = new char[std::strlen(__old) + 1];
- std::strcpy(__sav, __old);
- std::setlocale(LC_NUMERIC, "C");
- }
+ // Convert numeric value of type float/double/long double to string and
+ // return length of string. If vsnprintf is available use it, otherwise
+ // fall back to the unsafe vsprintf which, in general, can be dangerous
+ // and should be avoided.
+ inline int
+ __convert_from_v(char* __out,
+ const int __size __attribute__((__unused__)),
+ const __c_locale&, const char* __fmt, ...)
+ {
+ char* __old = std::setlocale(LC_NUMERIC, NULL);
+ char* __sav = NULL;
+ if (std::strcmp(__old, "C"))
+ {
+ __sav = new char[std::strlen(__old) + 1];
+ std::strcpy(__sav, __old);
+ std::setlocale(LC_NUMERIC, "C");
+ }
+ va_list __args;
+ va_start(__args, __fmt);
+
#ifdef _GLIBCXX_USE_C99
- const int __ret = std::snprintf(__out, __size, __fmt, __prec, __v);
+ const int __ret = std::vsnprintf(__out, __size, __fmt, __args);
#else
- const int __ret = std::sprintf(__out, __fmt, __prec, __v);
+ const int __ret = std::vsprintf(__out, __fmt, __args);
#endif
- if (__sav)
- {
- std::setlocale(LC_NUMERIC, __sav);
- delete [] __sav;
- }
- return __ret;
- }
+ if (__sav)
+ {
+ std::setlocale(LC_NUMERIC, __sav);
+ delete [] __sav;
+ }
+ return __ret;
+ }
_GLIBCXX_END_NAMESPACE