[PATCH] D27167: [libc++] Support multibyte decimal_point and thousands_sep
Eric van Gyzen via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 28 09:03:10 PST 2016
vangyzen created this revision.
vangyzen added a subscriber: cfe-commits.
Herald added a subscriber: emaste.
Herald added a reviewer: EricWF.
numpunct_byname<wchar_t> assumed that decimal_point and thousands_sep
were ASCII and simply copied the first byte from them. Add support
for multibyte strings in these fields.
I found this problem on FreeBSD 11, where thousands_sep in fr_FR.UTF-8
is a no-break space (U+00A0).
https://reviews.llvm.org/D27167
Files:
src/locale.cpp
Index: src/locale.cpp
===================================================================
--- src/locale.cpp
+++ src/locale.cpp
@@ -4281,23 +4281,51 @@
{
}
+#if defined(__clang__)
+#pragma clang diagnostic ignored "-Wmissing-braces"
+#endif
+
void
numpunct_byname<wchar_t>::__init(const char* nm)
{
if (strcmp(nm, "C") != 0)
{
__locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
if (loc == nullptr)
- __throw_runtime_error("numpunct_byname<char>::numpunct_byname"
- " failed to construct for " + string(nm));
+ __throw_runtime_error("numpunct_byname<wchar_t>::numpunct_byname"
+ " failed to construct for " + string(nm));
lconv* lc = __libcpp_localeconv_l(loc.get());
- if (*lc->decimal_point)
- __decimal_point_ = *lc->decimal_point;
- if (*lc->thousands_sep)
- __thousands_sep_ = *lc->thousands_sep;
+ if (*lc->decimal_point) {
+ size_t len = strlen(lc->decimal_point);
+ mbstate_t mbs = {0};
+ wchar_t wc;
+ size_t nb = __libcpp_mbrtowc_l(&wc, lc->decimal_point, len, &mbs,
+ loc.get());
+ if (nb == len) {
+ __decimal_point_ = wc;
+ } else {
+ __throw_runtime_error("numpunct_byname<wchar_t>: decimal_point"
+ " is not a valid multibyte character: " +
+ string(lc->decimal_point));
+ }
+ }
+ if (*lc->thousands_sep) {
+ size_t len = strlen(lc->thousands_sep);
+ mbstate_t mbs = {0};
+ wchar_t wc;
+ size_t nb = __libcpp_mbrtowc_l(&wc, lc->thousands_sep, len, &mbs,
+ loc.get());
+ if (nb == len) {
+ __thousands_sep_ = wc;
+ } else {
+ __throw_runtime_error("numpunct_byname<wchar_t>: thousands_sep"
+ " is not a valid multibyte character: " +
+ string(lc->thousands_sep));
+ }
+ }
__grouping_ = lc->grouping;
- // locallization for truename and falsename is not available
+ // localization for truename and falsename is not available
}
}
@@ -4861,10 +4889,6 @@
return result;
}
-#if defined(__clang__)
-#pragma clang diagnostic ignored "-Wmissing-braces"
-#endif
-
template <>
wstring
__time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D27167.79411.patch
Type: text/x-patch
Size: 2611 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161128/b93fe9b2/attachment-0001.bin>
More information about the cfe-commits
mailing list