mirror of
https://gcc.gnu.org/git/gcc.git
synced 2025-01-26 14:24:18 +08:00
re PR libstdc++/38081 (time_get<>::do_get_weekday does not always recognize full names of weekdays)
2010-01-05 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/38081 * include/bits/locale_facets_nonio.h (time_get<>:: _M_extract_wday_or_month): New, declare. * include/bits/locale_facets_nonio.tcc (time_get<>:: _M_extract_wday_or_month): Define. (time_get<>::do_get_weekday, time_get<>::do_get_monthname): Use it. * config/abi/pre/gnu.ver: Export new symbols. * doc/xml/manual/prerequisites.xml: Add ru_RU.UTF-8 and ru_RU.ISO-8859-5. * testsuite/lib/libstdc++.exp: Adjust. * testsuite/22_locale/time_get/get_weekday/char/38081-1.cc: New. * testsuite/22_locale/time_get/get_weekday/char/38081-2.cc: Likewise. From-SVN: r155659
This commit is contained in:
parent
9bf4cdf575
commit
ac2bb43770
@ -1,3 +1,18 @@
|
||||
2010-01-05 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR libstdc++/38081
|
||||
* include/bits/locale_facets_nonio.h (time_get<>::
|
||||
_M_extract_wday_or_month): New, declare.
|
||||
* include/bits/locale_facets_nonio.tcc (time_get<>::
|
||||
_M_extract_wday_or_month): Define.
|
||||
(time_get<>::do_get_weekday, time_get<>::do_get_monthname): Use it.
|
||||
* config/abi/pre/gnu.ver: Export new symbols.
|
||||
* doc/xml/manual/prerequisites.xml: Add ru_RU.UTF-8 and
|
||||
ru_RU.ISO-8859-5.
|
||||
* testsuite/lib/libstdc++.exp: Adjust.
|
||||
* testsuite/22_locale/time_get/get_weekday/char/38081-1.cc: New.
|
||||
* testsuite/22_locale/time_get/get_weekday/char/38081-2.cc: Likewise.
|
||||
|
||||
2010-01-05 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
* configure: Regenerate.
|
||||
|
@ -1,6 +1,6 @@
|
||||
## Linker script for GNU versioning (GNU ld 2.13.91+ only.)
|
||||
##
|
||||
## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
||||
## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||
## Free Software Foundation, Inc.
|
||||
##
|
||||
## This file is part of the GNU ISO C++ Library. This library is free
|
||||
@ -149,7 +149,7 @@ GLIBCXX_3.4 {
|
||||
std::th[a-h]*;
|
||||
std::th[j-q]*;
|
||||
std::th[s-z]*;
|
||||
std::t[i-n]*;
|
||||
# std::t[i-n]*;
|
||||
std::tr1::h[^a]*;
|
||||
std::t[s-z]*;
|
||||
# std::[A-Zu-z]*;
|
||||
@ -459,6 +459,21 @@ GLIBCXX_3.4 {
|
||||
# std::money_put
|
||||
_ZNKSt9money_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEE*;
|
||||
|
||||
# std::time_get
|
||||
_ZNSt8time_get*;
|
||||
_ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE[0-9]*;
|
||||
_ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE1[0-9]*;
|
||||
|
||||
# std::time_get_byname
|
||||
_ZNSt15time_get_byname*;
|
||||
|
||||
# std::time_put
|
||||
_ZNSt8time_put*;
|
||||
_ZNKSt8time_put*;
|
||||
|
||||
# std::time_put_byname
|
||||
_ZNSt15time_put_byname*;
|
||||
|
||||
# std::numeric_limits
|
||||
_ZNSt14numeric_limitsI[^g]E*;
|
||||
|
||||
@ -1081,6 +1096,9 @@ GLIBCXX_3.4.14 {
|
||||
|
||||
_ZSt25__throw_bad_function_callv;
|
||||
|
||||
# std::time_get::_M_extract_wday_or_month
|
||||
_ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE24_M_extract_wday_or_month*;
|
||||
|
||||
} GLIBCXX_3.4.13;
|
||||
|
||||
# Symbols in the support library (libsupc++) have their own tag.
|
||||
|
@ -86,6 +86,8 @@ fr_FR@euro ISO-8859-15
|
||||
is_IS UTF-8
|
||||
it_IT ISO-8859-1
|
||||
ja_JP.eucjp EUC-JP
|
||||
ru_RU.ISO-8859-5 ISO-8859-5
|
||||
ru_RU.UTF-8 UTF-8
|
||||
se_NO.UTF-8 UTF-8
|
||||
ta_IN UTF-8
|
||||
zh_TW BIG5
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Locale support -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007, 2009 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008, 2009, 2010 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
|
||||
@ -652,13 +652,18 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
int __min, int __max, size_t __len,
|
||||
ios_base& __io, ios_base::iostate& __err) const;
|
||||
|
||||
// Extract day or month name, or any unique array of string
|
||||
// literals in a const _CharT* array.
|
||||
// Extract any unique array of string literals in a const _CharT* array.
|
||||
iter_type
|
||||
_M_extract_name(iter_type __beg, iter_type __end, int& __member,
|
||||
const _CharT** __names, size_t __indexlen,
|
||||
ios_base& __io, ios_base::iostate& __err) const;
|
||||
|
||||
// Extract day or month name in a const _CharT* array.
|
||||
iter_type
|
||||
_M_extract_wday_or_month(iter_type __beg, iter_type __end, int& __member,
|
||||
const _CharT** __names, size_t __indexlen,
|
||||
ios_base& __io, ios_base::iostate& __err) const;
|
||||
|
||||
// Extract on a component-by-component basis, via __format argument.
|
||||
iter_type
|
||||
_M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io,
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Locale support -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2007, 2008, 2009, 2010 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
|
||||
@ -947,6 +947,77 @@ _GLIBCXX_END_LDBL_NAMESPACE
|
||||
return __beg;
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _InIter>
|
||||
_InIter
|
||||
time_get<_CharT, _InIter>::
|
||||
_M_extract_wday_or_month(iter_type __beg, iter_type __end, int& __member,
|
||||
const _CharT** __names, size_t __indexlen,
|
||||
ios_base& __io, ios_base::iostate& __err) const
|
||||
{
|
||||
typedef char_traits<_CharT> __traits_type;
|
||||
const locale& __loc = __io._M_getloc();
|
||||
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
|
||||
|
||||
int* __matches = static_cast<int*>(__builtin_alloca(2 * sizeof(int)
|
||||
* __indexlen));
|
||||
size_t __nmatches = 0;
|
||||
size_t* __matches_lengths = 0;
|
||||
size_t __pos = 0;
|
||||
|
||||
if (__beg != __end)
|
||||
{
|
||||
const char_type __c = *__beg;
|
||||
for (size_t __i = 0; __i < 2 * __indexlen; ++__i)
|
||||
if (__c == __names[__i][0]
|
||||
|| __c == __ctype.toupper(__names[__i][0]))
|
||||
__matches[__nmatches++] = __i;
|
||||
}
|
||||
|
||||
if (__nmatches)
|
||||
{
|
||||
++__beg, ++__pos;
|
||||
|
||||
__matches_lengths
|
||||
= static_cast<size_t*>(__builtin_alloca(sizeof(size_t)
|
||||
* __nmatches));
|
||||
for (size_t __i = 0; __i < __nmatches; ++__i)
|
||||
__matches_lengths[__i]
|
||||
= __traits_type::length(__names[__matches[__i]]);
|
||||
}
|
||||
|
||||
for (; __beg != __end; ++__beg, ++__pos)
|
||||
{
|
||||
size_t __nskipped = 0;
|
||||
const char_type __c = *__beg;
|
||||
for (size_t __i = 0; __i < __nmatches;)
|
||||
{
|
||||
const char_type* __name = __names[__matches[__i]];
|
||||
if (__pos >= __matches_lengths[__i])
|
||||
++__nskipped, ++__i;
|
||||
else if (!(__name[__pos] == __c))
|
||||
{
|
||||
--__nmatches;
|
||||
__matches[__i] = __matches[__nmatches];
|
||||
__matches_lengths[__i] = __matches_lengths[__nmatches];
|
||||
}
|
||||
else
|
||||
++__i;
|
||||
}
|
||||
if (__nskipped == __nmatches)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((__nmatches == 1 && __matches_lengths[0] == __pos)
|
||||
|| (__nmatches == 2 && (__matches_lengths[0] == __pos
|
||||
|| __matches_lengths[1] == __pos)))
|
||||
__member = (__matches[0] >= __indexlen
|
||||
? __matches[0] - __indexlen : __matches[0]);
|
||||
else
|
||||
__err |= ios_base::failbit;
|
||||
|
||||
return __beg;
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _InIter>
|
||||
_InIter
|
||||
time_get<_CharT, _InIter>::
|
||||
@ -991,35 +1062,14 @@ _GLIBCXX_END_LDBL_NAMESPACE
|
||||
const locale& __loc = __io._M_getloc();
|
||||
const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
|
||||
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
|
||||
const char_type* __days[7];
|
||||
const char_type* __days[14];
|
||||
__tp._M_days_abbreviated(__days);
|
||||
__tp._M_days(__days + 7);
|
||||
int __tmpwday;
|
||||
ios_base::iostate __tmperr = ios_base::goodbit;
|
||||
__beg = _M_extract_name(__beg, __end, __tmpwday, __days, 7,
|
||||
__io, __tmperr);
|
||||
|
||||
// Check to see if non-abbreviated name exists, and extract.
|
||||
// NB: Assumes both _M_days and _M_days_abbreviated organized in
|
||||
// exact same order, first to last, such that the resulting
|
||||
// __days array with the same index points to a day, and that
|
||||
// day's abbreviated form.
|
||||
// NB: Also assumes that an abbreviated name is a subset of the name.
|
||||
if (!__tmperr && __beg != __end)
|
||||
{
|
||||
size_t __pos = __traits_type::length(__days[__tmpwday]);
|
||||
__tp._M_days(__days);
|
||||
const char_type* __name = __days[__tmpwday];
|
||||
if (__name[__pos] == *__beg)
|
||||
{
|
||||
// Extract the rest of it.
|
||||
const size_t __len = __traits_type::length(__name);
|
||||
while (__pos < __len && __beg != __end
|
||||
&& __name[__pos] == *__beg)
|
||||
++__beg, ++__pos;
|
||||
if (__len != __pos)
|
||||
__tmperr |= ios_base::failbit;
|
||||
}
|
||||
}
|
||||
__beg = _M_extract_wday_or_month(__beg, __end, __tmpwday, __days, 7,
|
||||
__io, __tmperr);
|
||||
if (!__tmperr)
|
||||
__tm->tm_wday = __tmpwday;
|
||||
else
|
||||
@ -1040,35 +1090,14 @@ _GLIBCXX_END_LDBL_NAMESPACE
|
||||
const locale& __loc = __io._M_getloc();
|
||||
const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
|
||||
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
|
||||
const char_type* __months[12];
|
||||
const char_type* __months[24];
|
||||
__tp._M_months_abbreviated(__months);
|
||||
__tp._M_months(__months + 12);
|
||||
int __tmpmon;
|
||||
ios_base::iostate __tmperr = ios_base::goodbit;
|
||||
__beg = _M_extract_name(__beg, __end, __tmpmon, __months, 12,
|
||||
__io, __tmperr);
|
||||
|
||||
// Check to see if non-abbreviated name exists, and extract.
|
||||
// NB: Assumes both _M_months and _M_months_abbreviated organized in
|
||||
// exact same order, first to last, such that the resulting
|
||||
// __months array with the same index points to a month, and that
|
||||
// month's abbreviated form.
|
||||
// NB: Also assumes that an abbreviated name is a subset of the name.
|
||||
if (!__tmperr && __beg != __end)
|
||||
{
|
||||
size_t __pos = __traits_type::length(__months[__tmpmon]);
|
||||
__tp._M_months(__months);
|
||||
const char_type* __name = __months[__tmpmon];
|
||||
if (__name[__pos] == *__beg)
|
||||
{
|
||||
// Extract the rest of it.
|
||||
const size_t __len = __traits_type::length(__name);
|
||||
while (__pos < __len && __beg != __end
|
||||
&& __name[__pos] == *__beg)
|
||||
++__beg, ++__pos;
|
||||
if (__len != __pos)
|
||||
__tmperr |= ios_base::failbit;
|
||||
}
|
||||
}
|
||||
__beg = _M_extract_wday_or_month(__beg, __end, __tmpmon, __months, 12,
|
||||
__io, __tmperr);
|
||||
if (!__tmperr)
|
||||
__tm->tm_mon = __tmpmon;
|
||||
else
|
||||
|
@ -0,0 +1,86 @@
|
||||
// { dg-require-namedlocale "" }
|
||||
|
||||
// Copyright (C) 2010 Free Software Foundation
|
||||
//
|
||||
// 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 3, 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 COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// 22.2.5.1.1 time_get members
|
||||
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
// libstdc++/38081
|
||||
void test01()
|
||||
{
|
||||
using namespace std;
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
typedef istreambuf_iterator<char> iterator_type;
|
||||
|
||||
// basic construction
|
||||
locale loc("ru_RU.ISO-8859-5");
|
||||
|
||||
// create an ostream-derived object, cache the time_get facet
|
||||
iterator_type end;
|
||||
|
||||
istringstream iss;
|
||||
iss.imbue(loc);
|
||||
const time_get<char>& tim_get = use_facet<time_get<char> >(iss.getloc());
|
||||
|
||||
const ios_base::iostate good = ios_base::goodbit;
|
||||
ios_base::iostate errorstate = good;
|
||||
|
||||
// iter_type
|
||||
// get_weekday(iter_type, iter_type, ios_base&,
|
||||
// ios_base::iostate&, tm*) const
|
||||
|
||||
iss.str("\xbf\xdd\xd4");
|
||||
iterator_type is_it01(iss);
|
||||
tm time01;
|
||||
memset(&time01, -1, sizeof(tm));
|
||||
errorstate = good;
|
||||
tim_get.get_weekday(is_it01, end, iss, errorstate, &time01);
|
||||
VERIFY( time01.tm_wday == 1 );
|
||||
VERIFY( errorstate == ios_base::eofbit );
|
||||
|
||||
iss.str("\xbf\xde\xdd\xd5\xd4\xd5\xdb\xec\xdd\xd8\xda");
|
||||
iterator_type is_it02(iss);
|
||||
tm time02;
|
||||
memset(&time02, -1, sizeof(tm));
|
||||
errorstate = good;
|
||||
tim_get.get_weekday(is_it02, end, iss, errorstate, &time02);
|
||||
VERIFY( time02.tm_wday == 1 );
|
||||
VERIFY( errorstate == ios_base::eofbit );
|
||||
|
||||
iss.str("\xbf\xdd\xd4\xd5\xd4\xd5\xdb\xec\xdd\xd8\xda");
|
||||
iterator_type is_it03(iss);
|
||||
tm time03;
|
||||
memset(&time03, -1, sizeof(tm));
|
||||
errorstate = good;
|
||||
iterator_type ret = tim_get.get_weekday(is_it03, end, iss,
|
||||
errorstate, &time03);
|
||||
VERIFY( time03.tm_wday == 1 );
|
||||
VERIFY( errorstate == ios_base::goodbit );
|
||||
VERIFY( *ret == '\xd5' );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
// 2010-01-05 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
// Copyright (C) 2010 Free Software Foundation
|
||||
//
|
||||
// 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 3, 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 COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// 22.2.5.1.1 time_get members
|
||||
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
using namespace std;
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
typedef istreambuf_iterator<char> iterator_type;
|
||||
|
||||
// basic construction
|
||||
locale loc("ru_RU.UTF8");
|
||||
|
||||
// create an ostream-derived object, cache the time_get facet
|
||||
iterator_type end;
|
||||
|
||||
istringstream iss;
|
||||
iss.imbue(loc);
|
||||
const time_get<char>& tim_get = use_facet<time_get<char> >(iss.getloc());
|
||||
|
||||
const ios_base::iostate good = ios_base::goodbit;
|
||||
ios_base::iostate errorstate = good;
|
||||
|
||||
// iter_type
|
||||
// get_weekday(iter_type, iter_type, ios_base&,
|
||||
// ios_base::iostate&, tm*) const
|
||||
|
||||
const char* awdays[7] = { "\u0412\u0441\u043A",
|
||||
"\u041F\u043D\u0434",
|
||||
"\u0412\u0442\u0440",
|
||||
"\u0421\u0440\u0434",
|
||||
"\u0427\u0442\u0432",
|
||||
"\u041F\u0442\u043D",
|
||||
"\u0421\u0431\u0442" };
|
||||
|
||||
for (unsigned i = 0; i < 7; ++i)
|
||||
{
|
||||
iss.str(awdays[i]);
|
||||
iterator_type is_it01(iss);
|
||||
tm time01;
|
||||
memset(&time01, -1, sizeof(tm));
|
||||
errorstate = good;
|
||||
tim_get.get_weekday(is_it01, end, iss, errorstate, &time01);
|
||||
VERIFY( time01.tm_wday == i );
|
||||
VERIFY( errorstate == ios_base::eofbit );
|
||||
}
|
||||
|
||||
const char* wdays[7] = { "\u0412\u043E\u0441\u043A\u0440\u0435"
|
||||
"\u0441\u0435\u043D\u044C\u0435",
|
||||
"\u041F\u043E\u043D\u0435\u0434\u0435"
|
||||
"\u043B\u044C\u043D\u0438\u043A",
|
||||
"\u0412\u0442\u043E\u0440\u043D\u0438\u043A",
|
||||
"\u0421\u0440\u0435\u0434\u0430",
|
||||
"\u0427\u0435\u0442\u0432\u0435\u0440\u0433",
|
||||
"\u041F\u044F\u0442\u043D\u0438\u0446\u0430",
|
||||
"\u0421\u0443\u0431\u0431\u043E\u0442\u0430" };
|
||||
|
||||
for (unsigned i = 0; i < 7; ++i)
|
||||
{
|
||||
iss.str(wdays[i]);
|
||||
iterator_type is_it01(iss);
|
||||
tm time01;
|
||||
memset(&time01, -1, sizeof(tm));
|
||||
errorstate = good;
|
||||
tim_get.get_weekday(is_it01, end, iss, errorstate, &time01);
|
||||
VERIFY( time01.tm_wday == i );
|
||||
VERIFY( errorstate == ios_base::eofbit );
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
# libstdc++ "tool init file" for DejaGNU
|
||||
|
||||
# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
||||
# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@ -883,6 +883,8 @@ proc check_v3_target_namedlocale { } {
|
||||
puts $f " locale(\"is_IS.UTF-8\");"
|
||||
puts $f " locale(\"it_IT\");"
|
||||
puts $f " locale(\"ja_JP.eucjp\");"
|
||||
puts $f " locale(\"ru_RU.ISO-8859-5\");"
|
||||
puts $f " locale(\"ru_RU.UTF-8\");"
|
||||
puts $f " locale(\"se_NO.UTF-8\");"
|
||||
puts $f " locale(\"ta_IN\");"
|
||||
puts $f " locale(\"zh_TW\");"
|
||||
|
Loading…
Reference in New Issue
Block a user