[PATCH] D25018: Always print doubles with the C locale
Nicolai Hähnle via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 28 06:12:12 PDT 2016
nhaehnle created this revision.
nhaehnle added reviewers: chandlerc, chapuni.
nhaehnle added a subscriber: llvm-commits.
This fixes a problem where AsmWriter asserts or produces invalid textual IR
when the locale is set such that ',' is used for the decimal point.
The reliance on C++ streams is perhaps annoying, but I see no other way
short of importing a whole double-to-string routine. Having the user change
the locale certainly isn't an option because this occurs in a context where
LLVM is embedded in a larger application.
https://reviews.llvm.org/D25018
Files:
lib/Support/raw_ostream.cpp
Index: lib/Support/raw_ostream.cpp
===================================================================
--- lib/Support/raw_ostream.cpp
+++ lib/Support/raw_ostream.cpp
@@ -28,6 +28,9 @@
#include <cerrno>
#include <cstdio>
#include <iterator>
+#include <iomanip>
+#include <sstream>
+#include <string>
#include <system_error>
#include <sys/stat.h>
@@ -230,8 +233,6 @@
raw_ostream &raw_ostream::operator<<(double N) {
#ifdef _WIN32
- // On MSVCRT and compatible, output of %e is incompatible to Posix
- // by default. Number of exponent digits should be at least 2. "%+03d"
// FIXME: Implement our formatter to here or Support/Format.h!
#if defined(__MINGW32__)
// FIXME: It should be generic to C++11.
@@ -244,29 +245,29 @@
if (fpcl == _FPCLASS_NZ)
return *this << "-0.000000e+00";
#endif
-
- char buf[16];
- unsigned len;
- len = format("%e", N).snprint(buf, sizeof(buf));
- if (len <= sizeof(buf) - 2) {
- if (len >= 5 && buf[len - 5] == 'e' && buf[len - 3] == '0') {
- int cs = buf[len - 4];
- if (cs == '+' || cs == '-') {
- int c1 = buf[len - 2];
- int c0 = buf[len - 1];
- if (isdigit(static_cast<unsigned char>(c1)) &&
- isdigit(static_cast<unsigned char>(c0))) {
- // Trim leading '0': "...e+012" -> "...e+12\0"
- buf[len - 3] = c1;
- buf[len - 2] = c0;
- buf[--len] = 0;
- }
+#endif
+ std::ostringstream os;
+ os.imbue(std::locale("C"));
+ os << std::scientific << N;
+ std::string result = os.str();
+#ifdef _WIN32
+ // On MSVCRT and compatible, output of %e is incompatible to Posix
+ // by default. Number of exponent digits should be at least 2. "%+03d"
+ if (result.size() >= 5 && result[result.size() - 5] == 'e' &&
+ result[result.size() - 3] == '0') {
+ int cs = result[result.size() - 4];
+ if (cs == '+' || cs == '-') {
+ int c1 = result[result.size() - 2];
+ int c0 = result[result.size() - 1];
+ if (isdigit(static_cast<unsigned char>(c1)) &&
+ isdigit(static_cast<unsigned char>(c0))) {
+ // Trim leading '0': "...e+012" -> "...e+12\0"
+ result.erase(result.end() - 3);
}
}
- return this->operator<<(buf);
}
#endif
- return this->operator<<(format("%e", N));
+ return this->operator<<(result);
}
void raw_ostream::flush_nonempty() {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D25018.72814.patch
Type: text/x-patch
Size: 2354 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160928/bdd18de6/attachment.bin>
More information about the llvm-commits
mailing list