Commit 82ce2a94 by Paolo Carlini Committed by Paolo Carlini

re PR libstdc++/19955 (Second std::ctype<char>::narrow() does not call…

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
parent fd9850d5
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> 2005-02-15 Jakub Jelinek <jakub@redhat.com>
PR libstdc++/19946 PR libstdc++/19946
......
// Locale support -*- C++ -*- // 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. // Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // This file is part of the GNU ISO C++ Library. This library is free
...@@ -690,7 +690,7 @@ namespace std ...@@ -690,7 +690,7 @@ namespace std
mutable char _M_widen[1 + static_cast<unsigned char>(-1)]; mutable char _M_widen[1 + static_cast<unsigned char>(-1)];
mutable char _M_narrow[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, mutable char _M_narrow_ok; // 0 uninitialized, 1 init,
// 2 non-consecutive // 2 memcpy can't be used
public: public:
/// The facet id for ctype<char> /// The facet id for ctype<char>
...@@ -865,7 +865,8 @@ namespace std ...@@ -865,7 +865,8 @@ namespace std
char_type char_type
widen(char __c) const 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(); this->_M_widen_init();
return this->do_widen(__c); return this->do_widen(__c);
} }
...@@ -896,7 +897,8 @@ namespace std ...@@ -896,7 +897,8 @@ namespace std
memcpy(__to, __lo, __hi - __lo); memcpy(__to, __lo, __hi - __lo);
return __hi; return __hi;
} }
if (!_M_widen_ok) _M_widen_init(); if (!_M_widen_ok)
_M_widen_init();
return this->do_widen(__lo, __hi, __to); return this->do_widen(__lo, __hi, __to);
} }
...@@ -924,7 +926,8 @@ namespace std ...@@ -924,7 +926,8 @@ namespace std
if (_M_narrow[static_cast<unsigned char>(__c)]) if (_M_narrow[static_cast<unsigned char>(__c)])
return _M_narrow[static_cast<unsigned char>(__c)]; return _M_narrow[static_cast<unsigned char>(__c)];
const char __t = do_narrow(__c, __dfault); 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; return __t;
} }
...@@ -954,7 +957,7 @@ namespace std ...@@ -954,7 +957,7 @@ namespace std
narrow(const char_type* __lo, const char_type* __hi, narrow(const char_type* __lo, const char_type* __hi,
char __dfault, char *__to) const 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); memcpy(__to, __lo, __hi - __lo);
return __hi; return __hi;
...@@ -1161,17 +1164,13 @@ namespace std ...@@ -1161,17 +1164,13 @@ namespace std
_M_widen_ok = 1; _M_widen_ok = 1;
// Set _M_widen_ok to 2 if memcpy can't be used. // Set _M_widen_ok to 2 if memcpy can't be used.
for (size_t __j = 0; __j < sizeof(_M_widen); ++__j) if (memcmp(__tmp, _M_widen, sizeof(_M_widen)))
if (__tmp[__j] != _M_widen[__j]) _M_widen_ok = 2;
{
_M_widen_ok = 2;
break;
}
} }
// Fill in the narrowing cache and flag whether all values are // 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 // valid or not. _M_narrow_ok is set to 2 if memcpy can't
// narrowed, 2 if only some values could be narrowed. // be used.
void _M_narrow_init() const void _M_narrow_init() const
{ {
char __tmp[sizeof(_M_narrow)]; char __tmp[sizeof(_M_narrow)];
...@@ -1179,21 +1178,18 @@ namespace std ...@@ -1179,21 +1178,18 @@ namespace std
__tmp[__i] = __i; __tmp[__i] = __i;
do_narrow(__tmp, __tmp + sizeof(__tmp), 0, _M_narrow); do_narrow(__tmp, __tmp + sizeof(__tmp), 0, _M_narrow);
// Check if any default values were created. Do this by _M_narrow_ok = 1;
// renarrowing with a different default value and comparing. if (memcmp(__tmp, _M_narrow, sizeof(_M_narrow)))
bool __consecutive = true; _M_narrow_ok = 2;
for (size_t __j = 0; __j < sizeof(_M_narrow); ++__j) else
if (!_M_narrow[__j]) {
{ // Deal with the special case of zero: renarrow with a
char __c; // different default and compare.
do_narrow(__tmp + __j, __tmp + __j + 1, 1, &__c); char __c;
if (__c == 1) do_narrow(__tmp, __tmp + 1, 1, &__c);
{ if (__c == 1)
__consecutive = false; _M_narrow_ok = 2;
break; }
}
}
_M_narrow_ok = __consecutive ? 1 : 2;
} }
}; };
......
// 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment