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