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 #if defined(__MVS__) 14 #include <__support/ibm/locale_mgmt_zos.h> 15 #endif // defined(__MVS__) 16 17 #include <stdarg.h> 18 19 #include "cstdlib" 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 #if defined(__MVS__) 26 #include <wctype.h> 27 // POSIX routines 28 #include <__support/xlocale/__posix_l_fallback.h> 29 #endif // defined(__MVS__) 30 31 namespace { 32 33 struct __setAndRestore { 34 explicit __setAndRestore(locale_t locale) { 35 if (locale == (locale_t)0) { 36 __cloc = newlocale(LC_ALL_MASK, "C", /* base */ (locale_t)0); 37 __stored = uselocale(__cloc); 38 } else { 39 __stored = uselocale(locale); 40 } 41 } 42 43 ~__setAndRestore() { 44 uselocale(__stored); 45 if (__cloc) 46 freelocale(__cloc); 47 } 48 49 private: 50 locale_t __stored = (locale_t)0; 51 locale_t __cloc = (locale_t)0; 52 }; 53 54 } // namespace 55 56 // The following are not POSIX routines. These are quick-and-dirty hacks 57 // to make things pretend to work 58 inline _LIBCPP_HIDE_FROM_ABI long long 59 strtoll_l(const char *__nptr, char **__endptr, int __base, locale_t locale) { 60 __setAndRestore __newloc(locale); 61 return ::strtoll(__nptr, __endptr, __base); 62 } 63 64 inline _LIBCPP_HIDE_FROM_ABI long 65 strtol_l(const char *__nptr, char **__endptr, int __base, locale_t locale) { 66 __setAndRestore __newloc(locale); 67 return ::strtol(__nptr, __endptr, __base); 68 } 69 70 inline _LIBCPP_HIDE_FROM_ABI double 71 strtod_l(const char *__nptr, char **__endptr, locale_t locale) { 72 __setAndRestore __newloc(locale); 73 return ::strtod(__nptr, __endptr); 74 } 75 76 inline _LIBCPP_HIDE_FROM_ABI float 77 strtof_l(const char *__nptr, char **__endptr, locale_t locale) { 78 __setAndRestore __newloc(locale); 79 return ::strtof(__nptr, __endptr); 80 } 81 82 inline _LIBCPP_HIDE_FROM_ABI long double 83 strtold_l(const char *__nptr, char **__endptr, locale_t locale) { 84 __setAndRestore __newloc(locale); 85 return ::strtold(__nptr, __endptr); 86 } 87 88 inline _LIBCPP_HIDE_FROM_ABI unsigned long long 89 strtoull_l(const char *__nptr, char **__endptr, int __base, locale_t locale) { 90 __setAndRestore __newloc(locale); 91 return ::strtoull(__nptr, __endptr, __base); 92 } 93 94 inline _LIBCPP_HIDE_FROM_ABI unsigned long 95 strtoul_l(const char *__nptr, char **__endptr, int __base, locale_t locale) { 96 __setAndRestore __newloc(locale); 97 return ::strtoul(__nptr, __endptr, __base); 98 } 99 100 inline _LIBCPP_HIDE_FROM_ABI int 101 vasprintf(char **strp, const char *fmt, va_list ap) { 102 const size_t buff_size = 256; 103 if ((*strp = (char *)malloc(buff_size)) == NULL) { 104 return -1; 105 } 106 107 va_list ap_copy; 108 // va_copy may not be provided by the C library in C++ 03 mode. 109 #if defined(_LIBCPP_CXX03_LANG) && __has_builtin(__builtin_va_copy) 110 __builtin_va_copy(ap_copy, ap); 111 #else 112 va_copy(ap_copy, ap); 113 #endif 114 int str_size = vsnprintf(*strp, buff_size, fmt, ap_copy); 115 va_end(ap_copy); 116 117 if ((size_t) str_size >= buff_size) { 118 if ((*strp = (char *)realloc(*strp, str_size + 1)) == NULL) { 119 return -1; 120 } 121 str_size = vsnprintf(*strp, str_size + 1, fmt, ap); 122 } 123 return str_size; 124 } 125 126 #ifdef __cplusplus 127 } 128 #endif 129 #endif // _LIBCPP___SUPPORT_IBM_XLOCALE_H 130