Index: include/locale =================================================================== --- include/locale +++ include/locale @@ -191,8 +191,18 @@ #endif #include #include + +#ifndef __has_include +#define __has_include(x) 0 +#endif +#if __has_include() +#include // for _NEWLIB_VERSION +#endif + #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) #include +#elif defined(_NEWLIB_VERSION) +#include #elif !defined(__ANDROID__) #include #endif @@ -229,7 +239,8 @@ // OSX has nice foo_l() functions that let you turn off use of the global // locale. Linux, not so much. The following functions avoid the locale when // that's possible and otherwise do the wrong thing. FIXME. -#if defined(__linux__) || defined(__EMSCRIPTEN__) || defined(_AIX) +#if defined(__linux__) || defined(__EMSCRIPTEN__) || defined(_AIX) || \ + defined(_NEWLIB_VERSION) #ifdef _LIBCPP_LOCALE__L_EXTENSIONS decltype(MB_CUR_MAX_L(_VSTD::declval())) @@ -3673,7 +3684,7 @@ typename messages<_CharT>::catalog messages<_CharT>::do_open(const basic_string& __nm, const locale&) const { -#if defined(_WIN32) || defined(__ANDROID__) +#if defined(_WIN32) || defined(__ANDROID__) || defined(_NEWLIB_VERSION) return -1; #else // _WIN32 || __ANDROID__ catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE); @@ -3688,7 +3699,7 @@ messages<_CharT>::do_get(catalog __c, int __set, int __msgid, const string_type& __dflt) const { -#if defined(_WIN32) || defined(__ANDROID__) +#if defined(_WIN32) || defined(__ANDROID__) || defined(_NEWLIB_VERSION) return __dflt; #else // _WIN32 string __ndflt; @@ -3710,7 +3721,7 @@ void messages<_CharT>::do_close(catalog __c) const { -#if !defined(_WIN32) && !defined(__ANDROID__) +#if !defined(_WIN32) && !defined(__ANDROID__) && !defined(_NEWLIB_VERSION) if (__c != -1) __c <<= 1; nl_catd __cat = (nl_catd)__c; Index: include/support/newlib/xlocale.h =================================================================== --- include/support/newlib/xlocale.h +++ include/support/newlib/xlocale.h @@ -0,0 +1,206 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_SUPPORT_NEWLIB_XLOCALE_H +#define _LIBCPP_SUPPORT_NEWLIB_XLOCALE_H + +#if defined(_NEWLIB_VERSION) + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#if defined(__STRICT_ANSI__) +// TODO(jroelofs): so newlib has this, but it's guarded out in c++. Would it be +// better to put the declaration for that here? +static inline int isascii(int c) { + return (0 <= c && c <= 127) ? 1 : 0; +} +#endif + +// Patch over newlib's lack of extended locale support +typedef void *locale_t; +static inline locale_t duplocale(locale_t) { + return nullptr; +} + +static inline void freelocale(locale_t) { + +} + +static inline locale_t newlocale(int, const char *, locale_t) { + return nullptr; +} + +static inline locale_t uselocale(locale_t) { + return nullptr; +} + +#define LC_COLLATE_MASK (1 << LC_COLLATE) +#define LC_CTYPE_MASK (1 << LC_CTYPE) +#define LC_MESSAGES_MASK (1 << LC_MESSAGES) +#define LC_MONETARY_MASK (1 << LC_MONETARY) +#define LC_NUMERIC_MASK (1 << LC_NUMERIC) +#define LC_TIME_MASK (1 << LC_TIME) +#define LC_ALL_MASK (LC_COLLATE_MASK|\ + LC_CTYPE_MASK|\ + LC_MONETARY_MASK|\ + LC_NUMERIC_MASK|\ + LC_TIME_MASK|\ + LC_MESSAGES_MASK) + +static inline int isdigit_l(char c, locale_t l) { + (void) l; + return isdigit(c); +} + +static inline int isxdigit_l(char c, locale_t l) { + (void) l; + return isxdigit(c); +} + +static inline int islower_l(int ch, locale_t l) { + (void) l; + return islower(ch); +} + +static inline int isupper_l(int ch, locale_t l) { + (void) l; + return isupper(ch); +} + +static inline int iswalpha_l(wint_t wc, locale_t l) { + (void) l; + return iswalpha(wc); +} + +static inline int iswblank_l(wint_t wc, locale_t l) { + (void) l; + return iswblank(wc); +} + +static inline int iswcntrl_l(wint_t wc, locale_t l) { + (void) l; + return iswcntrl(wc); +} + +static inline int iswdigit_l(wint_t wc, locale_t l) { + (void) l; + return iswdigit(wc); +} + +static inline int iswlower_l(wint_t wc, locale_t l) { + (void) l; + return iswlower(wc); +} + +static inline int iswprint_l(wint_t wc, locale_t l) { + (void) l; + return iswprint(wc); +} + +static inline int iswpunct_l(wint_t wc, locale_t l) { + (void) l; + return iswpunct(wc); +} + +static inline int iswspace_l(wint_t wc, locale_t l) { + (void) l; + return iswspace(wc); +} + +static inline int iswupper_l(wint_t wc, locale_t l) { + (void) l; + return iswupper(wc); +} + +static inline int iswxdigit_l(wint_t wc, locale_t l) { + (void) l; + return iswxdigit(wc); +} + +static inline long long strtoll_l(const char *s, char **end, int base, + locale_t l) { + (void) l; + return strtoll(s, end, base); +} + +static inline unsigned long long strtoull_l(const char *s, char **end, int base, + locale_t l) { + (void) l; + return strtoull(s, end, base); +} + +static inline long double strtold_l(const char *s, char **end, locale_t l) { + (void) l; + return strtold(s, end); +} + +static inline int strcoll_l(const char *s1, const char *s2, locale_t l) { + (void) l; + return strcoll(s1, s2); +} + +static inline size_t strftime_l(char *s, size_t m, const char *f, + const struct tm *t, + locale_t l) { + (void) l; + return strftime(s, m, f, t); +} + +static inline size_t strxfrm_l(char *s1, const char *s2, size_t n, locale_t l) { + (void) l; + return strxfrm(s1, s2, n); +} + +static inline int tolower_l(int c, locale_t l) { + (void) l; + return tolower(c); +} + +static inline int toupper_l(int c, locale_t l) { + (void) l; + return toupper(c); +} + +static inline wint_t towlower_l(wint_t wc, locale_t l) { + (void) l; + return towlower(wc); +} + +static inline wint_t towupper_l(wint_t wc, locale_t l) { + (void) l; + return towupper(wc); +} + +static inline size_t wcsxfrm_l(wchar_t *ws1, const wchar_t *ws2, size_t n, + locale_t l) { + (void) l; + return wcsxfrm(ws1, ws2, n); +} + +static inline int wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, + locale_t l) { + (void) l; + return wcscoll(ws1, ws2); +} + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _NEWLIB_VERSION + +#endif