-
Notifications
You must be signed in to change notification settings - Fork 15k
[libc++][z/OS] Move z/OS to new locale API and resolve all name collisions #165428
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@llvm/pr-subscribers-libcxx Author: Zibi Sarbinowski (zibi2) ChangesPatch is 46.51 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/165428.diff 17 Files Affected:
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 37259a7e6e7dd..b7871e4b6ff70 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -532,6 +532,7 @@ set(files
__locale_dir/support/no_locale/characters.h
__locale_dir/support/no_locale/strtonum.h
__locale_dir/support/windows.h
+ __locale_dir/support/zos.h
__locale_dir/time.h
__locale_dir/wbuffer_convert.h
__locale_dir/wstring_convert.h
@@ -755,6 +756,7 @@ set(files
__support/ibm/gettod_zos.h
__support/ibm/locale_mgmt_zos.h
__support/ibm/nanosleep.h
+ __support/ibm/vasprintf.h
__support/xlocale/__nop_locale_mgmt.h
__support/xlocale/__posix_l_fallback.h
__support/xlocale/__strtonum_fallback.h
diff --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h
index 9f3ce02a3af20..9a8202a8ca050 100644
--- a/libcxx/include/__locale_dir/locale_base_api.h
+++ b/libcxx/include/__locale_dir/locale_base_api.h
@@ -15,6 +15,9 @@
# pragma GCC system_header
#endif
+LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
// The platform-specific headers have to provide the following interface.
//
// These functions are equivalent to their C counterparts, except that __locale::__locale_t
@@ -121,13 +124,15 @@
# include <__locale_dir/support/fuchsia.h>
# elif defined(__linux__)
# include <__locale_dir/support/linux.h>
+# elif defined(__MVS__)
+# include <__locale_dir/support/zos.h>
# else
// TODO: This is a temporary definition to bridge between the old way we defined the locale base API
// (by providing global non-reserved names) and the new API. As we move individual platforms
// towards the new way of defining the locale base API, this should disappear since each platform
// will define those directly.
-# if defined(_AIX) || defined(__MVS__)
+# if defined(_AIX)
# include <__locale_dir/locale_base_api/ibm.h>
# elif defined(__OpenBSD__)
# include <__locale_dir/locale_base_api/openbsd.h>
@@ -317,4 +322,6 @@ _LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_HAS_LOCALIZATION
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H
diff --git a/libcxx/include/__locale_dir/support/zos.h b/libcxx/include/__locale_dir/support/zos.h
new file mode 100644
index 0000000000000..3ab85bc0fabd9
--- /dev/null
+++ b/libcxx/include/__locale_dir/support/zos.h
@@ -0,0 +1,318 @@
+//===-----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___LOCALE_DIR_SUPPORT_IBM_H
+#define _LIBCPP___LOCALE_DIR_SUPPORT_IBM_H
+
+#include <__support/ibm/locale_mgmt_zos.h>
+#include <__support/ibm/vasprintf.h>
+
+#include "cstdlib"
+#include <clocale> // std::lconv
+#include <locale.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <wctype.h>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// These functions are exported within std namespace
+// for compatibility with previous versions.
+_LIBCPP_EXPORTED_FROM_ABI int isdigit_l(int, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int isxdigit_l(int, locale_t);
+
+namespace __locale {
+struct __locale_guard {
+ _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t& __loc) : __old_loc_(std::uselocale(__loc)) {}
+
+ _LIBCPP_HIDE_FROM_ABI ~__locale_guard() {
+ // if (__old_loc_)
+ if (__old_loc_ != (locale_t)0)
+ std::uselocale(__old_loc_);
+ }
+
+ locale_t __old_loc_;
+
+ __locale_guard(__locale_guard const&) = delete;
+ __locale_guard& operator=(__locale_guard const&) = delete;
+};
+
+//
+// Locale management
+//
+#define _LIBCPP_COLLATE_MASK LC_COLLATE_MASK
+#define _LIBCPP_CTYPE_MASK LC_CTYPE_MASK
+#define _LIBCPP_MONETARY_MASK LC_MONETARY_MASK
+#define _LIBCPP_NUMERIC_MASK LC_NUMERIC_MASK
+#define _LIBCPP_TIME_MASK LC_TIME_MASK
+#define _LIBCPP_MESSAGES_MASK LC_MESSAGES_MASK
+#define _LIBCPP_ALL_MASK LC_ALL_MASK
+#define _LIBCPP_LC_ALL LC_ALL
+
+#define _LIBCPP_CLOC std::__c_locale()
+#ifndef _LIBCPP_LC_GLOBAL_LOCALE
+# define _LIBCPP_LC_GLOBAL_LOCALE ((locale_t) - 1)
+#endif
+
+using __locale_t _LIBCPP_NODEBUG = locale_t;
+
+#if defined(_LIBCPP_BUILDING_LIBRARY)
+using __lconv_t _LIBCPP_NODEBUG = std::lconv;
+
+inline _LIBCPP_HIDE_FROM_ABI __locale_t __newlocale(int __category_mask, const char* __locale, __locale_t __base) {
+ return newlocale(__category_mask, __locale, __base);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI void __freelocale(__locale_t __loc) { freelocale(__loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI char* __setlocale(int __category, char const* __locale) {
+ return ::setlocale(__category, __locale);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI __lconv_t* __localeconv(__locale_t& __loc) {
+ __locale_guard __current(__loc);
+ return std::localeconv();
+}
+#endif // _LIBCPP_BUILDING_LIBRARY
+
+// The following are not POSIX routines. These are quick-and-dirty hacks
+// to make things pretend to work
+
+//
+// Strtonum functions
+//
+inline _LIBCPP_HIDE_FROM_ABI float __strtof(const char* __nptr, char** __endptr, __locale_t __loc) {
+ __locale_guard __newloc(__loc);
+ return ::strtof(__nptr, __endptr);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr, __locale_t __loc) {
+ __locale_guard __newloc(__loc);
+ return ::strtod(__nptr, __endptr);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __endptr, __locale_t __loc) {
+ __locale_guard __newloc(__loc);
+ return ::strtold(__nptr, __endptr);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
+ __locale_guard __newloc(__loc);
+ return ::strtoll(__nptr, __endptr, __base);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI unsigned long long
+__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
+ __locale_guard __newloc(__loc);
+ return ::strtoull(__nptr, __endptr, __base);
+}
+
+//
+// Character manipulation functions
+//
+namespace __ibm {
+_LIBCPP_HIDE_FROM_ABI int islower_l(int, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int isupper_l(int, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int iswalpha_l(wint_t, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int iswblank_l(wint_t, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int iswcntrl_l(wint_t, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int iswdigit_l(wint_t, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int iswlower_l(wint_t, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int iswprint_l(wint_t, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int iswpunct_l(wint_t, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int iswspace_l(wint_t, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int iswupper_l(wint_t, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int iswxdigit_l(wint_t, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int toupper_l(int, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int tolower_l(int, __locale_t);
+_LIBCPP_HIDE_FROM_ABI wint_t towupper_l(wint_t, __locale_t);
+_LIBCPP_HIDE_FROM_ABI wint_t towlower_l(wint_t, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int strcoll_l(const char*, const char*, __locale_t);
+_LIBCPP_HIDE_FROM_ABI size_t strxfrm_l(char*, const char*, size_t, __locale_t);
+_LIBCPP_HIDE_FROM_ABI size_t strftime_l(char*, size_t, const char*, const struct tm*, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int wcscoll_l(const wchar_t*, const wchar_t*, __locale_t);
+_LIBCPP_HIDE_FROM_ABI size_t wcsxfrm_l(wchar_t*, const wchar_t*, size_t, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int iswctype_l(wint_t, wctype_t, __locale_t);
+_LIBCPP_HIDE_FROM_ABI size_t mbsnrtowcs(wchar_t*, const char**, size_t, size_t, mbstate_t*);
+_LIBCPP_HIDE_FROM_ABI size_t wcsnrtombs(char*, const wchar_t**, size_t, size_t, mbstate_t*);
+
+// These functions are not used internally by libcxx
+// and are included for completness.
+_LIBCPP_HIDE_FROM_ABI int isalnum_l(int, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int isalpha_l(int, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int isblank_l(int, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int iscntrl_l(int, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int isgraph_l(int, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int isprint_l(int, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int ispunct_l(int, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int isspace_l(int, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int iswalnum_l(wint_t, __locale_t);
+_LIBCPP_HIDE_FROM_ABI int iswgraph_l(wint_t, __locale_t);
+} // namespace __ibm
+
+using namespace __ibm;
+
+#if defined(_LIBCPP_BUILDING_LIBRARY)
+inline _LIBCPP_HIDE_FROM_ABI int __islower(int __c, __locale_t __loc) { return islower_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __isupper(int __c, __locale_t __loc) { return isupper_l(__c, __loc); }
+#endif
+
+inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t __loc) { return isdigit_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t __loc) { return isxdigit_l(__c, __loc); }
+
+#if defined(_LIBCPP_BUILDING_LIBRARY)
+inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return toupper_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __tolower(int __c, __locale_t __loc) { return tolower_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __strcoll(const char* __s1, const char* __s2, __locale_t __loc) {
+ return strcoll_l(__s1, __s2, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __strxfrm(char* __dest, const char* __src, size_t __n, __locale_t __loc) {
+ return strxfrm_l(__dest, __src, __n, __loc);
+}
+
+# if _LIBCPP_HAS_WIDE_CHARACTERS
+inline _LIBCPP_HIDE_FROM_ABI int __iswctype(wint_t __c, wctype_t __type, __locale_t __loc) {
+ return iswctype_l(__c, __type, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswspace(wint_t __c, __locale_t __loc) { return iswspace_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswprint(wint_t __c, __locale_t __loc) { return iswprint_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswcntrl(wint_t __c, __locale_t __loc) { return iswcntrl_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswupper(wint_t __c, __locale_t __loc) { return iswupper_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswlower(wint_t __c, __locale_t __loc) { return iswlower_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswalpha(wint_t __c, __locale_t __loc) { return iswalpha_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswblank(wint_t __c, __locale_t __loc) { return iswblank_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswdigit(wint_t __c, __locale_t __loc) { return iswdigit_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswpunct(wint_t __c, __locale_t __loc) { return iswpunct_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswxdigit(wint_t __c, __locale_t __loc) { return iswxdigit_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI wint_t __towupper(wint_t __c, __locale_t __loc) { return towupper_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI wint_t __towlower(wint_t __c, __locale_t __loc) { return towlower_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __wcscoll(const wchar_t* __ws1, const wchar_t* __ws2, __locale_t __loc) {
+ return wcscoll_l(__ws1, __ws2, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __wcsxfrm(wchar_t* __dest, const wchar_t* __src, size_t __n, __locale_t __loc) {
+ return wcsxfrm_l(__dest, __src, __n, __loc);
+}
+# endif // _LIBCPP_HAS_WIDE_CHARACTERS
+
+inline _LIBCPP_HIDE_FROM_ABI
+size_t __strftime(char* __s, size_t __max, const char* __format, const struct tm* __tm, __locale_t __loc) {
+ return strftime_l(__s, __max, __format, __tm, __loc);
+}
+
+//
+// Other functions
+//
+inline _LIBCPP_HIDE_FROM_ABI decltype(MB_CUR_MAX) __mb_len_max(__locale_t __loc) {
+ __locale_guard __current(__loc);
+ return MB_CUR_MAX;
+}
+
+# if _LIBCPP_HAS_WIDE_CHARACTERS
+inline _LIBCPP_HIDE_FROM_ABI wint_t __btowc(int __c, __locale_t __loc) {
+ __locale_guard __current(__loc);
+ return std::btowc(__c);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __wctob(wint_t __c, __locale_t __loc) {
+ __locale_guard __current(__loc);
+ return std::wctob(__c);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t
+__wcsnrtombs(char* __dest, const wchar_t** __src, size_t __nwc, size_t __len, mbstate_t* __ps, __locale_t __loc) {
+ __locale_guard __current(__loc);
+ return wcsnrtombs(__dest, __src, __nwc, __len, __ps); // non-standard
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __wcrtomb(char* __s, wchar_t __wc, mbstate_t* __ps, __locale_t __loc) {
+ __locale_guard __current(__loc);
+ return std::wcrtomb(__s, __wc, __ps);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t
+__mbsnrtowcs(wchar_t* __dest, const char** __src, size_t __nms, size_t __len, mbstate_t* __ps, __locale_t __loc) {
+ __locale_guard __current(__loc);
+ return mbsnrtowcs(__dest, __src, __nms, __len, __ps); // non-standard
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t
+__mbrtowc(wchar_t* __pwc, const char* __s, size_t __n, mbstate_t* __ps, __locale_t __loc) {
+ __locale_guard __current(__loc);
+ return std::mbrtowc(__pwc, __s, __n, __ps);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __mbtowc(wchar_t* __pwc, const char* __pmb, size_t __max, __locale_t __loc) {
+ __locale_guard __current(__loc);
+ return std::mbtowc(__pwc, __pmb, __max);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __mbrlen(const char* __s, size_t __n, mbstate_t* __ps, __locale_t __loc) {
+ __locale_guard __current(__loc);
+ return std::mbrlen(__s, __n, __ps);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t
+__mbsrtowcs(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps, __locale_t __loc) {
+ __locale_guard __current(__loc);
+ return std::mbsrtowcs(__dest, __src, __len, __ps);
+}
+# endif // _LIBCPP_BUILDING_LIBRARY
+#endif // _LIBCPP_HAS_WIDE_CHARACTERS
+
+_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __snprintf(
+ char* __s, size_t __n, __locale_t __loc, const char* __format, ...) {
+ va_list __va;
+ va_start(__va, __format);
+ __locale_guard __current(__loc);
+ int __res = std::vsnprintf(__s, __n, __format, __va);
+ va_end(__va);
+ return __res;
+}
+
+_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __asprintf(
+ char** __s, __locale_t __loc, const char* __format, ...) {
+ va_list __va;
+ va_start(__va, __format);
+ __locale_guard __current(__loc);
+ int __res = std::__ibm::vasprintf(__s, __format, __va); // non-standard
+ va_end(__va);
+ return __res;
+}
+
+_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf(
+ const char* __s, __locale_t __loc, const char* __format, ...) {
+ va_list __va;
+ va_start(__va, __format);
+ __locale_guard __current(__loc);
+ int __res = std::vsscanf(__s, __format, __va);
+ va_end(__va);
+ return __res;
+}
+} // namespace __locale
+_LIBCPP_END_NAMESPACE_STD
+#endif // _LIBCPP___LOCALE_DIR_SUPPORT_IBM_H
diff --git a/libcxx/include/__support/ibm/vasprintf.h b/libcxx/include/__support/ibm/vasprintf.h
new file mode 100644
index 0000000000000..bf42ec7963f45
--- /dev/null
+++ b/libcxx/include/__support/ibm/vasprintf.h
@@ -0,0 +1,51 @@
+//===-----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___SUPPORT_IBMVASPRINTF_H
+#define _LIBCPP___SUPPORT_IBMVASPRINTF_H
+
+#include <cstdlib> // malloc, realloc
+#include <stdarg.h> // va_copy, va_end
+#include <stdio.h> // vsnprintf
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __ibm {
+
+inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 2, 0) int vasprintf(char** strp, const char* fmt, va_list ap) {
+ const size_t buff_size = 256;
+ if ((*strp = (char*)malloc(buff_size)) == nullptr) {
+ return -1;
+ }
+
+ va_list ap_copy;
+ // va_copy may not be provided by the C library in C++03 mode.
+#if defined(_LIBCPP_CXX03_LANG) && __has_builtin(__builtin_va_copy)
+# if defined(__MVS__) && !defined(_VARARG_EXT_)
+ __builtin_zos_va_copy(ap_copy, ap);
+# else
+ __builtin_va_copy(ap_copy, ap);
+# endif
+#else
+ va_copy(ap_copy, ap);
+#endif
+ int str_size = vsnprintf(*strp, buff_size, fmt, ap_copy);
+ va_end(ap_copy);
+
+ if ((size_t)str_size >= buff_size) {
+ if ((*strp = (char*)realloc(*strp, str_size + 1)) == nullptr) {
+ return -1;
+ }
+ str_size = vsnprintf(*strp, str_size + 1, fmt, ap);
+ }
+ return str_size;
+}
+
+} // namespace __ibm
+_LIBCPP_END_NAMESPACE_STD
+#endif // _LIBCPP___SUPPORT_IBMVASPRINTF_H
diff --git a/libcxx/include/__undef_macros b/libcxx/include/__undef_macros
index 29ab327e1c375..f02547841e621 100644
--- a/libcxx/include/__undef_macros
+++ b/libcxx/include/__undef_macros
@@ -26,3 +26,79 @@
#ifdef erase
# undef erase
#endif
+
+#ifdef __islower
+# undef __islower
+#endif
+
+#ifdef __isupper
+# undef __isupper
+#endif
+
+#ifdef __isdigit
+# undef __isdigit
+#endif
+
+#ifdef __isxdigit
+# undef __isxdigit
+#endif
+
+#ifdef __toupper
+# undef __toupper
+#endif
+
+#ifdef __tolower
+# undef __tolower
+#endif
+
+#ifdef __iswctype
+# undef __iswctype
+#endif
+
+#ifdef __iswspace
+# undef __iswspace
+#endif
+
+#ifdef __iswprint
+# undef __iswprint
+#endif
+
+#ifdef __iswcntrl
+# undef __iswcntrl
+#endif
+
+#ifdef __iswupper
+# undef __iswupper
+#endif
+
+#ifdef __iswlower
+# undef __iswlower
+#endif
+
+#ifdef __iswalpha
+# undef __iswalpha
+#endif
+
+#ifdef __iswblank
+# undef __iswblank
+#endif
+
+#ifdef __iswdigit
+# undef __iswdigit
+#endif
+
+#ifdef __iswpunct
+# undef __iswpunct
+#endif
+
+#ifdef __iswxdigit
+# undef __iswxdigit
+#endif
+
+#ifdef __towupper
+# undef __towupper
+#endif
+
+#ifdef __towlower
+# undef __towlower
+#endif
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index a86d6c6a43d0e..28ea168dbb8c8 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1587,6 +1587,7 @@ module std [system] {
textual header "__locale_dir/support/freebsd.h"
textual header "__locale_dir/support/fuchsia.h"
textual header "__locale_dir/support/linux.h"
+ textual header "__locale_dir/support/zos.h"
textual header "__locale_dir/support/no_locale/characters.h"
textual header "__locale_dir/support/no_locale/strtonum.h"
textual header "__locale_dir/support/windows.h"
diff --git a/libcxx/include/wchar.h b/libcxx/include/wchar.h
index a932dd266b862..82984143aa6c5 100644
--- a/libcxx/include/wchar.h
+++ b/libcxx/include/wchar.h
@@ -193,14 +193,14 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD wchar_t* wmemchr(wchar_t
}
# endif
-# if defined(__cplusplus) && (defined(_LIBCPP_MSVCRT_LIKE) || defined(__MVS__))
+# if defined(__cplusplus) && defined(_LIBCPP_MSVCRT_LIKE)
extern "C" {
size_t mbsnrtowcs(
wchar_t* __restrict __dst, const char** __restrict __src, size_t __nmc, size_t __len, mbstate_t* __restrict __ps);
size_t wcsnrtombs(
char* __restrict __dst, const wchar_t** __restrict __src, size_t __nwc, size_t __len, mbstate_t* __restrict __ps);
} // extern "C"
-# endif // __cplusplus && (_LIBCPP_MSVCRT || __MVS__)
+# endif // __cplusplus && _LIBCPP_MSVCRT
# endif // _LIBCPP_HAS_WIDE_CHARACTERS
# endif // _LIBCPP_WCHAR_H
diff --git a/libcxx/src/support/ibm/localeconv.cpp b/libcxx/src/support/ibm/localeconv.cpp
new file mode 100644
index 0000000000000..4ab6b7a75f618
--- /dev/null
+++ b/libcxx/src/support/ibm/localeconv.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <__locale>
+#include <__locale_dir/support/zos.h> // __locale_guard
+#include <memory>
+#include <stdlib.h>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+lconv *__libcpp_localeconv_l(locale_t& __l)
+{
+ __locale::__locale_guard __current(__l);
+
+ lconv * lc = localeconv();
+ static lconv newlc;
+ newlc = *...
[truncated]
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
8444d45 to
97bb07c
Compare
| // towards the new way of defining the locale base API, this should disappear since each platform | ||
| // will define those directly. | ||
| # if defined(_AIX) || defined(__MVS__) | ||
| # if defined(_AIX) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about AIX? z/OS is technically not officially supported since we don't have CI for it. In practice, as long as it uses basically the same code as AIX, I'm fine with shoving that under the rug, but we should migrate AIX to the new locale API as well in this PR to avoid introducing a chunk of z/OS-only code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I asked @xingxue-ibm to look into it and will let him to decide whether to use separate or same PR for AIX.
| // Character manipulation functions | ||
| // | ||
| namespace __ibm { | ||
| _LIBCPP_HIDE_FROM_ABI int islower_l(int, __locale_t); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need these non-reserved functions? Can't we use functions like __islower directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is because system header is using macro to define them as follows:
# define __islower_l(c,l) __isctype_l((c), _ISlower, (l))
# define islower_l(c,l) __islower_l ((c), (l))
| # undef erase | ||
| #endif | ||
|
|
||
| #ifdef __islower |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain the need for these? Can't the system headers be fixed not to define these macros instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are macros in system headers, see my previous comment.
aa1b487 to
f8690f4
Compare
No description provided.