diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 69b390267ac..f1c463207ae 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,16 @@ +2006-06-12 Paolo Carlini + + 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. + 2006-06-09 Paolo Carlini * include/tr1/random (random_device::random_device(const diff --git a/libstdc++-v3/config/locale/generic/c_locale.h b/libstdc++-v3/config/locale/generic/c_locale.h index d6e2f65e06e..d71af1d0a16 100644 --- a/libstdc++-v3/config/locale/generic/c_locale.h +++ b/libstdc++-v3/config/locale/generic/c_locale.h @@ -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 #include // get std::strlen -#include // get std::snprintf or std::sprintf +#include // get std::vsnprintf or std::vsprintf +#include #define _GLIBCXX_NUM_CATEGORIES 0 @@ -48,39 +50,42 @@ _GLIBCXX_BEGIN_NAMESPACE(std) 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 - 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 double and 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(const __c_locale&, char* __out, + const int __size __attribute__((__unused__)), + 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 + + va_end(__args); - 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 diff --git a/libstdc++-v3/config/locale/gnu/c_locale.h b/libstdc++-v3/config/locale/gnu/c_locale.h index 55e160e1b9b..c5a301f9aaa 100644 --- a/libstdc++-v3/config/locale/gnu/c_locale.h +++ b/libstdc++-v3/config/locale/gnu/c_locale.h @@ -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 @@ -39,11 +40,12 @@ #pragma GCC system_header #include // get std::strlen -#include // get std::snprintf or std::sprintf +#include // get std::vsnprintf or std::vsprintf #include #include // For codecvt #include // For codecvt using iconv, iconv_t #include // For messages +#include #define _GLIBCXX_C_LOCALE_GNU 1 @@ -61,42 +63,44 @@ _GLIBCXX_BEGIN_NAMESPACE(std) 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 - int - __convert_from_v(char* __out, - const int __size __attribute__ ((__unused__)), - const char* __fmt, + // Convert numeric value of type double and 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(const __c_locale& __cloc __attribute__ ((__unused__)), + char* __out, + const int __size __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 + va_end(__args); + #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 diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index bfe6fc7f419..485851ecb4d 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -1135,7 +1135,7 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE __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 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE char* __cs = static_cast(__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(_S_get_c_locale(), __cs, __cs_size, + __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(__builtin_alloca(__cs_size)); - __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v, - _S_get_c_locale(), __prec); + __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, + __fbuf, __prec, __v); } #else // Consider the possibility of long ios_base::fixed outputs @@ -1203,8 +1203,8 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE char* __cs = static_cast(__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(_S_get_c_locale(), __cs, 0, __fbuf, + __prec, __v); #endif // [22.2.2.2.2] Stage 2, convert to char_type, using correct @@ -1834,22 +1834,22 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE char* __cs = static_cast(__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(_S_get_c_locale(), __cs, __cs_size, + "%.*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(__builtin_alloca(__cs_size)); - __len = std::__convert_from_v(__cs, __cs_size, "%.*Lf", __units, - _S_get_c_locale(), 0); + __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, + "%.*Lf", 0, __units); } #else // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'. const int __cs_size = numeric_limits::max_exponent10 + 3; char* __cs = static_cast(__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(_S_get_c_locale(), __cs, 0, "%.*Lf", + 0, __units); #endif _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __cs_size)); diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am index b3ada6aeddb..d54b71ecdac 100644 --- a/libstdc++-v3/src/Makefile.am +++ b/libstdc++-v3/src/Makefile.am @@ -162,7 +162,6 @@ sources = \ istream-inst.cc \ istream.cc \ locale-inst.cc \ - locale-misc-inst.cc \ misc-inst.cc \ ostream-inst.cc \ sstream-inst.cc \ diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in index c6e412e3c53..053ebc602ac 100644 --- a/libstdc++-v3/src/Makefile.in +++ b/libstdc++-v3/src/Makefile.in @@ -67,9 +67,9 @@ am__libstdc___la_SOURCES_DIST = bitmap_allocator.cc pool_allocator.cc \ locale_init.cc locale_facets.cc localename.cc stdexcept.cc \ strstream.cc tree.cc allocator-inst.cc concept-inst.cc \ fstream-inst.cc ext-inst.cc ios-inst.cc iostream-inst.cc \ - istream-inst.cc istream.cc locale-inst.cc locale-misc-inst.cc \ - misc-inst.cc ostream-inst.cc sstream-inst.cc streambuf-inst.cc \ - streambuf.cc string-inst.cc valarray-inst.cc wlocale-inst.cc \ + istream-inst.cc istream.cc locale-inst.cc misc-inst.cc \ + ostream-inst.cc sstream-inst.cc streambuf-inst.cc streambuf.cc \ + string-inst.cc valarray-inst.cc wlocale-inst.cc \ wstring-inst.cc atomicity.cc codecvt_members.cc \ collate_members.cc ctype_members.cc messages_members.cc \ monetary_members.cc numeric_members.cc time_members.cc \ @@ -87,11 +87,10 @@ am__objects_4 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \ localename.lo stdexcept.lo strstream.lo tree.lo \ allocator-inst.lo concept-inst.lo fstream-inst.lo ext-inst.lo \ ios-inst.lo iostream-inst.lo istream-inst.lo istream.lo \ - locale-inst.lo locale-misc-inst.lo misc-inst.lo \ - ostream-inst.lo sstream-inst.lo streambuf-inst.lo streambuf.lo \ - string-inst.lo valarray-inst.lo wlocale-inst.lo \ - wstring-inst.lo $(am__objects_1) $(am__objects_2) \ - $(am__objects_3) + locale-inst.lo misc-inst.lo ostream-inst.lo sstream-inst.lo \ + streambuf-inst.lo streambuf.lo string-inst.lo valarray-inst.lo \ + wlocale-inst.lo wstring-inst.lo $(am__objects_1) \ + $(am__objects_2) $(am__objects_3) am_libstdc___la_OBJECTS = $(am__objects_4) libstdc___la_OBJECTS = $(am_libstdc___la_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) @@ -366,7 +365,6 @@ sources = \ istream-inst.cc \ istream.cc \ locale-inst.cc \ - locale-misc-inst.cc \ misc-inst.cc \ ostream-inst.cc \ sstream-inst.cc \ diff --git a/libstdc++-v3/src/locale-misc-inst.cc b/libstdc++-v3/src/locale-misc-inst.cc deleted file mode 100644 index 8af73596a6b..00000000000 --- a/libstdc++-v3/src/locale-misc-inst.cc +++ /dev/null @@ -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 - -_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