This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix libstdc++ usage of __ctype_b/__ctype_to*
- From: Benjamin Kosnik <bkoz at nabi dot net>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: drepper at redhat dot com, roland at redhat dot com, bkoz at redhat dot com, pcarlini at unitus dot it, libstdc++ at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Wed, 4 Sep 2002 16:05:57 -0500
- Subject: Re: [PATCH] Fix libstdc++ usage of __ctype_b/__ctype_to*
- Organization: secret_agent_headquarters
- References: <20020901022935.E7886@dhcp187.sf.frob.com><20020901061330.Z7920@devserv.devel.redhat.com><20020901034451.G7886@dhcp187.sf.frob.com><20020901065254.B7920@devserv.devel.redhat.com><20020901040933.I7886@dhcp187.sf.frob.com><20020901095711.C7920@devserv.devel.redhat.com><20020901102055.A5791@devserv.devel.redhat.com><3D724B9A.6050908@redhat.com><20020901145657.E7920@devserv.devel.redhat.com><3D726A72.2080106@redhat.com><20020901165440.F7920@devserv.devel.redhat.com>
> 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