xref: /openbsd-src/gnu/llvm/libcxx/include/__support/ibm/xlocale.h (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
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 {
__setAndRestore__setAndRestore34   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 
~__setAndRestore__setAndRestore43   ~__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
strtoll_l(const char * __nptr,char ** __endptr,int __base,locale_t locale)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
strtol_l(const char * __nptr,char ** __endptr,int __base,locale_t locale)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
strtod_l(const char * __nptr,char ** __endptr,locale_t locale)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
strtof_l(const char * __nptr,char ** __endptr,locale_t locale)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
strtold_l(const char * __nptr,char ** __endptr,locale_t locale)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
strtoull_l(const char * __nptr,char ** __endptr,int __base,locale_t locale)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
strtoul_l(const char * __nptr,char ** __endptr,int __base,locale_t locale)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
vasprintf(char ** strp,const char * fmt,va_list ap)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