xref: /openbsd-src/gnu/llvm/libcxx/include/__support/ibm/xlocale.h (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
176d0caaeSpatrick // -*- C++ -*-
276d0caaeSpatrick //===-----------------------------------------------------------------------===//
376d0caaeSpatrick //
476d0caaeSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
576d0caaeSpatrick // See https://llvm.org/LICENSE.txt for license information.
676d0caaeSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
776d0caaeSpatrick //
876d0caaeSpatrick //===----------------------------------------------------------------------===//
976d0caaeSpatrick 
10*4bdff4beSrobert #ifndef _LIBCPP___SUPPORT_IBM_XLOCALE_H
11*4bdff4beSrobert #define _LIBCPP___SUPPORT_IBM_XLOCALE_H
1276d0caaeSpatrick 
13*4bdff4beSrobert #if defined(__MVS__)
1476d0caaeSpatrick #include <__support/ibm/locale_mgmt_zos.h>
15*4bdff4beSrobert #endif // defined(__MVS__)
16*4bdff4beSrobert 
1776d0caaeSpatrick #include <stdarg.h>
1876d0caaeSpatrick 
1976d0caaeSpatrick #include "cstdlib"
2076d0caaeSpatrick 
2176d0caaeSpatrick #ifdef __cplusplus
2276d0caaeSpatrick extern "C" {
2376d0caaeSpatrick #endif
2476d0caaeSpatrick 
25*4bdff4beSrobert #if defined(__MVS__)
2676d0caaeSpatrick #include <wctype.h>
2776d0caaeSpatrick // POSIX routines
2876d0caaeSpatrick #include <__support/xlocale/__posix_l_fallback.h>
2976d0caaeSpatrick #endif // defined(__MVS__)
3076d0caaeSpatrick 
3176d0caaeSpatrick namespace {
3276d0caaeSpatrick 
3376d0caaeSpatrick struct __setAndRestore {
__setAndRestore__setAndRestore3476d0caaeSpatrick   explicit __setAndRestore(locale_t locale) {
3576d0caaeSpatrick     if (locale == (locale_t)0) {
3676d0caaeSpatrick       __cloc = newlocale(LC_ALL_MASK, "C", /* base */ (locale_t)0);
3776d0caaeSpatrick       __stored = uselocale(__cloc);
3876d0caaeSpatrick     } else {
3976d0caaeSpatrick       __stored = uselocale(locale);
4076d0caaeSpatrick     }
4176d0caaeSpatrick   }
4276d0caaeSpatrick 
~__setAndRestore__setAndRestore4376d0caaeSpatrick   ~__setAndRestore() {
4476d0caaeSpatrick     uselocale(__stored);
4576d0caaeSpatrick     if (__cloc)
4676d0caaeSpatrick       freelocale(__cloc);
4776d0caaeSpatrick   }
4876d0caaeSpatrick 
4976d0caaeSpatrick private:
5076d0caaeSpatrick   locale_t __stored = (locale_t)0;
5176d0caaeSpatrick   locale_t __cloc = (locale_t)0;
5276d0caaeSpatrick };
5376d0caaeSpatrick 
5476d0caaeSpatrick } // namespace
5576d0caaeSpatrick 
5676d0caaeSpatrick // The following are not POSIX routines.  These are quick-and-dirty hacks
5776d0caaeSpatrick // to make things pretend to work
58*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI long long
strtoll_l(const char * __nptr,char ** __endptr,int __base,locale_t locale)59*4bdff4beSrobert strtoll_l(const char *__nptr, char **__endptr, int __base, locale_t locale) {
6076d0caaeSpatrick   __setAndRestore __newloc(locale);
61*4bdff4beSrobert   return ::strtoll(__nptr, __endptr, __base);
6276d0caaeSpatrick }
6376d0caaeSpatrick 
64*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI long
strtol_l(const char * __nptr,char ** __endptr,int __base,locale_t locale)65*4bdff4beSrobert strtol_l(const char *__nptr, char **__endptr, int __base, locale_t locale) {
6676d0caaeSpatrick   __setAndRestore __newloc(locale);
67*4bdff4beSrobert   return ::strtol(__nptr, __endptr, __base);
6876d0caaeSpatrick }
6976d0caaeSpatrick 
70*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI double
strtod_l(const char * __nptr,char ** __endptr,locale_t locale)71*4bdff4beSrobert strtod_l(const char *__nptr, char **__endptr, locale_t locale) {
7276d0caaeSpatrick   __setAndRestore __newloc(locale);
73*4bdff4beSrobert   return ::strtod(__nptr, __endptr);
7476d0caaeSpatrick }
7576d0caaeSpatrick 
76*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI float
strtof_l(const char * __nptr,char ** __endptr,locale_t locale)77*4bdff4beSrobert strtof_l(const char *__nptr, char **__endptr, locale_t locale) {
7876d0caaeSpatrick   __setAndRestore __newloc(locale);
79*4bdff4beSrobert   return ::strtof(__nptr, __endptr);
8076d0caaeSpatrick }
8176d0caaeSpatrick 
82*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI long double
strtold_l(const char * __nptr,char ** __endptr,locale_t locale)83*4bdff4beSrobert strtold_l(const char *__nptr, char **__endptr, locale_t locale) {
8476d0caaeSpatrick   __setAndRestore __newloc(locale);
85*4bdff4beSrobert   return ::strtold(__nptr, __endptr);
8676d0caaeSpatrick }
8776d0caaeSpatrick 
88*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI unsigned long long
strtoull_l(const char * __nptr,char ** __endptr,int __base,locale_t locale)89*4bdff4beSrobert strtoull_l(const char *__nptr, char **__endptr, int __base, locale_t locale) {
9076d0caaeSpatrick   __setAndRestore __newloc(locale);
91*4bdff4beSrobert   return ::strtoull(__nptr, __endptr, __base);
9276d0caaeSpatrick }
9376d0caaeSpatrick 
94*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI unsigned long
strtoul_l(const char * __nptr,char ** __endptr,int __base,locale_t locale)95*4bdff4beSrobert strtoul_l(const char *__nptr, char **__endptr, int __base, locale_t locale) {
9676d0caaeSpatrick   __setAndRestore __newloc(locale);
97*4bdff4beSrobert   return ::strtoul(__nptr, __endptr, __base);
9876d0caaeSpatrick }
9976d0caaeSpatrick 
100*4bdff4beSrobert inline _LIBCPP_HIDE_FROM_ABI int
vasprintf(char ** strp,const char * fmt,va_list ap)101*4bdff4beSrobert vasprintf(char **strp, const char *fmt, va_list ap) {
10276d0caaeSpatrick   const size_t buff_size = 256;
10376d0caaeSpatrick   if ((*strp = (char *)malloc(buff_size)) == NULL) {
10476d0caaeSpatrick     return -1;
10576d0caaeSpatrick   }
10676d0caaeSpatrick 
10776d0caaeSpatrick   va_list ap_copy;
10876d0caaeSpatrick   // va_copy may not be provided by the C library in C++ 03 mode.
10976d0caaeSpatrick #if defined(_LIBCPP_CXX03_LANG) && __has_builtin(__builtin_va_copy)
11076d0caaeSpatrick   __builtin_va_copy(ap_copy, ap);
11176d0caaeSpatrick #else
11276d0caaeSpatrick   va_copy(ap_copy, ap);
11376d0caaeSpatrick #endif
11476d0caaeSpatrick   int str_size = vsnprintf(*strp, buff_size, fmt,  ap_copy);
11576d0caaeSpatrick   va_end(ap_copy);
11676d0caaeSpatrick 
11776d0caaeSpatrick   if ((size_t) str_size >= buff_size) {
11876d0caaeSpatrick     if ((*strp = (char *)realloc(*strp, str_size + 1)) == NULL) {
11976d0caaeSpatrick       return -1;
12076d0caaeSpatrick     }
12176d0caaeSpatrick     str_size = vsnprintf(*strp, str_size + 1, fmt,  ap);
12276d0caaeSpatrick   }
12376d0caaeSpatrick   return str_size;
12476d0caaeSpatrick }
12576d0caaeSpatrick 
12676d0caaeSpatrick #ifdef __cplusplus
12776d0caaeSpatrick }
12876d0caaeSpatrick #endif
129*4bdff4beSrobert #endif // _LIBCPP___SUPPORT_IBM_XLOCALE_H
130