-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[zOS] Avoid ambiguous declarations when z/OS libc or wrapper lib adds functionality #133104
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
Closed
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
@llvm/pr-subscribers-libcxx Author: Sean Perry (perry-ca) Changesnanosleep
locale
Full diff: https://github.com/llvm/llvm-project/pull/133104.diff 3 Files Affected:
diff --git a/libcxx/include/__locale_dir/locale_base_api/ibm.h b/libcxx/include/__locale_dir/locale_base_api/ibm.h
index 1d1d15df9f799..9d51043b7ffdb 100644
--- a/libcxx/include/__locale_dir/locale_base_api/ibm.h
+++ b/libcxx/include/__locale_dir/locale_base_api/ibm.h
@@ -22,31 +22,41 @@
#if defined(__MVS__)
# include <wctype.h>
-// POSIX routines
-# include <__support/xlocale/__posix_l_fallback.h>
#endif // defined(__MVS__)
+_LIBCPP_BEGIN_NAMESPACE_STD
+#ifdef __MVS__
+#define _LIBCPP_CLOC std::__c_locale()
+#ifndef _LIBCPP_LC_GLOBAL_LOCALE
+#define _LIBCPP_LC_GLOBAL_LOCALE ((locale_t) -1)
+#endif
+#else
+extern locale_t __cloc();
+#define _LIBCPP_CLOC std::__cloc()
+#endif
+_LIBCPP_END_NAMESPACE_STD
+
+#ifdef __MVS__
+_LIBCPP_BEGIN_NAMESPACE_STD
+#endif
+
namespace {
struct __setAndRestore {
- explicit __setAndRestore(locale_t locale) {
- if (locale == (locale_t)0) {
- __cloc = newlocale(LC_ALL_MASK, "C", /* base */ (locale_t)0);
- __stored = uselocale(__cloc);
+ explicit __setAndRestore(locale_t __l) {
+ if (__l == (locale_t)0) {
+ __stored = std::uselocale(_LIBCPP_CLOC);
} else {
- __stored = uselocale(locale);
+ __stored = std::uselocale(__l);
}
}
~__setAndRestore() {
- uselocale(__stored);
- if (__cloc)
- freelocale(__cloc);
+ std::uselocale(__stored);
}
private:
locale_t __stored = (locale_t)0;
- locale_t __cloc = (locale_t)0;
};
} // namespace
@@ -89,7 +99,11 @@ _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 2, 0) int vasprintf(char** strp, const char
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
@@ -105,4 +119,8 @@ _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 2, 0) int vasprintf(char** strp, const char
return str_size;
}
+#ifdef __MVS__
+_LIBCPP_END_NAMESPACE_STD
+#endif
+
#endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_IBM_H
diff --git a/libcxx/include/__thread/support/pthread.h b/libcxx/include/__thread/support/pthread.h
index 14e92079dadfe..f32dbd7f09253 100644
--- a/libcxx/include/__thread/support/pthread.h
+++ b/libcxx/include/__thread/support/pthread.h
@@ -194,9 +194,15 @@ inline _LIBCPP_HIDE_FROM_ABI int __libcpp_thread_detach(__libcpp_thread_t* __t)
inline _LIBCPP_HIDE_FROM_ABI void __libcpp_thread_yield() { sched_yield(); }
inline _LIBCPP_HIDE_FROM_ABI void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) {
+#ifdef __MVS__
+ #define __LIBCPP_NS __ibm::
+#else
+ #define __LIBCPP_NS
+#endif
__libcpp_timespec_t __ts = std::__convert_to_timespec<__libcpp_timespec_t>(__ns);
- while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR)
+ while (__LIBCPP_NS nanosleep(&__ts, &__ts) == -1 && errno == EINTR)
;
+#undef __LIBCPP_NS
}
//
diff --git a/libcxx/src/support/ibm/xlocale_zos.cpp b/libcxx/src/support/ibm/xlocale_zos.cpp
index 136999ec0b02f..fa5fb745df88e 100644
--- a/libcxx/src/support/ibm/xlocale_zos.cpp
+++ b/libcxx/src/support/ibm/xlocale_zos.cpp
@@ -6,125 +6,327 @@
//
//===----------------------------------------------------------------------===//
+#include "include/ibm_xlocale.h"
+
#include <__assert>
-#include <__support/ibm/xlocale.h>
-#include <sstream>
-#include <vector>
+#include <__locale_dir/locale_base_api/ibm.h>
+#include <errno.h>
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
+_LIBCPP_BEGIN_NAMESPACE_STD
-locale_t newlocale(int category_mask, const char* locale, locale_t base) {
- // Maintain current locale name(s) to restore later.
- std::string current_loc_name(setlocale(LC_ALL, 0));
+#define CategoryList(pair, sep) \
+ pair(LC_COLLATE, lc_collate) sep \
+ pair(LC_CTYPE, lc_ctype) sep \
+ pair(LC_MONETARY, lc_monetary) sep \
+ pair(LC_NUMERIC, lc_numeric) sep \
+ pair(LC_TIME, lc_time) sep \
+ pair(LC_MESSAGES, lc_messages)
+
+// check ids and masks agree
+#define check_ids_and_masks_agree(id, _) \
+ static_assert((1 << id) == id##_MASK, "id and mask do not agree for " #id); \
+ static_assert((1 << id) == _CATMASK(id), "mask does not have expected value for " #id);
+CategoryList(check_ids_and_masks_agree,)
+#undef check_ids_and_masks_agree
+
+// check that LC_ALL_MASK is defined as expected
+#define get_mask(id, _) id##_MASK
+static_assert(LC_ALL_MASK == (CategoryList(get_mask, |)), "LC_ALL_MASK does not have the expected value. Check that its definition includes all supported categories");
+#undef get_mask
+
+
+// initialize c_locale
+#define init_clocale(id, locale_member) "C",
+static locale_struct c_locale = { LC_ALL_MASK, CategoryList(init_clocale, ) };
+#undef init_clocale
- // Check for errors.
- if (category_mask == LC_ALL_MASK && setlocale(LC_ALL, locale) == nullptr) {
+static locale_t current_locale = _LIBCPP_LC_GLOBAL_LOCALE;
+
+
+locale_t __c_locale() {
+ return &c_locale;
+}
+
+// locale
+locale_t newlocale(int category_mask, const char* locale, locale_t base) {
+ // start with some basic checks
+ if (! locale) {
errno = EINVAL;
- return (locale_t)0;
- } else {
- for (int _Cat = 0; _Cat <= _LC_MAX; ++_Cat) {
- if ((_CATMASK(_Cat) & category_mask) != 0 && setlocale(_Cat, locale) == nullptr) {
- setlocale(LC_ALL, current_loc_name.c_str());
- errno = EINVAL;
- return (locale_t)0;
- }
- }
+ return (locale_t) 0;
+ }
+ if (category_mask & ~LC_ALL_MASK) {
+ // then there are bits in category_mask that does not correspond
+ // to a valid category
+ errno = EINVAL;
+ return (locale_t) 0;
}
- // Create new locale.
- locale_t newloc = new locale_struct();
+ locale_t new_loc = new locale_struct;
+ int num_locales_not_found = 0;
+
+ if (base && base != _LIBCPP_LC_GLOBAL_LOCALE)
+ *new_loc = *base;
+
+ auto set_for_category = [&](int id, int mask, std::string &setting) {
+ const char *setting_to_apply = nullptr;
+
+ if (category_mask & mask)
+ setting_to_apply = locale;
+ else if (!base)
+ setting_to_apply = "C";
- if (base) {
- if (category_mask != LC_ALL_MASK) {
- // Copy base when it will not be overwritten.
- memcpy(newloc, base, sizeof(locale_struct));
- newloc->category_mask = category_mask | base->category_mask;
+ if (setting_to_apply) {
+ // setlocale takes the id, not the mask
+ const char *saved_setting = setlocale(id, nullptr);
+ if (setlocale(id, setting_to_apply)) {
+ // then setting_to_apply is valid for this category
+ // restore the saved setting
+ setlocale(id, saved_setting);
+
+ new_loc->category_mask |= mask;
+ setting = setting_to_apply;
+ } else {
+ // unknown locale for this category
+ num_locales_not_found++;
+ }
}
- delete base;
- } else {
- newloc->category_mask = category_mask;
+ };
+
+ // now overlay values
+#define Set(id, locale_member) set_for_category(id, id##_MASK, new_loc->locale_member)
+ CategoryList(Set, ;);
+#undef Set
+
+ if (num_locales_not_found != 0) {
+ delete new_loc;
+ errno = ENOENT;
+ new_loc = (locale_t) 0;
}
- if (category_mask & LC_COLLATE_MASK)
- newloc->lc_collate = locale;
- if (category_mask & LC_CTYPE_MASK)
- newloc->lc_ctype = locale;
- if (category_mask & LC_MONETARY_MASK)
- newloc->lc_monetary = locale;
- if (category_mask & LC_NUMERIC_MASK)
- newloc->lc_numeric = locale;
- if (category_mask & LC_TIME_MASK)
- newloc->lc_time = locale;
- if (category_mask & LC_MESSAGES_MASK)
- newloc->lc_messages = locale;
-
- // Restore current locale.
- setlocale(LC_ALL, current_loc_name.c_str());
- return (locale_t)newloc;
-}
-
-void freelocale(locale_t locobj) { delete locobj; }
-
-locale_t uselocale(locale_t newloc) {
- // Maintain current locale name(s).
- std::string current_loc_name(setlocale(LC_ALL, 0));
-
- if (newloc) {
- // Set locales and check for errors.
- bool is_error =
- (newloc->category_mask & LC_COLLATE_MASK && setlocale(LC_COLLATE, newloc->lc_collate.c_str()) == nullptr) ||
- (newloc->category_mask & LC_CTYPE_MASK && setlocale(LC_CTYPE, newloc->lc_ctype.c_str()) == nullptr) ||
- (newloc->category_mask & LC_MONETARY_MASK && setlocale(LC_MONETARY, newloc->lc_monetary.c_str()) == nullptr) ||
- (newloc->category_mask & LC_NUMERIC_MASK && setlocale(LC_NUMERIC, newloc->lc_numeric.c_str()) == nullptr) ||
- (newloc->category_mask & LC_TIME_MASK && setlocale(LC_TIME, newloc->lc_time.c_str()) == nullptr) ||
- (newloc->category_mask & LC_MESSAGES_MASK && setlocale(LC_MESSAGES, newloc->lc_messages.c_str()) == nullptr);
-
- if (is_error) {
- setlocale(LC_ALL, current_loc_name.c_str());
+ return new_loc;
+}
+
+void freelocale(locale_t locobj) {
+ if (locobj != nullptr && locobj != &c_locale && locobj != _LIBCPP_LC_GLOBAL_LOCALE)
+ delete locobj;
+}
+
+locale_t uselocale(locale_t new_loc) {
+ locale_t prev_loc = current_locale;
+
+ if (new_loc == _LIBCPP_LC_GLOBAL_LOCALE) {
+ current_locale = _LIBCPP_LC_GLOBAL_LOCALE;
+ } else if (new_loc != nullptr) {
+ locale_struct saved_locale;
+ saved_locale.category_mask = 0;
+
+ auto apply_category = [&](int id, int mask, std::string &setting, std::string &save_setting)-> bool {
+ if (new_loc->category_mask & mask) {
+ const char *old_setting = setlocale(id, setting.c_str());
+ if (old_setting) {
+ // we were able to set for this category. Save the old setting
+ // in case a subsequent category fails, and we need to restore
+ // all earlier settings.
+ saved_locale.category_mask |= mask;
+ save_setting = old_setting;
+ return true;
+ }
+ return false;
+ }
+ return true;
+ };
+
+#define Apply(id, locale_member) apply_category(id, id##_MASK, new_loc->locale_member, saved_locale. locale_member)
+ bool is_ok = CategoryList(Apply, &&);
+#undef Apply
+
+ if (!is_ok) {
+ auto restore = [&](int id, int mask, std::string &setting) {
+ if (saved_locale.category_mask & mask)
+ setlocale(id, setting.c_str());
+ };
+#define Restore(id, locale_member) restore(id, id##_MASK, saved_locale. locale_member);
+ CategoryList(Restore,);
+#undef Restore
errno = EINVAL;
- return (locale_t)0;
+ return nullptr;
}
+ current_locale = new_loc;
}
- // Construct and return previous locale.
- locale_t previous_loc = new locale_struct();
+ return prev_loc;
+}
- // current_loc_name might be a comma-separated locale name list.
- if (current_loc_name.find(',') != std::string::npos) {
- // Tokenize locale name list.
- const char delimiter = ',';
- std::vector<std::string> tokenized;
- std::stringstream ss(current_loc_name);
- std::string s;
+int isdigit_l(int __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::isdigit(__c);
+}
- while (std::getline(ss, s, delimiter)) {
- tokenized.push_back(s);
- }
+int isxdigit_l(int __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::isxdigit(__c);
+}
- _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(tokenized.size() >= _NCAT, "locale-name list is too short");
-
- previous_loc->lc_collate = tokenized[LC_COLLATE];
- previous_loc->lc_ctype = tokenized[LC_CTYPE];
- previous_loc->lc_monetary = tokenized[LC_MONETARY];
- previous_loc->lc_numeric = tokenized[LC_NUMERIC];
- previous_loc->lc_time = tokenized[LC_TIME];
- // Skip LC_TOD.
- previous_loc->lc_messages = tokenized[LC_MESSAGES];
- } else {
- previous_loc->lc_collate = current_loc_name;
- previous_loc->lc_ctype = current_loc_name;
- previous_loc->lc_monetary = current_loc_name;
- previous_loc->lc_numeric = current_loc_name;
- previous_loc->lc_time = current_loc_name;
- previous_loc->lc_messages = current_loc_name;
- }
+namespace __ibm {
+int isalnum_l(int __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::isalnum(__c);
+}
+
+int isalpha_l(int __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::isalpha(__c);
+}
+
+int isblank_l(int __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::isblank(__c);
+}
+
+int iscntrl_l(int __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::iscntrl(__c);
+}
+
+int isgraph_l(int __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::isgraph(__c);
+}
+
+int islower_l(int __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::islower(__c);
+}
+
+int isprint_l(int __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::isprint(__c);
+}
+
+int ispunct_l(int __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::ispunct(__c);
+}
+
+int isspace_l(int __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::isspace(__c);
+}
+
+int isupper_l(int __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::isupper(__c);
+}
+
+int iswalnum_l(wint_t __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::iswalnum(__c);
+}
+
+int iswalpha_l(wint_t __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::iswalpha(__c);
+}
+
+int iswblank_l(wint_t __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::iswblank(__c);
+}
+
+int iswcntrl_l(wint_t __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::iswcntrl(__c);
+}
+
+int iswdigit_l(wint_t __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::iswdigit(__c);
+}
+
+int iswgraph_l(wint_t __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::iswgraph(__c);
+}
+
+int iswlower_l(wint_t __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::iswlower(__c);
+}
+
+int iswprint_l(wint_t __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::iswprint(__c);
+}
+
+int iswpunct_l(wint_t __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::iswpunct(__c);
+}
+
+int iswspace_l(wint_t __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::iswspace(__c);
+}
+
+int iswupper_l(wint_t __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::iswupper(__c);
+}
+
+int iswxdigit_l(wint_t __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::iswxdigit(__c);
+}
+
+int toupper_l(int __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::toupper(__c);
+}
+
+int tolower_l(int __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::tolower(__c);
+}
+
+wint_t towupper_l(wint_t __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::towupper(__c);
+}
+
+wint_t towlower_l(wint_t __c, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::towlower(__c);
+}
+
+int strcoll_l(const char *__s1, const char *__s2, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::strcoll(__s1, __s2);
+}
+
+size_t strxfrm_l(char *__dest, const char *__src, size_t __n, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::strxfrm(__dest, __src, __n);
+}
+
+size_t strftime_l(char *__s, size_t __max, const char *__format, const struct tm *__tm,
+ locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::strftime(__s, __max, __format, __tm);
+}
+
+int wcscoll_l(const wchar_t *__ws1, const wchar_t *__ws2, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::wcscoll(__ws1, __ws2);
+}
- previous_loc->category_mask = LC_ALL_MASK;
- return previous_loc;
+size_t wcsxfrm_l(wchar_t *__dest, const wchar_t *__src, size_t __n, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::wcsxfrm(__dest, __src, __n);
}
-#ifdef __cplusplus
+int iswctype_l(wint_t __c, wctype_t __type, locale_t __l) {
+ __setAndRestore __newloc(__l);
+ return ::iswctype(__c, __type);
}
-#endif // __cplusplus
+} // namespace __ibm
+_LIBCPP_END_NAMESPACE_STD
|
You can test this locally with the following command:git-clang-format --diff 214fb43cb671d89d0e2da6dde348c6ffc360d7f0 50ff1120cf23244c8e59d82252b16c89bee7fa69 --extensions cpp,h -- libcxx/include/__locale_dir/locale_base_api/ibm.h libcxx/include/__thread/support/pthread.h libcxx/src/support/ibm/xlocale_zos.cppView the diff from clang-format here.diff --git a/libcxx/include/__locale_dir/locale_base_api/ibm.h b/libcxx/include/__locale_dir/locale_base_api/ibm.h
index c007c875d5..2830261ca1 100644
--- a/libcxx/include/__locale_dir/locale_base_api/ibm.h
+++ b/libcxx/include/__locale_dir/locale_base_api/ibm.h
@@ -30,7 +30,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#ifdef __MVS__
# define _LIBCPP_CLOC std::__c_locale()
# ifndef _LIBCPP_LC_GLOBAL_LOCALE
-# define _LIBCPP_LC_GLOBAL_LOCALE ((locale_t) -1)
+# define _LIBCPP_LC_GLOBAL_LOCALE ((locale_t) - 1)
# endif
#else
extern locale_t __cloc();
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
nanosleep
locale