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 20extern "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. 27static inline 28int isalnum_l(int c, locale_t locale) 29{ 30 return __xisalnum(locale, c); 31} 32static inline 33int isalpha_l(int c, locale_t locale) 34{ 35 return __xisalpha(locale, c); 36} 37static inline 38int isblank_l(int c, locale_t locale) 39{ 40 return __xisblank(locale, c); 41} 42static inline 43int iscntrl_l(int c, locale_t locale) 44{ 45 return __xiscntrl(locale, c); 46} 47static inline 48int isdigit_l(int c, locale_t locale) 49{ 50 return __xisdigit(locale, c); 51} 52static inline 53int isgraph_l(int c, locale_t locale) 54{ 55 return __xisgraph(locale, c); 56} 57static inline 58int islower_l(int c, locale_t locale) 59{ 60 return __xislower(locale, c); 61} 62static inline 63int isprint_l(int c, locale_t locale) 64{ 65 return __xisprint(locale, c); 66} 67 68static inline 69int ispunct_l(int c, locale_t locale) 70{ 71 return __xispunct(locale, c); 72} 73static inline 74int isspace_l(int c, locale_t locale) 75{ 76 return __xisspace(locale, c); 77} 78static inline 79int isupper_l(int c, locale_t locale) 80{ 81 return __xisupper(locale, c); 82} 83 84static inline 85int isxdigit_l(int c, locale_t locale) 86{ 87 return __xisxdigit(locale, c); 88} 89 90static inline 91int iswalnum_l(wchar_t wc, locale_t locale) 92{ 93 return __xiswalnum(locale, wc); 94} 95 96static inline 97int iswalpha_l(wchar_t wc, locale_t locale) 98{ 99 return __xiswalpha(locale, wc); 100} 101 102static inline 103int iswblank_l(wchar_t wc, locale_t locale) 104{ 105 return __xiswblank(locale, wc); 106} 107 108static inline 109int iswcntrl_l(wchar_t wc, locale_t locale) 110{ 111 return __xiswcntrl(locale, wc); 112} 113 114static inline 115int iswdigit_l(wchar_t wc, locale_t locale) 116{ 117 return __xiswdigit(locale, wc); 118} 119 120static inline 121int iswgraph_l(wchar_t wc, locale_t locale) 122{ 123 return __xiswgraph(locale, wc); 124} 125 126static inline 127int iswlower_l(wchar_t wc, locale_t locale) 128{ 129 return __xiswlower(locale, wc); 130} 131 132static inline 133int iswprint_l(wchar_t wc, locale_t locale) 134{ 135 return __xiswprint(locale, wc); 136} 137 138static inline 139int iswpunct_l(wchar_t wc, locale_t locale) 140{ 141 return __xiswpunct(locale, wc); 142} 143 144static inline 145int iswspace_l(wchar_t wc, locale_t locale) 146{ 147 return __xiswspace(locale, wc); 148} 149 150static inline 151int iswupper_l(wchar_t wc, locale_t locale) 152{ 153 return __xiswupper(locale, wc); 154} 155 156static inline 157int iswxdigit_l(wchar_t wc, locale_t locale) 158{ 159 return __xiswxdigit(locale, wc); 160} 161 162static inline 163int iswctype_l(wint_t wc, wctype_t desc, locale_t locale) 164{ 165 return __xiswctype(locale, wc, desc); 166} 167 168static inline 169int toupper_l(int c, locale_t locale) 170{ 171 return __xtoupper(locale, c); 172} 173static inline 174int tolower_l(int c, locale_t locale) 175{ 176 return __xtolower(locale, c); 177} 178static inline 179wint_t towupper_l(wint_t wc, locale_t locale) 180{ 181 return __xtowupper(locale, wc); 182} 183static inline 184wint_t towlower_l(wint_t wc, locale_t locale) 185{ 186 return __xtowlower(locale, wc); 187} 188 189static inline 190int strcoll_l(const char *__s1, const char *__s2, locale_t locale) 191{ 192 return __xstrcoll(locale, __s1, __s2); 193} 194static inline 195int wcscoll_l(const wchar_t *__s1, const wchar_t *__s2, locale_t locale) 196{ 197 return __xwcscoll(locale, __s1, __s2); 198} 199static inline 200size_t strxfrm_l(char *__s1, const char *__s2, size_t __n, locale_t locale) 201{ 202 return __xstrxfrm(locale, __s1, __s2, __n); 203} 204 205static inline 206size_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) 216static inline 217size_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 229namespace { 230 231struct __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 247private: 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 256static inline 257long 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 263static inline 264long 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 270static inline 271double strtod_l(const char *__nptr, char **__endptr, 272 locale_t locale) { 273 __setAndRestore __newloc(locale); 274 return strtod(__nptr, __endptr); 275} 276 277static inline 278float strtof_l(const char *__nptr, char **__endptr, 279 locale_t locale) { 280 __setAndRestore __newloc(locale); 281 return strtof(__nptr, __endptr); 282} 283 284static inline 285long double strtold_l(const char *__nptr, char **__endptr, 286 locale_t locale) { 287 __setAndRestore __newloc(locale); 288 return strtold(__nptr, __endptr); 289} 290 291static inline 292unsigned 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 298static inline 299unsigned 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 305static inline 306int 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(ap_copy, ap); 314 int str_size = vsnprintf(*strp, buff_size, fmt, ap_copy); 315 va_end(ap_copy); 316 317 if ((size_t) str_size >= buff_size) { 318 if ((*strp = (char *)realloc(*strp, str_size + 1)) == NULL) { 319 return -1; 320 } 321 str_size = vsnprintf(*strp, str_size + 1, fmt, ap); 322 } 323 return str_size; 324} 325 326#ifdef __cplusplus 327} 328#endif 329#endif // _LIBCPP_SUPPORT_IBM_XLOCALE_H 330