98 lines · c
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-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_IBM_H11#define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_IBM_H12 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 routines26# include <__support/xlocale/__posix_l_fallback.h>27#endif // defined(__MVS__)28 29namespace {30 31struct __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 47private:48 locale_t __stored = (locale_t)0;49 locale_t __cloc = (locale_t)0;50};51 52} // namespace53 54// The following are not POSIX routines. These are quick-and-dirty hacks55// to make things pretend to work56inline _LIBCPP_HIDE_FROM_ABI double strtod_l(const char* __nptr, char** __endptr, locale_t locale) {57 __setAndRestore __newloc(locale);58 return ::strtod(__nptr, __endptr);59}60 61inline _LIBCPP_HIDE_FROM_ABI float strtof_l(const char* __nptr, char** __endptr, locale_t locale) {62 __setAndRestore __newloc(locale);63 return ::strtof(__nptr, __endptr);64}65 66inline _LIBCPP_HIDE_FROM_ABI long double strtold_l(const char* __nptr, char** __endptr, locale_t locale) {67 __setAndRestore __newloc(locale);68 return ::strtold(__nptr, __endptr);69}70 71inline _LIBCPP_HIDE_FROM_ABI72_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 2, 0) int vasprintf(char** strp, const char* fmt, va_list ap) {73 const size_t buff_size = 256;74 if ((*strp = (char*)malloc(buff_size)) == nullptr) {75 return -1;76 }77 78 va_list ap_copy;79 // va_copy may not be provided by the C library in C++03 mode.80#if defined(_LIBCPP_CXX03_LANG) && __has_builtin(__builtin_va_copy)81 __builtin_va_copy(ap_copy, ap);82#else83 va_copy(ap_copy, ap);84#endif85 int str_size = vsnprintf(*strp, buff_size, fmt, ap_copy);86 va_end(ap_copy);87 88 if ((size_t)str_size >= buff_size) {89 if ((*strp = (char*)realloc(*strp, str_size + 1)) == nullptr) {90 return -1;91 }92 str_size = vsnprintf(*strp, str_size + 1, fmt, ap);93 }94 return str_size;95}96 97#endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_IBM_H98