Skip to content

Commit 8444d45

Browse files
committed
Move z/OS to new locale API and resolve all name collisions
1 parent 1c837ec commit 8444d45

File tree

17 files changed

+1069
-105
lines changed

17 files changed

+1069
-105
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ set(files
532532
__locale_dir/support/no_locale/characters.h
533533
__locale_dir/support/no_locale/strtonum.h
534534
__locale_dir/support/windows.h
535+
__locale_dir/support/zos.h
535536
__locale_dir/time.h
536537
__locale_dir/wbuffer_convert.h
537538
__locale_dir/wstring_convert.h
@@ -755,6 +756,7 @@ set(files
755756
__support/ibm/gettod_zos.h
756757
__support/ibm/locale_mgmt_zos.h
757758
__support/ibm/nanosleep.h
759+
__support/ibm/vasprintf.h
758760
__support/xlocale/__nop_locale_mgmt.h
759761
__support/xlocale/__posix_l_fallback.h
760762
__support/xlocale/__strtonum_fallback.h

libcxx/include/__locale_dir/locale_base_api.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
# pragma GCC system_header
1616
#endif
1717

18+
LIBCPP_PUSH_MACROS
19+
#include <__undef_macros>
20+
1821
// The platform-specific headers have to provide the following interface.
1922
//
2023
// These functions are equivalent to their C counterparts, except that __locale::__locale_t
@@ -121,13 +124,15 @@
121124
# include <__locale_dir/support/fuchsia.h>
122125
# elif defined(__linux__)
123126
# include <__locale_dir/support/linux.h>
127+
# elif defined(__MVS__)
128+
# include <__locale_dir/support/zos.h>
124129
# else
125130

126131
// TODO: This is a temporary definition to bridge between the old way we defined the locale base API
127132
// (by providing global non-reserved names) and the new API. As we move individual platforms
128133
// towards the new way of defining the locale base API, this should disappear since each platform
129134
// will define those directly.
130-
# if defined(_AIX) || defined(__MVS__)
135+
# if defined(_AIX)
131136
# include <__locale_dir/locale_base_api/ibm.h>
132137
# elif defined(__OpenBSD__)
133138
# include <__locale_dir/locale_base_api/openbsd.h>
@@ -317,4 +322,6 @@ _LIBCPP_END_NAMESPACE_STD
317322

318323
#endif // _LIBCPP_HAS_LOCALIZATION
319324

325+
_LIBCPP_POP_MACROS
326+
320327
#endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H
Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
//===-----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef _LIBCPP___LOCALE_DIR_SUPPORT_IBM_H
10+
#define _LIBCPP___LOCALE_DIR_SUPPORT_IBM_H
11+
12+
#include <__support/ibm/locale_mgmt_zos.h>
13+
#include <__support/ibm/vasprintf.h>
14+
15+
#include "cstdlib"
16+
#include <clocale> // std::lconv
17+
#include <locale.h>
18+
#include <stdarg.h>
19+
#include <stdio.h>
20+
21+
#include <wctype.h>
22+
23+
_LIBCPP_BEGIN_NAMESPACE_STD
24+
25+
// These functions are exported within std namespace
26+
// for compatibility with previous versions.
27+
_LIBCPP_EXPORTED_FROM_ABI int isdigit_l(int, locale_t);
28+
_LIBCPP_EXPORTED_FROM_ABI int isxdigit_l(int, locale_t);
29+
30+
namespace __locale {
31+
struct __locale_guard {
32+
_LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t& __loc) : __old_loc_(std::uselocale(__loc)) {}
33+
34+
_LIBCPP_HIDE_FROM_ABI ~__locale_guard() {
35+
// if (__old_loc_)
36+
if (__old_loc_ != (locale_t)0)
37+
std::uselocale(__old_loc_);
38+
}
39+
40+
locale_t __old_loc_;
41+
42+
__locale_guard(__locale_guard const&) = delete;
43+
__locale_guard& operator=(__locale_guard const&) = delete;
44+
};
45+
46+
//
47+
// Locale management
48+
//
49+
#define _LIBCPP_COLLATE_MASK LC_COLLATE_MASK
50+
#define _LIBCPP_CTYPE_MASK LC_CTYPE_MASK
51+
#define _LIBCPP_MONETARY_MASK LC_MONETARY_MASK
52+
#define _LIBCPP_NUMERIC_MASK LC_NUMERIC_MASK
53+
#define _LIBCPP_TIME_MASK LC_TIME_MASK
54+
#define _LIBCPP_MESSAGES_MASK LC_MESSAGES_MASK
55+
#define _LIBCPP_ALL_MASK LC_ALL_MASK
56+
#define _LIBCPP_LC_ALL LC_ALL
57+
58+
#define _LIBCPP_CLOC std::__c_locale()
59+
#ifndef _LIBCPP_LC_GLOBAL_LOCALE
60+
# define _LIBCPP_LC_GLOBAL_LOCALE ((locale_t) - 1)
61+
#endif
62+
63+
using __locale_t _LIBCPP_NODEBUG = locale_t;
64+
65+
#if defined(_LIBCPP_BUILDING_LIBRARY)
66+
using __lconv_t _LIBCPP_NODEBUG = std::lconv;
67+
68+
inline _LIBCPP_HIDE_FROM_ABI __locale_t __newlocale(int __category_mask, const char* __locale, __locale_t __base) {
69+
return newlocale(__category_mask, __locale, __base);
70+
}
71+
72+
inline _LIBCPP_HIDE_FROM_ABI void __freelocale(__locale_t __loc) { freelocale(__loc); }
73+
74+
inline _LIBCPP_HIDE_FROM_ABI char* __setlocale(int __category, char const* __locale) {
75+
return ::setlocale(__category, __locale);
76+
}
77+
78+
inline _LIBCPP_HIDE_FROM_ABI __lconv_t* __localeconv(__locale_t& __loc) {
79+
__locale_guard __current(__loc);
80+
return std::localeconv();
81+
}
82+
#endif // _LIBCPP_BUILDING_LIBRARY
83+
84+
// The following are not POSIX routines. These are quick-and-dirty hacks
85+
// to make things pretend to work
86+
87+
//
88+
// Strtonum functions
89+
//
90+
inline _LIBCPP_HIDE_FROM_ABI float __strtof(const char* __nptr, char** __endptr, __locale_t __loc) {
91+
__locale_guard __newloc(__loc);
92+
return ::strtof(__nptr, __endptr);
93+
}
94+
95+
inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr, __locale_t __loc) {
96+
__locale_guard __newloc(__loc);
97+
return ::strtod(__nptr, __endptr);
98+
}
99+
100+
inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __endptr, __locale_t __loc) {
101+
__locale_guard __newloc(__loc);
102+
return ::strtold(__nptr, __endptr);
103+
}
104+
105+
inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
106+
__locale_guard __newloc(__loc);
107+
return ::strtoll(__nptr, __endptr, __base);
108+
}
109+
110+
inline _LIBCPP_HIDE_FROM_ABI unsigned long long
111+
__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
112+
__locale_guard __newloc(__loc);
113+
return ::strtoull(__nptr, __endptr, __base);
114+
}
115+
116+
//
117+
// Character manipulation functions
118+
//
119+
namespace __ibm {
120+
_LIBCPP_HIDE_FROM_ABI int islower_l(int, __locale_t);
121+
_LIBCPP_HIDE_FROM_ABI int isupper_l(int, __locale_t);
122+
_LIBCPP_HIDE_FROM_ABI int iswalpha_l(wint_t, __locale_t);
123+
_LIBCPP_HIDE_FROM_ABI int iswblank_l(wint_t, __locale_t);
124+
_LIBCPP_HIDE_FROM_ABI int iswcntrl_l(wint_t, __locale_t);
125+
_LIBCPP_HIDE_FROM_ABI int iswdigit_l(wint_t, __locale_t);
126+
_LIBCPP_HIDE_FROM_ABI int iswlower_l(wint_t, __locale_t);
127+
_LIBCPP_HIDE_FROM_ABI int iswprint_l(wint_t, __locale_t);
128+
_LIBCPP_HIDE_FROM_ABI int iswpunct_l(wint_t, __locale_t);
129+
_LIBCPP_HIDE_FROM_ABI int iswspace_l(wint_t, __locale_t);
130+
_LIBCPP_HIDE_FROM_ABI int iswupper_l(wint_t, __locale_t);
131+
_LIBCPP_HIDE_FROM_ABI int iswxdigit_l(wint_t, __locale_t);
132+
_LIBCPP_HIDE_FROM_ABI int toupper_l(int, __locale_t);
133+
_LIBCPP_HIDE_FROM_ABI int tolower_l(int, __locale_t);
134+
_LIBCPP_HIDE_FROM_ABI wint_t towupper_l(wint_t, __locale_t);
135+
_LIBCPP_HIDE_FROM_ABI wint_t towlower_l(wint_t, __locale_t);
136+
_LIBCPP_HIDE_FROM_ABI int strcoll_l(const char*, const char*, __locale_t);
137+
_LIBCPP_HIDE_FROM_ABI size_t strxfrm_l(char*, const char*, size_t, __locale_t);
138+
_LIBCPP_HIDE_FROM_ABI size_t strftime_l(char*, size_t, const char*, const struct tm*, __locale_t);
139+
_LIBCPP_HIDE_FROM_ABI int wcscoll_l(const wchar_t*, const wchar_t*, __locale_t);
140+
_LIBCPP_HIDE_FROM_ABI size_t wcsxfrm_l(wchar_t*, const wchar_t*, size_t, __locale_t);
141+
_LIBCPP_HIDE_FROM_ABI int iswctype_l(wint_t, wctype_t, __locale_t);
142+
_LIBCPP_HIDE_FROM_ABI size_t mbsnrtowcs(wchar_t*, const char**, size_t, size_t, mbstate_t*);
143+
_LIBCPP_HIDE_FROM_ABI size_t wcsnrtombs(char*, const wchar_t**, size_t, size_t, mbstate_t*);
144+
145+
// These functions are not used internally by libcxx
146+
// and are included for completness.
147+
_LIBCPP_HIDE_FROM_ABI int isalnum_l(int, __locale_t);
148+
_LIBCPP_HIDE_FROM_ABI int isalpha_l(int, __locale_t);
149+
_LIBCPP_HIDE_FROM_ABI int isblank_l(int, __locale_t);
150+
_LIBCPP_HIDE_FROM_ABI int iscntrl_l(int, __locale_t);
151+
_LIBCPP_HIDE_FROM_ABI int isgraph_l(int, __locale_t);
152+
_LIBCPP_HIDE_FROM_ABI int isprint_l(int, __locale_t);
153+
_LIBCPP_HIDE_FROM_ABI int ispunct_l(int, __locale_t);
154+
_LIBCPP_HIDE_FROM_ABI int isspace_l(int, __locale_t);
155+
_LIBCPP_HIDE_FROM_ABI int iswalnum_l(wint_t, __locale_t);
156+
_LIBCPP_HIDE_FROM_ABI int iswgraph_l(wint_t, __locale_t);
157+
} // namespace __ibm
158+
159+
using namespace __ibm;
160+
161+
#if defined(_LIBCPP_BUILDING_LIBRARY)
162+
inline _LIBCPP_HIDE_FROM_ABI int __islower(int __c, __locale_t __loc) { return islower_l(__c, __loc); }
163+
164+
inline _LIBCPP_HIDE_FROM_ABI int __isupper(int __c, __locale_t __loc) { return isupper_l(__c, __loc); }
165+
#endif
166+
167+
inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t __loc) { return isdigit_l(__c, __loc); }
168+
169+
inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t __loc) { return isxdigit_l(__c, __loc); }
170+
171+
#if defined(_LIBCPP_BUILDING_LIBRARY)
172+
inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return toupper_l(__c, __loc); }
173+
174+
inline _LIBCPP_HIDE_FROM_ABI int __tolower(int __c, __locale_t __loc) { return tolower_l(__c, __loc); }
175+
176+
inline _LIBCPP_HIDE_FROM_ABI int __strcoll(const char* __s1, const char* __s2, __locale_t __loc) {
177+
return strcoll_l(__s1, __s2, __loc);
178+
}
179+
180+
inline _LIBCPP_HIDE_FROM_ABI size_t __strxfrm(char* __dest, const char* __src, size_t __n, __locale_t __loc) {
181+
return strxfrm_l(__dest, __src, __n, __loc);
182+
}
183+
184+
# if _LIBCPP_HAS_WIDE_CHARACTERS
185+
inline _LIBCPP_HIDE_FROM_ABI int __iswctype(wint_t __c, wctype_t __type, __locale_t __loc) {
186+
return iswctype_l(__c, __type, __loc);
187+
}
188+
189+
inline _LIBCPP_HIDE_FROM_ABI int __iswspace(wint_t __c, __locale_t __loc) { return iswspace_l(__c, __loc); }
190+
191+
inline _LIBCPP_HIDE_FROM_ABI int __iswprint(wint_t __c, __locale_t __loc) { return iswprint_l(__c, __loc); }
192+
193+
inline _LIBCPP_HIDE_FROM_ABI int __iswcntrl(wint_t __c, __locale_t __loc) { return iswcntrl_l(__c, __loc); }
194+
195+
inline _LIBCPP_HIDE_FROM_ABI int __iswupper(wint_t __c, __locale_t __loc) { return iswupper_l(__c, __loc); }
196+
197+
inline _LIBCPP_HIDE_FROM_ABI int __iswlower(wint_t __c, __locale_t __loc) { return iswlower_l(__c, __loc); }
198+
199+
inline _LIBCPP_HIDE_FROM_ABI int __iswalpha(wint_t __c, __locale_t __loc) { return iswalpha_l(__c, __loc); }
200+
201+
inline _LIBCPP_HIDE_FROM_ABI int __iswblank(wint_t __c, __locale_t __loc) { return iswblank_l(__c, __loc); }
202+
203+
inline _LIBCPP_HIDE_FROM_ABI int __iswdigit(wint_t __c, __locale_t __loc) { return iswdigit_l(__c, __loc); }
204+
205+
inline _LIBCPP_HIDE_FROM_ABI int __iswpunct(wint_t __c, __locale_t __loc) { return iswpunct_l(__c, __loc); }
206+
207+
inline _LIBCPP_HIDE_FROM_ABI int __iswxdigit(wint_t __c, __locale_t __loc) { return iswxdigit_l(__c, __loc); }
208+
209+
inline _LIBCPP_HIDE_FROM_ABI wint_t __towupper(wint_t __c, __locale_t __loc) { return towupper_l(__c, __loc); }
210+
211+
inline _LIBCPP_HIDE_FROM_ABI wint_t __towlower(wint_t __c, __locale_t __loc) { return towlower_l(__c, __loc); }
212+
213+
inline _LIBCPP_HIDE_FROM_ABI int __wcscoll(const wchar_t* __ws1, const wchar_t* __ws2, __locale_t __loc) {
214+
return wcscoll_l(__ws1, __ws2, __loc);
215+
}
216+
217+
inline _LIBCPP_HIDE_FROM_ABI size_t __wcsxfrm(wchar_t* __dest, const wchar_t* __src, size_t __n, __locale_t __loc) {
218+
return wcsxfrm_l(__dest, __src, __n, __loc);
219+
}
220+
# endif // _LIBCPP_HAS_WIDE_CHARACTERS
221+
222+
inline _LIBCPP_HIDE_FROM_ABI
223+
size_t __strftime(char* __s, size_t __max, const char* __format, const struct tm* __tm, __locale_t __loc) {
224+
return strftime_l(__s, __max, __format, __tm, __loc);
225+
}
226+
227+
//
228+
// Other functions
229+
//
230+
inline _LIBCPP_HIDE_FROM_ABI decltype(MB_CUR_MAX) __mb_len_max(__locale_t __loc) {
231+
__locale_guard __current(__loc);
232+
return MB_CUR_MAX;
233+
}
234+
235+
# if _LIBCPP_HAS_WIDE_CHARACTERS
236+
inline _LIBCPP_HIDE_FROM_ABI wint_t __btowc(int __c, __locale_t __loc) {
237+
__locale_guard __current(__loc);
238+
return std::btowc(__c);
239+
}
240+
241+
inline _LIBCPP_HIDE_FROM_ABI int __wctob(wint_t __c, __locale_t __loc) {
242+
__locale_guard __current(__loc);
243+
return std::wctob(__c);
244+
}
245+
246+
inline _LIBCPP_HIDE_FROM_ABI size_t
247+
__wcsnrtombs(char* __dest, const wchar_t** __src, size_t __nwc, size_t __len, mbstate_t* __ps, __locale_t __loc) {
248+
__locale_guard __current(__loc);
249+
return wcsnrtombs(__dest, __src, __nwc, __len, __ps); // non-standard
250+
}
251+
252+
inline _LIBCPP_HIDE_FROM_ABI size_t __wcrtomb(char* __s, wchar_t __wc, mbstate_t* __ps, __locale_t __loc) {
253+
__locale_guard __current(__loc);
254+
return std::wcrtomb(__s, __wc, __ps);
255+
}
256+
257+
inline _LIBCPP_HIDE_FROM_ABI size_t
258+
__mbsnrtowcs(wchar_t* __dest, const char** __src, size_t __nms, size_t __len, mbstate_t* __ps, __locale_t __loc) {
259+
__locale_guard __current(__loc);
260+
return mbsnrtowcs(__dest, __src, __nms, __len, __ps); // non-standard
261+
}
262+
263+
inline _LIBCPP_HIDE_FROM_ABI size_t
264+
__mbrtowc(wchar_t* __pwc, const char* __s, size_t __n, mbstate_t* __ps, __locale_t __loc) {
265+
__locale_guard __current(__loc);
266+
return std::mbrtowc(__pwc, __s, __n, __ps);
267+
}
268+
269+
inline _LIBCPP_HIDE_FROM_ABI int __mbtowc(wchar_t* __pwc, const char* __pmb, size_t __max, __locale_t __loc) {
270+
__locale_guard __current(__loc);
271+
return std::mbtowc(__pwc, __pmb, __max);
272+
}
273+
274+
inline _LIBCPP_HIDE_FROM_ABI size_t __mbrlen(const char* __s, size_t __n, mbstate_t* __ps, __locale_t __loc) {
275+
__locale_guard __current(__loc);
276+
return std::mbrlen(__s, __n, __ps);
277+
}
278+
279+
inline _LIBCPP_HIDE_FROM_ABI size_t
280+
__mbsrtowcs(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps, __locale_t __loc) {
281+
__locale_guard __current(__loc);
282+
return std::mbsrtowcs(__dest, __src, __len, __ps);
283+
}
284+
# endif // _LIBCPP_BUILDING_LIBRARY
285+
#endif // _LIBCPP_HAS_WIDE_CHARACTERS
286+
287+
_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __snprintf(
288+
char* __s, size_t __n, __locale_t __loc, const char* __format, ...) {
289+
va_list __va;
290+
va_start(__va, __format);
291+
__locale_guard __current(__loc);
292+
int __res = std::vsnprintf(__s, __n, __format, __va);
293+
va_end(__va);
294+
return __res;
295+
}
296+
297+
_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __asprintf(
298+
char** __s, __locale_t __loc, const char* __format, ...) {
299+
va_list __va;
300+
va_start(__va, __format);
301+
__locale_guard __current(__loc);
302+
int __res = std::__ibm::vasprintf(__s, __format, __va); // non-standard
303+
va_end(__va);
304+
return __res;
305+
}
306+
307+
_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf(
308+
const char* __s, __locale_t __loc, const char* __format, ...) {
309+
va_list __va;
310+
va_start(__va, __format);
311+
__locale_guard __current(__loc);
312+
int __res = std::vsscanf(__s, __format, __va);
313+
va_end(__va);
314+
return __res;
315+
}
316+
} // namespace __locale
317+
_LIBCPP_END_NAMESPACE_STD
318+
#endif // _LIBCPP___LOCALE_DIR_SUPPORT_IBM_H

0 commit comments

Comments
 (0)