1 // -*- C++ -*- 2 //===-----------------------------------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef _LIBCPP_SUPPORT_IBM_XLOCALE_H 11 #define _LIBCPP_SUPPORT_IBM_XLOCALE_H 12 13 #include <__support/ibm/locale_mgmt_aix.h> 14 #include <__support/ibm/locale_mgmt_zos.h> 15 #include <stdarg.h> 16 17 #include "cstdlib" 18 19 #ifdef __cplusplus 20 extern "C" { 21 #endif 22 23 #if defined(_AIX) 24 #if !defined(_AIX71) 25 // AIX 7.1 and higher has these definitions. Definitions and stubs 26 // are provied here as a temporary workaround on AIX 6.1. 27 static inline 28 int isalnum_l(int c, locale_t locale) 29 { 30 return __xisalnum(locale, c); 31 } 32 static inline 33 int isalpha_l(int c, locale_t locale) 34 { 35 return __xisalpha(locale, c); 36 } 37 static inline 38 int isblank_l(int c, locale_t locale) 39 { 40 return __xisblank(locale, c); 41 } 42 static inline 43 int iscntrl_l(int c, locale_t locale) 44 { 45 return __xiscntrl(locale, c); 46 } 47 static inline 48 int isdigit_l(int c, locale_t locale) 49 { 50 return __xisdigit(locale, c); 51 } 52 static inline 53 int isgraph_l(int c, locale_t locale) 54 { 55 return __xisgraph(locale, c); 56 } 57 static inline 58 int islower_l(int c, locale_t locale) 59 { 60 return __xislower(locale, c); 61 } 62 static inline 63 int isprint_l(int c, locale_t locale) 64 { 65 return __xisprint(locale, c); 66 } 67 68 static inline 69 int ispunct_l(int c, locale_t locale) 70 { 71 return __xispunct(locale, c); 72 } 73 static inline 74 int isspace_l(int c, locale_t locale) 75 { 76 return __xisspace(locale, c); 77 } 78 static inline 79 int isupper_l(int c, locale_t locale) 80 { 81 return __xisupper(locale, c); 82 } 83 84 static inline 85 int isxdigit_l(int c, locale_t locale) 86 { 87 return __xisxdigit(locale, c); 88 } 89 90 static inline 91 int iswalnum_l(wchar_t wc, locale_t locale) 92 { 93 return __xiswalnum(locale, wc); 94 } 95 96 static inline 97 int iswalpha_l(wchar_t wc, locale_t locale) 98 { 99 return __xiswalpha(locale, wc); 100 } 101 102 static inline 103 int iswblank_l(wchar_t wc, locale_t locale) 104 { 105 return __xiswblank(locale, wc); 106 } 107 108 static inline 109 int iswcntrl_l(wchar_t wc, locale_t locale) 110 { 111 return __xiswcntrl(locale, wc); 112 } 113 114 static inline 115 int iswdigit_l(wchar_t wc, locale_t locale) 116 { 117 return __xiswdigit(locale, wc); 118 } 119 120 static inline 121 int iswgraph_l(wchar_t wc, locale_t locale) 122 { 123 return __xiswgraph(locale, wc); 124 } 125 126 static inline 127 int iswlower_l(wchar_t wc, locale_t locale) 128 { 129 return __xiswlower(locale, wc); 130 } 131 132 static inline 133 int iswprint_l(wchar_t wc, locale_t locale) 134 { 135 return __xiswprint(locale, wc); 136 } 137 138 static inline 139 int iswpunct_l(wchar_t wc, locale_t locale) 140 { 141 return __xiswpunct(locale, wc); 142 } 143 144 static inline 145 int iswspace_l(wchar_t wc, locale_t locale) 146 { 147 return __xiswspace(locale, wc); 148 } 149 150 static inline 151 int iswupper_l(wchar_t wc, locale_t locale) 152 { 153 return __xiswupper(locale, wc); 154 } 155 156 static inline 157 int iswxdigit_l(wchar_t wc, locale_t locale) 158 { 159 return __xiswxdigit(locale, wc); 160 } 161 162 static inline 163 int iswctype_l(wint_t wc, wctype_t desc, locale_t locale) 164 { 165 return __xiswctype(locale, wc, desc); 166 } 167 168 static inline 169 int toupper_l(int c, locale_t locale) 170 { 171 return __xtoupper(locale, c); 172 } 173 static inline 174 int tolower_l(int c, locale_t locale) 175 { 176 return __xtolower(locale, c); 177 } 178 static inline 179 wint_t towupper_l(wint_t wc, locale_t locale) 180 { 181 return __xtowupper(locale, wc); 182 } 183 static inline 184 wint_t towlower_l(wint_t wc, locale_t locale) 185 { 186 return __xtowlower(locale, wc); 187 } 188 189 static inline 190 int strcoll_l(const char *__s1, const char *__s2, locale_t locale) 191 { 192 return __xstrcoll(locale, __s1, __s2); 193 } 194 static inline 195 int wcscoll_l(const wchar_t *__s1, const wchar_t *__s2, locale_t locale) 196 { 197 return __xwcscoll(locale, __s1, __s2); 198 } 199 static inline 200 size_t strxfrm_l(char *__s1, const char *__s2, size_t __n, locale_t locale) 201 { 202 return __xstrxfrm(locale, __s1, __s2, __n); 203 } 204 205 static inline 206 size_t wcsxfrm_l(wchar_t *__ws1, const wchar_t *__ws2, size_t __n, 207 locale_t locale) 208 { 209 return __xwcsxfrm(locale, __ws1, __ws2, __n); 210 } 211 #endif // !defined(_AIX71) 212 213 // strftime_l() is defined by POSIX. However, AIX 7.1 and z/OS do not have it 214 // implemented yet. z/OS retrieves it from the POSIX fallbacks. 215 #if !defined(_AIX72) 216 static inline 217 size_t strftime_l(char *__s, size_t __size, const char *__fmt, 218 const struct tm *__tm, locale_t locale) { 219 return __xstrftime(locale, __s, __size, __fmt, __tm); 220 } 221 #endif 222 223 #elif defined(__MVS__) 224 #include <wctype.h> 225 // POSIX routines 226 #include <__support/xlocale/__posix_l_fallback.h> 227 #endif // defined(__MVS__) 228 229 namespace { 230 231 struct __setAndRestore { 232 explicit __setAndRestore(locale_t locale) { 233 if (locale == (locale_t)0) { 234 __cloc = newlocale(LC_ALL_MASK, "C", /* base */ (locale_t)0); 235 __stored = uselocale(__cloc); 236 } else { 237 __stored = uselocale(locale); 238 } 239 } 240 241 ~__setAndRestore() { 242 uselocale(__stored); 243 if (__cloc) 244 freelocale(__cloc); 245 } 246 247 private: 248 locale_t __stored = (locale_t)0; 249 locale_t __cloc = (locale_t)0; 250 }; 251 252 } // namespace 253 254 // The following are not POSIX routines. These are quick-and-dirty hacks 255 // to make things pretend to work 256 static inline 257 long long strtoll_l(const char *__nptr, char **__endptr, 258 int __base, locale_t locale) { 259 __setAndRestore __newloc(locale); 260 return strtoll(__nptr, __endptr, __base); 261 } 262 263 static inline 264 long strtol_l(const char *__nptr, char **__endptr, 265 int __base, locale_t locale) { 266 __setAndRestore __newloc(locale); 267 return strtol(__nptr, __endptr, __base); 268 } 269 270 static inline 271 double strtod_l(const char *__nptr, char **__endptr, 272 locale_t locale) { 273 __setAndRestore __newloc(locale); 274 return strtod(__nptr, __endptr); 275 } 276 277 static inline 278 float strtof_l(const char *__nptr, char **__endptr, 279 locale_t locale) { 280 __setAndRestore __newloc(locale); 281 return strtof(__nptr, __endptr); 282 } 283 284 static inline 285 long double strtold_l(const char *__nptr, char **__endptr, 286 locale_t locale) { 287 __setAndRestore __newloc(locale); 288 return strtold(__nptr, __endptr); 289 } 290 291 static inline 292 unsigned long long strtoull_l(const char *__nptr, char **__endptr, 293 int __base, locale_t locale) { 294 __setAndRestore __newloc(locale); 295 return strtoull(__nptr, __endptr, __base); 296 } 297 298 static inline 299 unsigned long strtoul_l(const char *__nptr, char **__endptr, 300 int __base, locale_t locale) { 301 __setAndRestore __newloc(locale); 302 return strtoul(__nptr, __endptr, __base); 303 } 304 305 static inline 306 int vasprintf(char **strp, const char *fmt, va_list ap) { 307 const size_t buff_size = 256; 308 if ((*strp = (char *)malloc(buff_size)) == NULL) { 309 return -1; 310 } 311 312 va_list ap_copy; 313 // va_copy may not be provided by the C library in C++ 03 mode. 314 #if defined(_LIBCPP_CXX03_LANG) && __has_builtin(__builtin_va_copy) 315 __builtin_va_copy(ap_copy, ap); 316 #else 317 va_copy(ap_copy, ap); 318 #endif 319 int str_size = vsnprintf(*strp, buff_size, fmt, ap_copy); 320 va_end(ap_copy); 321 322 if ((size_t) str_size >= buff_size) { 323 if ((*strp = (char *)realloc(*strp, str_size + 1)) == NULL) { 324 return -1; 325 } 326 str_size = vsnprintf(*strp, str_size + 1, fmt, ap); 327 } 328 return str_size; 329 } 330 331 #ifdef __cplusplus 332 } 333 #endif 334 #endif // _LIBCPP_SUPPORT_IBM_XLOCALE_H 335