brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.4 KiB · 24402e8 Raw
186 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include <__locale_dir/support/windows.h>10#include <clocale> // std::localeconv() & friends11#include <cstdarg> // va_start & friends12#include <cstddef>13#include <cstdio>  // std::vsnprintf & friends14#include <cstdlib> // std::strtof & friends15#include <ctime>   // std::strftime16#include <cwchar>  // wide char manipulation17 18_LIBCPP_BEGIN_NAMESPACE_STD19namespace __locale {20 21//22// Locale management23//24// FIXME: base and mask currently unused. Needs manual work to construct the new locale25__locale_t __newlocale(int /*mask*/, const char* locale, __locale_t /*base*/) {26  return {::_create_locale(LC_ALL, locale), locale};27}28 29__lconv_t* __localeconv(__locale_t& loc) {30  __locale_guard __current(loc);31  lconv* lc = std::localeconv();32  if (!lc)33    return lc;34  return loc.__store_lconv(lc);35}36 37//38// Strtonum functions39//40#if !defined(_LIBCPP_MSVCRT)41float __strtof(const char* nptr, char** endptr, __locale_t loc) {42  __locale_guard __current(loc);43  return std::strtof(nptr, endptr);44}45 46long double __strtold(const char* nptr, char** endptr, __locale_t loc) {47  __locale_guard __current(loc);48  return std::strtold(nptr, endptr);49}50#endif51 52//53// Character manipulation functions54//55#if defined(__MINGW32__) && __MSVCRT_VERSION__ < 0x080056size_t __strftime(char* ret, size_t n, const char* format, const struct tm* tm, __locale_t loc) {57  __locale_guard __current(loc);58  return std::strftime(ret, n, format, tm);59}60#endif61 62//63// Other functions64//65decltype(MB_CUR_MAX) __mb_len_max(__locale_t __l) {66#if defined(_LIBCPP_MSVCRT)67  return ::___mb_cur_max_l_func(__l);68#else69  __locale_guard __current(__l);70  return MB_CUR_MAX;71#endif72}73 74wint_t __btowc(int c, __locale_t loc) {75  __locale_guard __current(loc);76  return std::btowc(c);77}78 79int __wctob(wint_t c, __locale_t loc) {80  __locale_guard __current(loc);81  return std::wctob(c);82}83 84size_t __wcsnrtombs(char* __restrict dst,85                    const wchar_t** __restrict src,86                    size_t nwc,87                    size_t len,88                    mbstate_t* __restrict ps,89                    __locale_t loc) {90  __locale_guard __current(loc);91  return ::wcsnrtombs(dst, src, nwc, len, ps);92}93 94size_t __wcrtomb(char* __restrict s, wchar_t wc, mbstate_t* __restrict ps, __locale_t loc) {95  __locale_guard __current(loc);96  return std::wcrtomb(s, wc, ps);97}98 99size_t __mbsnrtowcs(wchar_t* __restrict dst,100                    const char** __restrict src,101                    size_t nms,102                    size_t len,103                    mbstate_t* __restrict ps,104                    __locale_t loc) {105  __locale_guard __current(loc);106  return ::mbsnrtowcs(dst, src, nms, len, ps);107}108 109size_t110__mbrtowc(wchar_t* __restrict pwc, const char* __restrict s, size_t n, mbstate_t* __restrict ps, __locale_t loc) {111  __locale_guard __current(loc);112  return std::mbrtowc(pwc, s, n, ps);113}114 115size_t __mbrlen(const char* __restrict s, size_t n, mbstate_t* __restrict ps, __locale_t loc) {116  __locale_guard __current(loc);117  return std::mbrlen(s, n, ps);118}119 120size_t __mbsrtowcs(121    wchar_t* __restrict dst, const char** __restrict src, size_t len, mbstate_t* __restrict ps, __locale_t loc) {122  __locale_guard __current(loc);123  return std::mbsrtowcs(dst, src, len, ps);124}125 126int __snprintf(char* ret, size_t n, __locale_t loc, const char* format, ...) {127  va_list ap;128  va_start(ap, format);129#if defined(_LIBCPP_MSVCRT)130  // FIXME: Remove usage of internal CRT function and globals.131  int result = ::__stdio_common_vsprintf(132      _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, ret, n, format, loc, ap);133#else134  __locale_guard __current(loc);135  _LIBCPP_DIAGNOSTIC_PUSH136  _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")137  int result = std::vsnprintf(ret, n, format, ap);138  _LIBCPP_DIAGNOSTIC_POP139#endif140  va_end(ap);141  return result;142}143 144// Like sprintf, but when return value >= 0 it returns145// a pointer to a malloc'd string in *sptr.146// If return >= 0, use free to delete *sptr.147int __libcpp_vasprintf(char** sptr, const char* __restrict format, va_list ap) {148  *sptr = nullptr;149  // Query the count required.150  va_list ap_copy;151  va_copy(ap_copy, ap);152  _LIBCPP_DIAGNOSTIC_PUSH153  _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")154  int count = vsnprintf(nullptr, 0, format, ap_copy);155  _LIBCPP_DIAGNOSTIC_POP156  va_end(ap_copy);157  if (count < 0)158    return count;159  size_t buffer_size = static_cast<size_t>(count) + 1;160  char* p            = static_cast<char*>(malloc(buffer_size));161  if (!p)162    return -1;163  // If we haven't used exactly what was required, something is wrong.164  // Maybe bug in vsnprintf. Report the error and return.165  _LIBCPP_DIAGNOSTIC_PUSH166  _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")167  if (vsnprintf(p, buffer_size, format, ap) != count) {168    _LIBCPP_DIAGNOSTIC_POP169    free(p);170    return -1;171  }172  // All good. This is returning memory to the caller not freeing it.173  *sptr = p;174  return count;175}176 177int __asprintf(char** ret, __locale_t loc, const char* format, ...) {178  va_list ap;179  va_start(ap, format);180  __locale_guard __current(loc);181  return __libcpp_vasprintf(ret, format, ap);182}183 184} // namespace __locale185_LIBCPP_END_NAMESPACE_STD186