re PR libstdc++/19955 (Second std::ctype<char>::narrow() does not call std::ctype<char>::do_narrow())
2005-02-15 Paolo Carlini <pcarlini@suse.de> Jon Grimm <jgrimm2@us.ibm.com> PR libstdc++/19955 * include/bits/locale_facets.h (ctype<char>::_M_narrow_init()): Fix the logic setting _M_narrow_ok: first check whether the transformation is trivial with a dflt == 0, then deal with the special case of zero. * testsuite/22_locale/ctype/narrow/char/19955.cc: New. * include/bits/locale_facets.h (ctype<char>::_M_widen_init()): Tweak consistently to use memcmp; minor formatting fixes. Co-Authored-By: Jon Grimm <jgrimm2@us.ibm.com> From-SVN: r95082
This commit is contained in:
parent
fd9850d552
commit
82ce2a94d9
|
@ -1,3 +1,16 @@
|
|||
2005-02-15 Paolo Carlini <pcarlini@suse.de>
|
||||
Jon Grimm <jgrimm2@us.ibm.com>
|
||||
|
||||
PR libstdc++/19955
|
||||
* include/bits/locale_facets.h (ctype<char>::_M_narrow_init()):
|
||||
Fix the logic setting _M_narrow_ok: first check whether the
|
||||
transformation is trivial with a dflt == 0, then deal with the
|
||||
special case of zero.
|
||||
* testsuite/22_locale/ctype/narrow/char/19955.cc: New.
|
||||
|
||||
* include/bits/locale_facets.h (ctype<char>::_M_widen_init()):
|
||||
Tweak consistently to use memcmp; minor formatting fixes.
|
||||
|
||||
2005-02-15 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR libstdc++/19946
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Locale support -*- C++ -*-
|
||||
|
||||
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
|
||||
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
// Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
|
@ -690,7 +690,7 @@ namespace std
|
|||
mutable char _M_widen[1 + static_cast<unsigned char>(-1)];
|
||||
mutable char _M_narrow[1 + static_cast<unsigned char>(-1)];
|
||||
mutable char _M_narrow_ok; // 0 uninitialized, 1 init,
|
||||
// 2 non-consecutive
|
||||
// 2 memcpy can't be used
|
||||
|
||||
public:
|
||||
/// The facet id for ctype<char>
|
||||
|
@ -865,7 +865,8 @@ namespace std
|
|||
char_type
|
||||
widen(char __c) const
|
||||
{
|
||||
if (_M_widen_ok) return _M_widen[static_cast<unsigned char>(__c)];
|
||||
if (_M_widen_ok)
|
||||
return _M_widen[static_cast<unsigned char>(__c)];
|
||||
this->_M_widen_init();
|
||||
return this->do_widen(__c);
|
||||
}
|
||||
|
@ -896,7 +897,8 @@ namespace std
|
|||
memcpy(__to, __lo, __hi - __lo);
|
||||
return __hi;
|
||||
}
|
||||
if (!_M_widen_ok) _M_widen_init();
|
||||
if (!_M_widen_ok)
|
||||
_M_widen_init();
|
||||
return this->do_widen(__lo, __hi, __to);
|
||||
}
|
||||
|
||||
|
@ -924,7 +926,8 @@ namespace std
|
|||
if (_M_narrow[static_cast<unsigned char>(__c)])
|
||||
return _M_narrow[static_cast<unsigned char>(__c)];
|
||||
const char __t = do_narrow(__c, __dfault);
|
||||
if (__t != __dfault) _M_narrow[static_cast<unsigned char>(__c)] = __t;
|
||||
if (__t != __dfault)
|
||||
_M_narrow[static_cast<unsigned char>(__c)] = __t;
|
||||
return __t;
|
||||
}
|
||||
|
||||
|
@ -954,7 +957,7 @@ namespace std
|
|||
narrow(const char_type* __lo, const char_type* __hi,
|
||||
char __dfault, char *__to) const
|
||||
{
|
||||
if (__builtin_expect(_M_narrow_ok == 1,true))
|
||||
if (__builtin_expect(_M_narrow_ok == 1, true))
|
||||
{
|
||||
memcpy(__to, __lo, __hi - __lo);
|
||||
return __hi;
|
||||
|
@ -1161,17 +1164,13 @@ namespace std
|
|||
|
||||
_M_widen_ok = 1;
|
||||
// Set _M_widen_ok to 2 if memcpy can't be used.
|
||||
for (size_t __j = 0; __j < sizeof(_M_widen); ++__j)
|
||||
if (__tmp[__j] != _M_widen[__j])
|
||||
{
|
||||
_M_widen_ok = 2;
|
||||
break;
|
||||
}
|
||||
if (memcmp(__tmp, _M_widen, sizeof(_M_widen)))
|
||||
_M_widen_ok = 2;
|
||||
}
|
||||
|
||||
// Fill in the narrowing cache and flag whether all values are
|
||||
// valid or not. _M_narrow_ok is set to 1 if the whole table is
|
||||
// narrowed, 2 if only some values could be narrowed.
|
||||
// valid or not. _M_narrow_ok is set to 2 if memcpy can't
|
||||
// be used.
|
||||
void _M_narrow_init() const
|
||||
{
|
||||
char __tmp[sizeof(_M_narrow)];
|
||||
|
@ -1179,21 +1178,18 @@ namespace std
|
|||
__tmp[__i] = __i;
|
||||
do_narrow(__tmp, __tmp + sizeof(__tmp), 0, _M_narrow);
|
||||
|
||||
// Check if any default values were created. Do this by
|
||||
// renarrowing with a different default value and comparing.
|
||||
bool __consecutive = true;
|
||||
for (size_t __j = 0; __j < sizeof(_M_narrow); ++__j)
|
||||
if (!_M_narrow[__j])
|
||||
{
|
||||
char __c;
|
||||
do_narrow(__tmp + __j, __tmp + __j + 1, 1, &__c);
|
||||
if (__c == 1)
|
||||
{
|
||||
__consecutive = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_M_narrow_ok = __consecutive ? 1 : 2;
|
||||
_M_narrow_ok = 1;
|
||||
if (memcmp(__tmp, _M_narrow, sizeof(_M_narrow)))
|
||||
_M_narrow_ok = 2;
|
||||
else
|
||||
{
|
||||
// Deal with the special case of zero: renarrow with a
|
||||
// different default and compare.
|
||||
char __c;
|
||||
do_narrow(__tmp, __tmp + 1, 1, &__c);
|
||||
if (__c == 1)
|
||||
_M_narrow_ok = 2;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
// Copyright (C) 2005 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// 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.
|
||||
|
||||
// 22.2.1.3.2 ctype<char> members
|
||||
|
||||
#include <locale>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
class Ctype1
|
||||
: public std::ctype<char>
|
||||
{
|
||||
protected:
|
||||
const char*
|
||||
do_narrow(const char* lo, const char* hi,
|
||||
char dflt, char* to) const
|
||||
{
|
||||
for (int i = 0; lo != hi; ++lo, ++to, ++i)
|
||||
*to = *lo + i;
|
||||
return hi;
|
||||
}
|
||||
};
|
||||
|
||||
class Ctype2
|
||||
: public std::ctype<char>
|
||||
{
|
||||
protected:
|
||||
const char*
|
||||
do_narrow(const char* lo, const char* hi,
|
||||
char dflt, char* to) const
|
||||
{
|
||||
for (int i = 0; lo != hi; ++lo, ++to, ++i)
|
||||
if (*lo == '\000')
|
||||
*to = dflt;
|
||||
else
|
||||
*to = *lo;
|
||||
return hi;
|
||||
}
|
||||
};
|
||||
|
||||
// libstdc++/19955
|
||||
void test01()
|
||||
{
|
||||
using namespace std;
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
const char src[] = "abcd";
|
||||
|
||||
locale mylocale1(locale::classic(), new Ctype1);
|
||||
const ctype<char>& mc1 = use_facet<ctype<char> >(mylocale1);
|
||||
|
||||
char dst1[sizeof(src)];
|
||||
memset(dst1, 0, sizeof(src));
|
||||
char dst2[sizeof(src)];
|
||||
memset(dst2, 0, sizeof(src));
|
||||
|
||||
mc1.narrow(src, src + sizeof(src), '*', dst1);
|
||||
mc1.narrow(src, src + sizeof(src), '*', dst2);
|
||||
|
||||
VERIFY( !memcmp(dst1, "aceg\004", 5) );
|
||||
VERIFY( !memcmp(dst1, dst2, 5) );
|
||||
|
||||
locale mylocale2(locale::classic(), new Ctype2);
|
||||
const ctype<char>& mc2 = use_facet<ctype<char> >(mylocale2);
|
||||
|
||||
char dst3[sizeof(src)];
|
||||
memset(dst3, 0, sizeof(src));
|
||||
char dst4[sizeof(src)];
|
||||
memset(dst4, 0, sizeof(src));
|
||||
|
||||
mc2.narrow(src, src + sizeof(src), '*', dst3);
|
||||
mc2.narrow(src, src + sizeof(src), '*', dst4);
|
||||
|
||||
VERIFY( !memcmp(dst3, "abcd*", 5) );
|
||||
VERIFY( !memcmp(dst3, dst4, 5) );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue