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:
Paolo Carlini 2005-02-15 23:29:52 +00:00 committed by Paolo Carlini
parent fd9850d552
commit 82ce2a94d9
3 changed files with 143 additions and 29 deletions

View File

@ -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

View File

@ -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;
}
}
};

View File

@ -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;
}