mirror of git://gcc.gnu.org/git/gcc.git
locale-inst.cc (__convert_from_v): Add an additional __size parameter in the declarations.
2002-03-19 Paolo Carlini <pcarlini@unitus.it> Ulrich Drepper <drepper@redhat.com> * src/locale-inst.cc (__convert_from_v): Add an additional __size parameter in the declarations. * include/bits/locale_facets.tcc (__convert_from_v): When available (that is, _GLIBCPP_USE_C99 defined) use snprintf instead of sprintf. (num_put::_M_convert_float): Depending on _GLIBCPP_USE_C99 being defined or not, call and use __convert_from_v in the appropriate way. (num_put::_M_convert_int): Same here. (money_put::do_put(long double)): Same here. Co-Authored-By: Ulrich Drepper <drepper@redhat.com> From-SVN: r51050
This commit is contained in:
parent
1e82682ba4
commit
6d8e16a463
|
|
@ -1,3 +1,17 @@
|
||||||
|
2002-03-19 Paolo Carlini <pcarlini@unitus.it>
|
||||||
|
Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* src/locale-inst.cc (__convert_from_v): Add an additional
|
||||||
|
__size parameter in the declarations.
|
||||||
|
* include/bits/locale_facets.tcc
|
||||||
|
(__convert_from_v): When available (that is,
|
||||||
|
_GLIBCPP_USE_C99 defined) use snprintf instead of sprintf.
|
||||||
|
(num_put::_M_convert_float): Depending on _GLIBCPP_USE_C99
|
||||||
|
being defined or not, call and use __convert_from_v in the
|
||||||
|
appropriate way.
|
||||||
|
(num_put::_M_convert_int): Same here.
|
||||||
|
(money_put::do_put(long double)): Same here.
|
||||||
|
|
||||||
2002-03-19 Phil Edwards <pme@gcc.gnu.org>
|
2002-03-19 Phil Edwards <pme@gcc.gnu.org>
|
||||||
|
|
||||||
* docs/html/faq/index.html (#3.6): Rewrap and close <a href> tags.
|
* docs/html/faq/index.html (#3.6): Rewrap and close <a href> tags.
|
||||||
|
|
|
||||||
|
|
@ -592,16 +592,15 @@ namespace std
|
||||||
return __beg;
|
return __beg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The following code uses snprintf (or sprintf(), when _GLIBCPP_USE_C99
|
||||||
// The following code uses sprintf() to convert floating point
|
// is not defined) to convert floating point values for insertion into a
|
||||||
// values for insertion into a stream. An optimization would be to
|
// stream. An optimization would be to replace them with code that works
|
||||||
// replace sprintf() with code that works directly on a wide buffer
|
// directly on a wide buffer and then use __pad to do the padding.
|
||||||
// and then use __pad to do the padding. It would be good
|
// It would be good to replace them anyway to gain back the efficiency
|
||||||
// to replace sprintf() anyway to avoid accidental buffer overruns
|
// that C++ provides by knowing up front the type of the values to insert.
|
||||||
// and to gain back the efficiency that C++ provides by knowing up
|
// Also, sprintf is dangerous since may lead to accidental buffer overruns.
|
||||||
// front the type of the values to insert. This implementation
|
// This implementation follows the C++ standard fairly directly as
|
||||||
// follows the C++ standard fairly directly as outlined in 22.2.2.2
|
// outlined in 22.2.2.2 [lib.locale.num.put]
|
||||||
// [lib.locale.num.put]
|
|
||||||
template<typename _CharT, typename _OutIter>
|
template<typename _CharT, typename _OutIter>
|
||||||
template<typename _ValueT>
|
template<typename _ValueT>
|
||||||
_OutIter
|
_OutIter
|
||||||
|
|
@ -613,13 +612,38 @@ namespace std
|
||||||
// we get the full available precision.
|
// we get the full available precision.
|
||||||
const int __max_digits = numeric_limits<_ValueT>::digits10 + 1;
|
const int __max_digits = numeric_limits<_ValueT>::digits10 + 1;
|
||||||
streamsize __prec = __io.precision();
|
streamsize __prec = __io.precision();
|
||||||
// Protect against sprintf() buffer overflows.
|
|
||||||
if (__prec > static_cast<streamsize>(__max_digits))
|
if (__prec > static_cast<streamsize>(__max_digits))
|
||||||
__prec = static_cast<streamsize>(__max_digits);
|
__prec = static_cast<streamsize>(__max_digits);
|
||||||
|
|
||||||
// Long enough for the max format spec.
|
// Long enough for the max format spec.
|
||||||
char __fbuf[16];
|
char __fbuf[16];
|
||||||
|
|
||||||
|
// [22.2.2.2.2] Stage 1, numeric conversion to character.
|
||||||
|
int __len;
|
||||||
|
#ifdef _GLIBCPP_USE_C99
|
||||||
|
// First try a buffer perhaps big enough (for sure sufficient for
|
||||||
|
// non-ios_base::fixed outputs)
|
||||||
|
int __cs_size = __max_digits * 3;
|
||||||
|
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
|
||||||
|
|
||||||
|
const bool __fp = _S_format_float(__io, __fbuf, __mod, __prec);
|
||||||
|
if (__fp)
|
||||||
|
__len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale, __prec);
|
||||||
|
else
|
||||||
|
__len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale);
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
if (__fp)
|
||||||
|
__len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale, __prec);
|
||||||
|
else
|
||||||
|
__len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale);
|
||||||
|
}
|
||||||
|
#else
|
||||||
// Consider the possibility of long ios_base::fixed outputs
|
// Consider the possibility of long ios_base::fixed outputs
|
||||||
const bool __fixed = __io.flags() & ios_base::fixed;
|
const bool __fixed = __io.flags() & ios_base::fixed;
|
||||||
const int __max_exp = numeric_limits<_ValueT>::max_exponent10;
|
const int __max_exp = numeric_limits<_ValueT>::max_exponent10;
|
||||||
|
|
@ -632,12 +656,11 @@ namespace std
|
||||||
: __max_digits * 3;
|
: __max_digits * 3;
|
||||||
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
|
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
|
||||||
|
|
||||||
int __len;
|
|
||||||
// [22.2.2.2.2] Stage 1, numeric conversion to character.
|
|
||||||
if (_S_format_float(__io, __fbuf, __mod, __prec))
|
if (_S_format_float(__io, __fbuf, __mod, __prec))
|
||||||
__len = __convert_from_v(__cs, __fbuf, __v, _S_c_locale, __prec);
|
__len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale, __prec);
|
||||||
else
|
else
|
||||||
__len = __convert_from_v(__cs, __fbuf, __v, _S_c_locale);
|
__len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale);
|
||||||
|
#endif
|
||||||
return _M_widen_float(__s, __io, __fill, __cs, __len);
|
return _M_widen_float(__s, __io, __fill, __cs, __len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -649,13 +672,28 @@ namespace std
|
||||||
char __modl, _ValueT __v) const
|
char __modl, _ValueT __v) const
|
||||||
{
|
{
|
||||||
// [22.2.2.2.2] Stage 1, numeric conversion to character.
|
// [22.2.2.2.2] Stage 1, numeric conversion to character.
|
||||||
// Leave room for "+/-," "0x," and commas. This size is
|
|
||||||
// arbitrary, but should work.
|
|
||||||
char __cs[64];
|
|
||||||
// Long enough for the max format spec.
|
// Long enough for the max format spec.
|
||||||
char __fbuf[16];
|
char __fbuf[16];
|
||||||
_S_format_int(__io, __fbuf, __mod, __modl);
|
_S_format_int(__io, __fbuf, __mod, __modl);
|
||||||
int __len = __convert_from_v(__cs, __fbuf, __v, _S_c_locale);
|
#ifdef _GLIBCPP_USE_C99
|
||||||
|
// First try a buffer perhaps big enough.
|
||||||
|
int __cs_size = 64;
|
||||||
|
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
|
||||||
|
int __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale);
|
||||||
|
// 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 = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Leave room for "+/-," "0x," and commas. This size is
|
||||||
|
// arbitrary, but should be largely sufficient.
|
||||||
|
char __cs[128];
|
||||||
|
int __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale);
|
||||||
|
#endif
|
||||||
return _M_widen_int(__s, __io, __fill, __cs, __len);
|
return _M_widen_int(__s, __io, __fill, __cs, __len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1111,12 +1149,26 @@ namespace std
|
||||||
{
|
{
|
||||||
const locale __loc = __io.getloc();
|
const locale __loc = __io.getloc();
|
||||||
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
|
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
|
||||||
|
#ifdef _GLIBCPP_USE_C99
|
||||||
|
// First try a buffer perhaps big enough.
|
||||||
|
int __cs_size = 64;
|
||||||
|
char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __cs_size));
|
||||||
|
int __len = __convert_from_v(__cs, __cs_size, "%.01Lf", __units, _S_c_locale);
|
||||||
|
// 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(sizeof(char) * __cs_size));
|
||||||
|
__len = __convert_from_v(__cs, __cs_size, "%.01Lf", __units, _S_c_locale);
|
||||||
|
}
|
||||||
|
#else
|
||||||
// max_exponent10 + 1 for the integer part, + 4 for sign, decimal point,
|
// max_exponent10 + 1 for the integer part, + 4 for sign, decimal point,
|
||||||
// decimal digit, '\0'.
|
// decimal digit, '\0'.
|
||||||
const int __n = numeric_limits<long double>::max_exponent10 + 5;
|
const int __cs_size = numeric_limits<long double>::max_exponent10 + 5;
|
||||||
char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __n));
|
char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __cs_size));
|
||||||
_CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
|
int __len = __convert_from_v(__cs, 0, "%.01Lf", __units, _S_c_locale);
|
||||||
int __len = __convert_from_v(__cs, "%.01Lf", __units, _S_c_locale);
|
#endif
|
||||||
|
_CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __cs_size));
|
||||||
__ctype.widen(__cs, __cs + __len, __ws);
|
__ctype.widen(__cs, __cs + __len, __ws);
|
||||||
string_type __digits(__ws);
|
string_type __digits(__ws);
|
||||||
return this->do_put(__s, __intl, __io, __fill, __digits);
|
return this->do_put(__s, __intl, __io, __fill, __digits);
|
||||||
|
|
@ -1894,20 +1946,39 @@ namespace std
|
||||||
const __c_locale& __cloc, int __base = 10);
|
const __c_locale& __cloc, int __base = 10);
|
||||||
|
|
||||||
// Convert numeric value of type _Tv to string and return length of string.
|
// 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.
|
||||||
|
#ifdef _GLIBCPP_USE_C99
|
||||||
template<typename _Tv>
|
template<typename _Tv>
|
||||||
int
|
int
|
||||||
__convert_from_v(char* __out, const char* __fmt, _Tv __v,
|
__convert_from_v(char* __out, const int __size, const char* __fmt,
|
||||||
|
_Tv __v, const __c_locale&, int __prec = -1)
|
||||||
|
{
|
||||||
|
int __ret;
|
||||||
|
const char* __old = setlocale(LC_ALL, "C");
|
||||||
|
if (__prec >= 0)
|
||||||
|
__ret = snprintf(__out, __size, __fmt, __prec, __v);
|
||||||
|
else
|
||||||
|
__ret = snprintf(__out, __size, __fmt, __v);
|
||||||
|
setlocale(LC_ALL, __old);
|
||||||
|
return __ret;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template<typename _Tv>
|
||||||
|
int
|
||||||
|
__convert_from_v(char* __out, const int, const char* __fmt, _Tv __v,
|
||||||
const __c_locale&, int __prec = -1)
|
const __c_locale&, int __prec = -1)
|
||||||
{
|
{
|
||||||
int __ret;
|
int __ret;
|
||||||
const char* __old = setlocale(LC_ALL, "C");
|
const char* __old = setlocale(LC_ALL, "C");
|
||||||
if (__prec >= 0)
|
if (__prec >= 0)
|
||||||
__ret = sprintf(__out, __fmt, __prec, __v);
|
__ret = sprintf(__out, __fmt, __prec, __v);
|
||||||
else
|
else
|
||||||
__ret = sprintf(__out, __fmt, __v);
|
__ret = sprintf(__out, __fmt, __v);
|
||||||
setlocale(LC_ALL, __old);
|
setlocale(LC_ALL, __old);
|
||||||
return __ret;
|
return __ret;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Construct correctly padded string, as per 22.2.2.2.2
|
// Construct correctly padded string, as per 22.2.2.2.2
|
||||||
// Assumes
|
// Assumes
|
||||||
|
|
|
||||||
|
|
@ -461,28 +461,28 @@ namespace std
|
||||||
|
|
||||||
template
|
template
|
||||||
int
|
int
|
||||||
__convert_from_v(char*, const char*, double, const __c_locale&, int);
|
__convert_from_v(char*, const int, const char*, double, const __c_locale&, int);
|
||||||
|
|
||||||
template
|
template
|
||||||
int
|
int
|
||||||
__convert_from_v(char*, const char*, long double, const __c_locale&, int);
|
__convert_from_v(char*, const int, const char*, long double, const __c_locale&, int);
|
||||||
|
|
||||||
template
|
template
|
||||||
int
|
int
|
||||||
__convert_from_v(char*, const char*, long, const __c_locale&, int);
|
__convert_from_v(char*, const int, const char*, long, const __c_locale&, int);
|
||||||
|
|
||||||
template
|
template
|
||||||
int
|
int
|
||||||
__convert_from_v(char*, const char*, unsigned long,
|
__convert_from_v(char*, const int, const char*, unsigned long,
|
||||||
const __c_locale&, int);
|
const __c_locale&, int);
|
||||||
|
|
||||||
template
|
template
|
||||||
int
|
int
|
||||||
__convert_from_v(char*, const char*, long long, const __c_locale&, int);
|
__convert_from_v(char*, const int, const char*, long long, const __c_locale&, int);
|
||||||
|
|
||||||
template
|
template
|
||||||
int
|
int
|
||||||
__convert_from_v(char*, const char*, unsigned long long,
|
__convert_from_v(char*, const int, const char*, unsigned long long,
|
||||||
const __c_locale&, int);
|
const __c_locale&, int);
|
||||||
|
|
||||||
template
|
template
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue