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]

Re: [PATCH] Fix libstdc++ usage of __ctype_b/__ctype_to*


> From what I can read in ISO C++98, ctype<char>::classic_table() is supposed to
> return LC_CTYPE __ctype_b mask table for the "C" locale (22.2.1.3.3), ie. my
> reading of the source is that the current implementation is wrong.
> It should return _S_c_locale->__ctype_b and if newlocale is not
> supported it should either play with setlocale, or return its own array.
> Returning __ctype_b is correct only if setlocale hasn't been called yet or
> last has been called with LC_CTYPE or LC_ALL, "C".

I agree with this.
 
> And ctype<char>::ctype(const mask* __table, bool __del, size_t __refs)
> constructor looks like it is supposed to use the user provided __table
> if non-NULL, otherwise classic_table() (that's just a guess, I actually
> couldn't find the exact wording anywhere, but it makes sense
> to me, especially in the presence of ctype_byname and
> ctype(__c_locale, ...)). 

Agreed.

> So, all in all, I think really nothing has to
> change in glibc CVS to make libstdc++-v3 happy (ie. __ctype_b doesn't
> really have to be exported as default symver, at least not for
> libstdc++-v3).

Right.
  
> -#if _GLIBCPP_USE_SHADOW_HEADERS
> +#if _GLIBCPP_C_LOCALE_GNU
> +  const ctype_base::mask*
> +  ctype<char>::classic_table() throw()
> +  {
> +    if (!_S_c_locale)
> +      _S_create_c_locale(_S_c_locale, "C");
> +    return _S_c_locale->__ctype_b;
> +  }
> +#else

_S_c_locale should be created before this. I suppose this is safer.

> +# if _GLIBCPP_USE_SHADOW_HEADERS
>    using _C_legacy::__ctype_toupper;
>    using _C_legacy::__ctype_tolower;
>    using _C_legacy::__ctype_b;
> -#endif

Just remove all this _GLIBCPP_USE_SHADOW_HEADERS cruft.

> +# endif
>  
>    const ctype_base::mask*
>    ctype<char>::classic_table() throw()
> -  { return __ctype_b; }  

Why not just _S_c_locale->__ctype_b?

> -  
> +  {
> +    const ctype_base::mask* __ret;
> +    char* __old = strdup(setlocale(LC_CTYPE, NULL));
> +    setlocale(LC_CTYPE, "C");
> +    __ret = __ctype_b;
> +    setlocale(__old);
> +    free(__old);
> +    return __ret;
> +  }
> +#endif

Ok. Make sure the generic/ctype_noninline.h also does this though.

> +
>  #if _GLIBCPP_C_LOCALE_GNU

all these hooks are in the gnu-linux file so that --enable-clocale=generic
will work on linux, so that I can test the generic codepath on checkins.

-benjamin


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