[PATCH] Fix libstdc++ usage of __ctype_b/__ctype_to*
Benjamin Kosnik
bkoz@nabi.net
Wed Sep 4 14:24:00 GMT 2002
> 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
More information about the Gcc-patches
mailing list