Windows patch work by Ruben Van Boxem

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@140781 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Howard Hinnant 2011-09-29 13:33:15 +00:00
parent 866569b8c3
commit 3c466fc631
3 changed files with 56 additions and 45 deletions

View File

@ -319,7 +319,7 @@ public:
static const mask xdigit = _ISxdigit; static const mask xdigit = _ISxdigit;
static const mask blank = _ISblank; static const mask blank = _ISblank;
#elif _WIN32 #elif _WIN32
typedef unsigned __int32 mask; typedef unsigned short mask;
static const mask space = _SPACE; static const mask space = _SPACE;
static const mask print = _BLANK|_PUNCT|_ALPHA|_DIGIT; static const mask print = _BLANK|_PUNCT|_ALPHA|_DIGIT;
static const mask cntrl = _CONTROL; static const mask cntrl = _CONTROL;
@ -557,7 +557,7 @@ public:
#endif #endif
_LIBCPP_ALWAYS_INLINE const mask* table() const _NOEXCEPT {return __tab_;} _LIBCPP_ALWAYS_INLINE const mask* table() const _NOEXCEPT {return __tab_;}
static const mask* classic_table() _NOEXCEPT; static const mask* classic_table() _NOEXCEPT;
#ifndef _LIBCPP_HAS_DEFAULTRUNELOCALE #if defined(__GLIBC__)
static const int* __classic_upper_table() _NOEXCEPT; static const int* __classic_upper_table() _NOEXCEPT;
static const int* __classic_lower_table() _NOEXCEPT; static const int* __classic_lower_table() _NOEXCEPT;
#endif #endif

View File

@ -11,6 +11,9 @@
#ifndef _LIBCPP_SUPPORT_WIN32_LOCALE_H #ifndef _LIBCPP_SUPPORT_WIN32_LOCALE_H
#define _LIBCPP_SUPPORT_WIN32_LOCALE_H #define _LIBCPP_SUPPORT_WIN32_LOCALE_H
// ctype mask table defined in msvcrt.dll
extern "C" unsigned short __declspec(dllimport) _ctype[];
#include "support/win32/support.h" #include "support/win32/support.h"
#include <memory> #include <memory>
#include <xlocinfo.h> // _locale_t #include <xlocinfo.h> // _locale_t
@ -62,6 +65,8 @@ decltype(MB_CUR_MAX) MB_CUR_MAX_L( locale_t __l )
#define strtoull_l _strtoui64_l #define strtoull_l _strtoui64_l
// FIXME: current msvcrt does not know about long double // FIXME: current msvcrt does not know about long double
#define strtold_l _strtod_l #define strtold_l _strtod_l
#define islower_l _islower_l
#define isupper_l _isupper_l
#define isdigit_l _isdigit_l #define isdigit_l _isdigit_l
#define isxdigit_l _isxdigit_l #define isxdigit_l _isxdigit_l
#define strcoll_l _strcoll_l #define strcoll_l _strcoll_l

View File

@ -20,7 +20,7 @@
#include "cwctype" #include "cwctype"
#include "__sso_allocator" #include "__sso_allocator"
#if _WIN32 #if _WIN32
#include <locale.h> #include <support/win32/locale.h>
#else // _WIN32 #else // _WIN32
#include <langinfo.h> #include <langinfo.h>
#endif // _!WIN32 #endif // _!WIN32
@ -722,10 +722,12 @@ ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high)
wchar_t wchar_t
ctype<wchar_t>::do_toupper(char_type c) const ctype<wchar_t>::do_toupper(char_type c) const
{ {
#ifndef _LIBCPP_HAS_DEFAULTRUNELOCALE #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
#elif defined(__GLIBC__)
return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c; return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
#else #else
return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c; return (isascii(c) && iswlower_l(c, __cloc())) ? c-L'a'+L'A' : c;
#endif #endif
} }
@ -733,11 +735,13 @@ const wchar_t*
ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
{ {
for (; low != high; ++low) for (; low != high; ++low)
#ifndef _LIBCPP_HAS_DEFAULTRUNELOCALE #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
*low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
#elif defined(__GLIBC__)
*low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low] *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
: *low; : *low;
#else #else
*low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low; *low = (isascii(*low) && islower_l(*low, __cloc())) ? (*low-L'a'+L'A') : *low;
#endif #endif
return low; return low;
} }
@ -745,10 +749,12 @@ ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
wchar_t wchar_t
ctype<wchar_t>::do_tolower(char_type c) const ctype<wchar_t>::do_tolower(char_type c) const
{ {
#ifndef _LIBCPP_HAS_DEFAULTRUNELOCALE #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
#elif defined(__GLIBC__)
return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c; return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
#else #else
return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c; return (isascii(c) && isupper_l(c, __cloc())) ? c-L'A'+'a' : c;
#endif #endif
} }
@ -756,11 +762,13 @@ const wchar_t*
ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
{ {
for (; low != high; ++low) for (; low != high; ++low)
#ifndef _LIBCPP_HAS_DEFAULTRUNELOCALE #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
*low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
#elif defined(__GLIBC__)
*low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low] *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
: *low; : *low;
#else #else
*low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low; *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-L'A'+L'a' : *low;
#endif #endif
return low; return low;
} }
@ -820,10 +828,12 @@ ctype<char>::~ctype()
char char
ctype<char>::do_toupper(char_type c) const ctype<char>::do_toupper(char_type c) const
{ {
#ifndef _LIBCPP_HAS_DEFAULTRUNELOCALE #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
#elif defined(__GLIBC__)
return isascii(c) ? __classic_upper_table()[c] : c; return isascii(c) ? __classic_upper_table()[c] : c;
#else #else
return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c; return (isascii(c) && islower_l(c, __cloc())) ? c-'a'+'A' : c;
#endif #endif
} }
@ -831,10 +841,12 @@ const char*
ctype<char>::do_toupper(char_type* low, const char_type* high) const ctype<char>::do_toupper(char_type* low, const char_type* high) const
{ {
for (; low != high; ++low) for (; low != high; ++low)
#ifndef _LIBCPP_HAS_DEFAULTRUNELOCALE #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
*low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
#elif defined(__GLIBC__)
*low = isascii(*low) ? __classic_upper_table()[*low] : *low; *low = isascii(*low) ? __classic_upper_table()[*low] : *low;
#else #else
*low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low; *low = (isascii(*low) && islower_l(*low, __cloc())) ? *low-'a'+'A' : *low;
#endif #endif
return low; return low;
} }
@ -842,10 +854,12 @@ ctype<char>::do_toupper(char_type* low, const char_type* high) const
char char
ctype<char>::do_tolower(char_type c) const ctype<char>::do_tolower(char_type c) const
{ {
#ifndef _LIBCPP_HAS_DEFAULTRUNELOCALE #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
#elif defined(__GLIBC__)
return isascii(c) ? __classic_lower_table()[c] : c; return isascii(c) ? __classic_lower_table()[c] : c;
#else #else
return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c; return (isascii(c) && isupper_l(c, __cloc())) ? c-'A'+'a' : c;
#endif #endif
} }
@ -853,10 +867,12 @@ const char*
ctype<char>::do_tolower(char_type* low, const char_type* high) const ctype<char>::do_tolower(char_type* low, const char_type* high) const
{ {
for (; low != high; ++low) for (; low != high; ++low)
#ifndef _LIBCPP_HAS_DEFAULTRUNELOCALE #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
*low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
#elif defined(__GLIBC__)
*low = isascii(*low) ? __classic_lower_table()[*low] : *low; *low = isascii(*low) ? __classic_lower_table()[*low] : *low;
#else #else
*low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low; *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-'A'+'a' : *low;
#endif #endif
return low; return low;
} }
@ -901,6 +917,8 @@ ctype<char>::classic_table() _NOEXCEPT
return _DefaultRuneLocale.__runetype; return _DefaultRuneLocale.__runetype;
#elif defined(__GLIBC__) #elif defined(__GLIBC__)
return __cloc()->__ctype_b; return __cloc()->__ctype_b;
#elif _WIN32
return _ctype+1; // internal ctype mask table defined in msvcrt.dll
// This is assumed to be safe, which is a nonsense assumption because we're // This is assumed to be safe, which is a nonsense assumption because we're
// going to end up dereferencing it later... // going to end up dereferencing it later...
#else #else
@ -908,31 +926,19 @@ ctype<char>::classic_table() _NOEXCEPT
#endif #endif
} }
#ifndef _LIBCPP_HAS_DEFAULTRUNELOCALE #if defined(__GLIBC__)
const int* const int*
ctype<char>::__classic_lower_table() _NOEXCEPT ctype<char>::__classic_lower_table() _NOEXCEPT
{ {
#if defined(__APPLE__) || defined(__FreeBSD__)
return _DefaultRuneLocale.__maplower;
#elif defined(__GLIBC__)
return __cloc()->__ctype_tolower; return __cloc()->__ctype_tolower;
#else
return NULL;
#endif
} }
const int* const int*
ctype<char>::__classic_upper_table() _NOEXCEPT ctype<char>::__classic_upper_table() _NOEXCEPT
{ {
#if defined(__APPLE__) || defined(__FreeBSD__)
return _DefaultRuneLocale.__mapupper;
#elif defined(__GLIBC__)
return __cloc()->__ctype_toupper; return __cloc()->__ctype_toupper;
#else
return NULL;
#endif
} }
#endif // _LIBCPP_HAS_DEFAULTRUNELOCALE #endif // __GLIBC__
// template <> class ctype_byname<char> // template <> class ctype_byname<char>
@ -1026,18 +1032,18 @@ ctype_byname<wchar_t>::do_is(mask m, char_type c) const
#ifdef _LIBCPP_WCTYPE_IS_MASK #ifdef _LIBCPP_WCTYPE_IS_MASK
return static_cast<bool>(iswctype_l(c, m, __l)); return static_cast<bool>(iswctype_l(c, m, __l));
#else #else
// FIXME: This is broken for things that test more than one flag. bool result = true;
if (m & space && !iswspace_l(c, __l)) return false; if (m & space && !iswspace_l(c, __l)) result = false;
if (m & print && !iswprint_l(c, __l)) return false; if (m & print && !iswprint_l(c, __l)) result = false;
if (m & cntrl && !iswcntrl_l(c, __l)) return false; if (m & cntrl && !iswcntrl_l(c, __l)) result = false;
if (m & upper && !iswupper_l(c, __l)) return false; if (m & upper && !iswupper_l(c, __l)) result = false;
if (m & lower && !iswlower_l(c, __l)) return false; if (m & lower && !iswlower_l(c, __l)) result = false;
if (m & alpha && !iswalpha_l(c, __l)) return false; if (m & alpha && !iswalpha_l(c, __l)) result = false;
if (m & digit && !iswdigit_l(c, __l)) return false; if (m & digit && !iswdigit_l(c, __l)) result = false;
if (m & punct && !iswpunct_l(c, __l)) return false; if (m & punct && !iswpunct_l(c, __l)) result = false;
if (m & xdigit && !iswxdigit_l(c, __l)) return false; if (m & xdigit && !iswxdigit_l(c, __l)) result = false;
if (m & blank && !iswblank_l(c, __l)) return false; if (m & blank && !iswblank_l(c, __l)) result = false;
return true; return result;
#endif #endif
} }