This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

(libstdc++-v3) PATCH: Fix unconditional non-usage of installed _M_table


It is possible for a C++ library user to install a non-default
character class table, known inside the implementation of ctype<> as
the _M_table.  All concrete implementations in
libstdc++-v3/config/os/.../ctype_inline.h support such installation.
However, some ports fail to use it.  On *-*-freebsd*, this patch
fixes: FAIL: 22_locale/ctype/is/char/3.cc execution test

A few other ports appear to require a similar yet subtly different fix:

    $ find libstdc++-v3/config -name ctype_inline.h >/tmp/a
    $ grep -l _M_table `{cat /tmp/a} >/tmp/b
    $ sort /tmp/[ab]|uniq -u                    # proposed person to fix
  libstdc++-v3/config/os/aix/ctype_inline.h     (AIX person)
  libstdc++-v3/config/os/generic/ctype_inline.h (Darwin or OpenBSD person)
  libstdc++-v3/config/os/windiss/ctype_inline.h (Unknown, unlisted)

I can probably fix them by inspection, but...if you are the blessed
port maintainer for libstdc++-v3, your port fails the signature test
and you can test the change yourself, then please fix it (even though
it was likely not your fault, a lot of cloning took place ;-).  I
copied correct handling of an installed _M_table from
config/os/gnu-linux.  You have my preapproval to commit a similar
(tested!) change for your port.  Otherwise, I will fix other ports by
inspection as time permits.

Tested on i386-unknown-freebsd4.8, which now has "good" C++ library
test results again.  Installed on mainline.  Probably needed everywhere...

	* config/os/bsd/freebsd/ctype_inline.h:  Support _M_table
	when so installed.

Index: libstdc++-v3/config/os/bsd/freebsd/ctype_inline.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/config/os/bsd/freebsd/ctype_inline.h,v
retrieving revision 1.1
diff -c -r1.1 ctype_inline.h
*** libstdc++-v3/config/os/bsd/freebsd/ctype_inline.h	24 Jun 2002 05:48:49 -0000	1.1
--- libstdc++-v3/config/os/bsd/freebsd/ctype_inline.h	11 Mar 2003 06:43:24 -0000
***************
*** 38,72 ****
    ctype<char>::
    is(mask __m, char __c) const
    { 
!     return __istype(__c, __m);
    }
  
    const char*
    ctype<char>::
    is(const char* __low, const char* __high, mask* __vec) const
    {
!     for (;__low < __high; ++__vec, ++__low)
!       {
  #if defined (_CTYPE_S) || defined (__istype)
! 	*__vec = __maskrune (*__low, upper | lower | alpha | digit | xdigit
! 			     | space | print | graph | cntrl | punct | alnum);
  #else
! 	mask __m = 0;
! 	if (this->is(upper, *__low)) __m |= upper;
! 	if (this->is(lower, *__low)) __m |= lower;
! 	if (this->is(alpha, *__low)) __m |= alpha;
! 	if (this->is(digit, *__low)) __m |= digit;
! 	if (this->is(xdigit, *__low)) __m |= xdigit;
! 	if (this->is(space, *__low)) __m |= space;
! 	if (this->is(print, *__low)) __m |= print;
! 	if (this->is(graph, *__low)) __m |= graph;
! 	if (this->is(cntrl, *__low)) __m |= cntrl;
! 	if (this->is(punct, *__low)) __m |= punct;
! 	// Do not include explicit line for alnum mask since it is a
! 	// pure composite of masks on FreeBSD.
! 	*__vec = __m;
  #endif
!       }
      return __high;
    }
  
--- 38,79 ----
    ctype<char>::
    is(mask __m, char __c) const
    { 
!     if (_M_table)
!       return _M_table[static_cast<unsigned char>(__c)] & __m;
!     else
!       return __istype(__c, __m);
    }
  
    const char*
    ctype<char>::
    is(const char* __low, const char* __high, mask* __vec) const
    {
!     if (_M_table)
!       while (__low < __high)
! 	*__vec++ = _M_table[static_cast<unsigned char>(*__low++)];
!     else
!       for (;__low < __high; ++__vec, ++__low)
! 	{
  #if defined (_CTYPE_S) || defined (__istype)
! 	  *__vec = __maskrune (*__low, upper | lower | alpha | digit | xdigit
! 			       | space | print | graph | cntrl | punct | alnum);
  #else
! 	  mask __m = 0;
! 	  if (this->is(upper, *__low)) __m |= upper;
! 	  if (this->is(lower, *__low)) __m |= lower;
! 	  if (this->is(alpha, *__low)) __m |= alpha;
! 	  if (this->is(digit, *__low)) __m |= digit;
! 	  if (this->is(xdigit, *__low)) __m |= xdigit;
! 	  if (this->is(space, *__low)) __m |= space;
! 	  if (this->is(print, *__low)) __m |= print;
! 	  if (this->is(graph, *__low)) __m |= graph;
! 	  if (this->is(cntrl, *__low)) __m |= cntrl;
! 	  if (this->is(punct, *__low)) __m |= punct;
! 	  // Do not include explicit line for alnum mask since it is a
! 	  // pure composite of masks on FreeBSD.
! 	  *__vec = __m;
  #endif
! 	}
      return __high;
    }
  
***************
*** 74,81 ****
    ctype<char>::
    scan_is(mask __m, const char* __low, const char* __high) const
    {
!     while (__low < __high && !this->is(__m, *__low))
!       ++__low;
      return __low;
    }
  
--- 81,93 ----
    ctype<char>::
    scan_is(mask __m, const char* __low, const char* __high) const
    {
!     if (_M_table)
!       while (__low < __high
! 	     && !(_M_table[static_cast<unsigned char>(*__low)] & __m))
! 	++__low;
!     else
!       while (__low < __high && !this->is(__m, *__low))
! 	++__low;
      return __low;
    }
  
***************
*** 83,94 ****
    ctype<char>::
    scan_not(mask __m, const char* __low, const char* __high) const
    {
!     while (__low < __high && this->is(__m, *__low) != 0)
!       ++__low;
      return __low;
    }
- 
- 
- 
- 
- 
--- 95,106 ----
    ctype<char>::
    scan_not(mask __m, const char* __low, const char* __high) const
    {
!     if (_M_table)
!       while (__low < __high
! 	     && (_M_table[static_cast<unsigned char>(*__low)] & __m) != 0)
! 	++__low;
!     else
!       while (__low < __high && this->is(__m, *__low) != 0)
! 	++__low;
      return __low;
    }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]