[cfe-dev] [libc++] xlocale usage portability issues
Howard Hinnant
hhinnant at apple.com
Mon Oct 10 09:59:37 PDT 2011
On Oct 10, 2011, at 11:50 AM, aep wrote:
> allright this compiles for me with my recent patches to musl. yey :)
I'm not sure why but I'm having trouble applying this patch:
$ patch -p1 < temp.patch
patching file include/__locale
patch: **** malformed patch at line 15: @@ -235,11 +235,11 @@ collate<_CharT>::do_hash(const char_type* lo, const char_type* hi) const
>
> There is still two unclear parts here
>
> 1) I commented out some usings. I don't quite know what they are supposed to do, but they break the build against musl.
They are supposed to import symbols from the global namespace into namespace std (more below).
> 2) The replacement of reinterpret to static cast is because in musl they are both long, and clang doesn't like reinterpret_cast from long to long.
> I'm unsure if that breaks something else.
On OS X catopen() returns a pointer. Perhaps a C-style cast is the way to go here.
>
>
> diff --git a/include/__locale b/include/__locale
> index 8aa8fc1..6029e6e 100644
> --- a/include/__locale
> +++ b/include/__locale
> @@ -21,9 +21,9 @@
> #include <locale.h>
> #if _WIN32
> # include <support/win32/locale_win32.h>
> -#else // _WIN32
> +#elif (__GLIBC__ || __APPLE__ || __FreeBSD__)
> # include <xlocale.h>
> -#endif // _WIN32
> +#endif // _WIN32 || __GLIBC__ || __APPLE__ || __FreeBSD_
>
> #pragma GCC system_header
>
> @@ -235,11 +235,11 @@ collate<_CharT>::do_hash(const char_type* lo, const char_type* hi) const
> {
> size_t h = 0;
> const size_t sr = __CHAR_BIT__ * sizeof(size_t) - 8;
> - const size_t mask = size_t(0xF) << (sr + 4);
> + const size_t cmask = size_t(0xF) << (sr + 4);
Does __mask work for you instead? And while you're at it can you prefix every local variable in here with "__"?
> for(const char_type* p = lo; p != hi; ++p)
> {
> h = (h << 4) + *p;
> - size_t g = h & mask;
> + size_t g = h & cmask;
> h ^= g | (g >> sr);
> }
> return static_cast<long>(h);
> @@ -330,7 +330,7 @@ public:
> static const mask punct = _PUNCT;
> static const mask xdigit = _HEX;
> static const mask blank = _BLANK;
> -#else // __GLIBC__ || _WIN32
> +#elif (__APPLE__ || __FreeBSD__)
> #if __APPLE__
> typedef __uint32_t mask;
> #elif __FreeBSD__
> @@ -346,7 +346,19 @@ public:
> static const mask punct = _CTYPE_P;
> static const mask xdigit = _CTYPE_X;
> static const mask blank = _CTYPE_B;
> -#endif // __GLIBC__ || _WIN32
> +#else // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__
> + typedef unsigned long mask;
> + static const mask space = 1<<0;
> + static const mask print = 1<<1;
> + static const mask cntrl = 1<<2;
> + static const mask upper = 1<<3;
> + static const mask lower = 1<<4;
> + static const mask alpha = 1<<5;
> + static const mask digit = 1<<6;
> + static const mask punct = 1<<7;
> + static const mask xdigit = 1<<8;
> + static const mask blank = 1<<9;
> +#endif // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__
> static const mask alnum = alpha | digit;
> static const mask graph = alnum | punct;
>
> diff --git a/include/cmath b/include/cmath
> index f8bc0df..eec9f03 100644
> --- a/include/cmath
> +++ b/include/cmath
> @@ -623,7 +623,7 @@ isunordered(_A1 __x, _A2 __y)
>
> _LIBCPP_BEGIN_NAMESPACE_STD
>
> -using ::signbit;
> +//using ::signbit;
At first I was thinking this was a problem because signbit is a macro for you. However this code earlier in cmath should turn signbit from a macro into an inline function:
// signbit
#ifdef signbit
template <class _A1>
_LIBCPP_ALWAYS_INLINE
bool
__libcpp_signbit(_A1 __x)
{
return signbit(__x);
}
#undef signbit
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
typename std::enable_if<std::is_floating_point<_A1>::value, bool>::type
signbit(_A1 __x)
{
return __libcpp_signbit(__x);
}
#endif // signbit
Can you preprocess this and find out why "using ::signbit" is causing a problem? I can't just eliminate this using without breaking code.
> using ::fpclassify;
> using ::isfinite;
> using ::isinf;
> @@ -637,8 +637,8 @@ using ::islessgreater;
> using ::isunordered;
> using ::isunordered;
>
> -using ::float_t;
> -using ::double_t;
> +//using ::float_t;
> +//using ::double_t;
Same here.
>
> // abs
>
> diff --git a/include/locale b/include/locale
> index 9f9996a..55185d6 100644
> --- a/include/locale
> +++ b/include/locale
> @@ -3696,7 +3696,7 @@ messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
> #if _WIN32
> return -1;
> #else // _WIN32
> - catalog __cat = reinterpret_cast<catalog>(catopen(__nm.c_str(), NL_CAT_LOCALE));
> + catalog __cat = static_cast<catalog>(catopen(__nm.c_str(), NL_CAT_LOCALE));
This breaks OS X. Try:
catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
(it seems a shame we have to resort to this)
Howard
> if (__cat != -1)
> __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
> return __cat;
> @@ -3717,7 +3717,7 @@ messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
> __dflt.c_str() + __dflt.size());
> if (__c != -1)
> __c <<= 1;
> - nl_catd __cat = reinterpret_cast<nl_catd>(__c);
> + nl_catd __cat = static_cast<nl_catd>(__c);
> char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());
> string_type __w;
> __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w),
> @@ -3733,7 +3733,7 @@ messages<_CharT>::do_close(catalog __c) const
> #if !_WIN32
> if (__c != -1)
> __c <<= 1;
> - nl_catd __cat = reinterpret_cast<nl_catd>(__c);
> + nl_catd __cat = static_cast<nl_catd>(__c);
> catclose(__cat);
> #endif // !_WIN32
> }
>
More information about the cfe-dev
mailing list