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-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <__locale_dir/support/windows.h>
10#include <clocale> // std::localeconv() & friends
11#include <cstdarg> // va_start & friends
12#include <cstddef>
13#include <cstdio> // std::vsnprintf & friends
14#include <cstdlib> // std::strtof & friends
15#include <ctime> // std::strftime
16#include <cwchar> // wide char manipulation
17
18_LIBCPP_BEGIN_NAMESPACE_STD
19namespace __locale {
20
21//
22// Locale management
23//
24// FIXME: base and mask currently unused. Needs manual work to construct the new locale
25__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 functions
39//
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: nptr, endptr: endptr);
44}
45
46long double __strtold(const char* nptr, char** endptr, __locale_t loc) {
47 __locale_guard __current(loc);
48 return std::strtold(nptr: nptr, endptr: endptr);
49}
50#endif
51
52//
53// Character manipulation functions
54//
55#if defined(__MINGW32__) && __MSVCRT_VERSION__ < 0x0800
56size_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#endif
61
62//
63// Other functions
64//
65decltype(MB_CUR_MAX) __mb_len_max(__locale_t __l) {
66#if defined(_LIBCPP_MSVCRT)
67 return ::___mb_cur_max_l_func(__l);
68#else
69 __locale_guard __current(__l);
70 return MB_CUR_MAX;
71#endif
72}
73
74wint_t __btowc(int c, __locale_t loc) {
75 __locale_guard __current(loc);
76 return std::btowc(c: c);
77}
78
79int __wctob(wint_t c, __locale_t loc) {
80 __locale_guard __current(loc);
81 return std::wctob(c: 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: dst, src: src, nwc: nwc, len: len, ps: 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: s, wc: wc, ps: 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: dst, src: src, nmc: nms, len: len, ps: ps);
107}
108
109size_t
110__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: pwc, s: s, n: n, p: 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: s, n: n, ps: 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: dst, src: src, len: len, ps: 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#else
134 __locale_guard __current(loc);
135 _LIBCPP_DIAGNOSTIC_PUSH
136 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
137 int result = std::vsnprintf(s: ret, maxlen: n, format: format, arg: ap);
138 _LIBCPP_DIAGNOSTIC_POP
139#endif
140 va_end(ap);
141 return result;
142}
143
144// Like sprintf, but when return value >= 0 it returns
145// 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_PUSH
153 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
154 int count = vsnprintf(s: nullptr, maxlen: 0, format: format, arg: ap_copy);
155 _LIBCPP_DIAGNOSTIC_POP
156 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(size: 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_PUSH
166 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
167 if (vsnprintf(p, buffer_size, format, ap) != count) {
168 _LIBCPP_DIAGNOSTIC_POP
169 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(sptr: ret, format, ap);
182}
183
184} // namespace __locale
185_LIBCPP_END_NAMESPACE_STD
186

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of libcxx/src/support/win32/locale_win32.cpp