Index: include/__locale =================================================================== --- include/__locale +++ include/__locale @@ -31,6 +31,62 @@ #pragma GCC system_header #endif +// Newlib doesn't have the following C extensions for locales. +#if defined(_NEWLIB_VERSION) +typedef void *locale_t; +extern "C" locale_t duplocale(locale_t); +extern "C" void freelocale(locale_t); +extern "C" locale_t newlocale(int, const char *, locale_t); +extern "C" locale_t uselocale(locale_t); +#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_MESSAGES_MASK | \ + LC_MONETARY_MASK | LC_NUMERIC_MASK | LC_TIME_MASK) +#define isxdigit_l(a, L) (((void) L), isxdigit(a)) +#define iswxdigit_l(a, L) (((void) L), iswxdigit(a)) +#define isdigit_l(a, L) (((void) L), isdigit(a)) +#define iswdigit_l(a, L) (((void) L), iswdigit(a)) +#define iswcntrl_l(a, L) (((void) L), iswcntrl(a)) +#define iswcntrl_l(a, L) (((void) L), iswcntrl(a)) +#define isalpha_l(a, L) (((void) L), isalpha(a)) +#define iswalpha_l(a, L) (((void) L), iswalpha(a)) +#define ispunct_l(a, L) (((void) L), ispunct(a)) +#define iswpunct_l(a, L) (((void) L), iswpunct(a)) +#define isblank_l(a, L) (((void) L), isblank(a)) +#define iswblank_l(a, L) (((void) L), iswblank(a)) +#define isspace_l(a, L) (((void) L), isspace(a)) +#define iswspace_l(a, L) (((void) L), iswspace(a)) +#define isprint_l(a, L) (((void) L), isprint(a)) +#define iswprint_l(a, L) (((void) L), iswprint(a)) +#define islower_l(a, L) (((void) L), islower(a)) +#define iswlower_l(a, L) (((void) L), iswlower(a)) +#define isupper_l(a, L) (((void) L), isupper(a)) +#define iswupper_l(a, L) (((void) L), iswupper(a)) +#define tolower_l(a, L) (((void) L), tolower(a)) +#define towlower_l(a, L) (((void) L), towlower(a)) +#define toupper_l(a, L) (((void) L), toupper(a)) +#define towupper_l(a, L) (((void) L), towupper(a)) +#define strftime_l(a, b, c, d, L) (((void) L), strftime(a, b, c, d)) +#define strtoll_l(a, b, c, L) (((void) L), strtoll(a, b, c)) +#define strtoull_l(a, b, c, L) (((void) L), strtoull(a, b, c)) +#define strtold_l(a, b, L) (((void) L), strtold(a, b)) +#define strcoll_l(a, b, L) (((void) L), strcoll(a, b)) +#define wstrcoll_l(a, b, L) (((void) L), wstrcoll(a, b)) +#define cscoll_l(a, b, L) (((void) L), cscoll(a, b)) +#define wcscoll_l(a, b, L) (((void) L), wcscoll(a, b)) +#define strxfrm_l(a, b, c, L) (((void) L), strxfrm(a, b, c)) +#define wstrxfrm_l(a, b, c, L) (((void) L), wstrxfrm(a, b, c)) +#define csxfrm_l(a, b, c, L) (((void) L), csxfrm(a, b, c)) +#define wcsxfrm_l(a, b, c, L) (((void) L), wcsxfrm(a, b, c)) +#define sscanf_l(a, b, L, ...) (((void) L), sscanf(a, b, ##__VA_ARGS__)) +#define snprintf_l(a, b, L, c, ...) (((void) L), snprintf(a, b, c, ##__VA_ARGS__)) +#define asprintf_l(a, L, b, ...) (((void) L), asprintf(a, b, ##__VA_ARGS__)) +#endif + _LIBCPP_BEGIN_NAMESPACE_STD class _LIBCPP_TYPE_VIS locale; @@ -375,7 +431,20 @@ static const mask punct = _ISPUNCT; static const mask xdigit = _ISXDIGIT; static const mask blank = _ISBLANK; -#else // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ || __EMSCRIPTEN__ || __sun__ +#elif defined(_NEWLIB_VERSION) + typedef char mask; // Same type as Newlib's _ctype_ array in ctype.h. + // The following macros are defined in Newlib's ctype.h. + static const mask space = _S; + static const mask print = _P | _U | _L | _N | _B; + static const mask cntrl = _C; + static const mask upper = _U; + static const mask lower = _L; + static const mask alpha = _U | _L; + static const mask digit = _N; + static const mask punct = _P; + static const mask xdigit = _X | _N; + static const mask blank = _B; +#else // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ || __EMSCRIPTEN__ || __NetBSD__ || __sun__ || _AIX || _NEWLIB_VERSION typedef unsigned long mask; static const mask space = 1<<0; static const mask print = 1<<1; @@ -387,7 +456,7 @@ static const mask punct = 1<<7; static const mask xdigit = 1<<8; static const mask blank = 1<<9; -#endif // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ +#endif // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ || __EMSCRIPTEN__ || __NetBSD__ || __sun__ || _AIX || _NEWLIB_VERSION static const mask alnum = alpha | digit; static const mask graph = alnum | punct; Index: include/cmath =================================================================== --- include/cmath +++ include/cmath @@ -1382,7 +1382,11 @@ using ::log2f; inline _LIBCPP_INLINE_VISIBILITY float log2(float __x) _NOEXCEPT {return log2f(__x);} +#if defined(_NEWLIB_VERSION) +inline _LIBCPP_INLINE_VISIBILITY long double log2(long double __x) _NOEXCEPT {return __builtin_log2(__x);} +#else inline _LIBCPP_INLINE_VISIBILITY long double log2(long double __x) _NOEXCEPT {return log2l(__x);} +#endif template inline _LIBCPP_INLINE_VISIBILITY @@ -1395,7 +1399,11 @@ using ::logbf; inline _LIBCPP_INLINE_VISIBILITY float logb(float __x) _NOEXCEPT {return logbf(__x);} +#if defined(_NEWLIB_VERSION) +inline _LIBCPP_INLINE_VISIBILITY long double logb(long double __x) _NOEXCEPT {return __builtin_logb(__x);} +#else inline _LIBCPP_INLINE_VISIBILITY long double logb(long double __x) _NOEXCEPT {return logbl(__x);} +#endif template inline _LIBCPP_INLINE_VISIBILITY @@ -1480,6 +1488,15 @@ // nexttoward +#if defined(_NEWLIB_VERSION) +inline _LIBCPP_INLINE_VISIBILITY float nexttoward(float __x, long double __y) _NOEXCEPT {return __builtin_nexttoward(__x, __y);} +inline _LIBCPP_INLINE_VISIBILITY long double nexttoward(long double __x, long double __y) _NOEXCEPT {return __builtin_nexttoward(__x, __y);} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if::value, double>::type +nexttoward(_A1 __x, long double __y) _NOEXCEPT {return __builtin_nexttoward((double)__x, __y);} +#else using ::nexttoward; using ::nexttowardf; @@ -1490,7 +1507,7 @@ inline _LIBCPP_INLINE_VISIBILITY typename enable_if::value, double>::type nexttoward(_A1 __x, long double __y) _NOEXCEPT {return nexttoward((double)__x, __y);} - +#endif // remainder using ::remainder; @@ -1663,14 +1680,18 @@ using ::llrintl; using ::llroundl; using ::log1pl; +#if !defined(_NEWLIB_VERSION) using ::log2l; using ::logbl; +#endif using ::lrintl; using ::lroundl; using ::nanl; using ::nearbyintl; using ::nextafterl; +#if !defined(_NEWLIB_VERSION) using ::nexttowardl; +#endif using ::remainderl; using ::remquol; using ::rintl; Index: include/cstdio =================================================================== --- include/cstdio +++ include/cstdio @@ -172,8 +172,11 @@ using ::fsetpos; using ::ftell; using ::rewind; +#undef clearerr using ::clearerr; +#undef feof using ::feof; +#undef ferror using ::ferror; using ::perror; Index: include/locale =================================================================== --- include/locale +++ include/locale @@ -193,7 +193,9 @@ #include #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) #include -#else // _LIBCPP_MSVCRT +#elif defined(_NEWLIB_VERSION) +// Not supported by newlib. +#else // _WIN32 #include #endif // !_LIBCPP_MSVCRT @@ -229,7 +231,7 @@ // 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 +3675,7 @@ typename messages<_CharT>::catalog messages<_CharT>::do_open(const basic_string& __nm, const locale&) const { -#ifdef _WIN32 +#if defined(_WIN32) || defined(_NEWLIB_VERSION) return -1; #else // _WIN32 catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE); @@ -3688,7 +3690,7 @@ messages<_CharT>::do_get(catalog __c, int __set, int __msgid, const string_type& __dflt) const { -#ifdef _WIN32 +#if defined(_WIN32) || defined(_NEWLIB_VERSION) return __dflt; #else // _WIN32 string __ndflt; @@ -3710,7 +3712,7 @@ void messages<_CharT>::do_close(catalog __c) const { -#if !defined(_WIN32) +#if !defined(_WIN32) && !defined(_NEWLIB_VERSION) if (__c != -1) __c <<= 1; nl_catd __cat = (nl_catd)__c; Index: src/locale.cpp =================================================================== --- src/locale.cpp +++ src/locale.cpp @@ -42,6 +42,16 @@ #pragma clang diagnostic ignored "-Wsign-conversion" #endif +// Newlib doesn't have the following C extensions for locales. +#if defined(_NEWLIB_VERSION) +extern "C" { + locale_t duplocale(locale_t) { return NULL; } + void freelocale(locale_t) { } + locale_t newlocale(int, const char *, locale_t) { return NULL; } + locale_t uselocale(locale_t) { return NULL; } +} +#endif + _LIBCPP_BEGIN_NAMESPACE_STD #ifdef __cloc_defined @@ -1037,6 +1047,9 @@ return *__ctype_b_loc(); #elif defined(_AIX) return (const unsigned int *)__lc_ctype_ptr->obj->mask; +#elif defined(_NEWLIB_VERSION) + // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1]. + return _ctype_ + 1; #else // Platform not supported: abort so the person doing the port knows what to // fix