mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-24 22:24:54 +00:00
Add writeFileWithSystemEncoding to LibLLVMSuppor.
This patch adds to LLVMSupport the capability of writing files with international characters encoded in the current system encoding. This is relevant for Windows, where we can either use UTF16 or the current code page (the legacy Windows international characters). On UNIX, the file is always saved in UTF8. This will be used in a patch for clang to thoroughly support response files creation when calling other tools, addressing PR15171. On Windows, to correctly support internationalization, we need the ability to write response files both in UTF16 or the current code page, depending on the tool we will call. GCC for mingw, for instance, requires files to be encoded in the current code page. MSVC tools requires files to be encoded in UTF16. Patch by Rafael Auler! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217068 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -919,11 +919,13 @@ std::error_code UTF8ToUTF16(llvm::StringRef utf8,
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
|
||||
llvm::SmallVectorImpl<char> &utf8) {
|
||||
static
|
||||
std::error_code UTF16ToCodePage(unsigned codepage, const wchar_t *utf16,
|
||||
size_t utf16_len,
|
||||
llvm::SmallVectorImpl<char> &utf8) {
|
||||
if (utf16_len) {
|
||||
// Get length.
|
||||
int len = ::WideCharToMultiByte(CP_UTF8, 0, utf16, utf16_len, utf8.begin(),
|
||||
int len = ::WideCharToMultiByte(codepage, 0, utf16, utf16_len, utf8.begin(),
|
||||
0, NULL, NULL);
|
||||
|
||||
if (len == 0)
|
||||
@@ -933,7 +935,7 @@ std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
|
||||
utf8.set_size(len);
|
||||
|
||||
// Now do the actual conversion.
|
||||
len = ::WideCharToMultiByte(CP_UTF8, 0, utf16, utf16_len, utf8.data(),
|
||||
len = ::WideCharToMultiByte(codepage, 0, utf16, utf16_len, utf8.data(),
|
||||
utf8.size(), NULL, NULL);
|
||||
|
||||
if (len == 0)
|
||||
@@ -946,6 +948,16 @@ std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
|
||||
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
|
||||
llvm::SmallVectorImpl<char> &utf8) {
|
||||
return UTF16ToCodePage(CP_UTF8, utf16, utf16_len, utf8);
|
||||
}
|
||||
|
||||
std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len,
|
||||
llvm::SmallVectorImpl<char> &utf8) {
|
||||
return UTF16ToCodePage(CP_ACP, utf16, utf16_len, utf8);
|
||||
}
|
||||
} // end namespace windows
|
||||
} // end namespace sys
|
||||
} // end namespace llvm
|
||||
|
@@ -12,7 +12,9 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "WindowsSupport.h"
|
||||
#include "llvm/Support/ConvertUTF.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cstdio>
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
@@ -440,6 +442,50 @@ ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code
|
||||
llvm::sys::writeFileWithEncoding(StringRef FileName, StringRef Contents,
|
||||
WindowsEncodingMethod Encoding) {
|
||||
std::error_code EC;
|
||||
llvm::raw_fd_ostream OS(FileName, EC, llvm::sys::fs::OpenFlags::F_Text);
|
||||
if (EC)
|
||||
return EC;
|
||||
|
||||
if (Encoding == WEM_UTF8) {
|
||||
OS << Contents;
|
||||
} else if (Encoding == WEM_CurrentCodePage) {
|
||||
SmallVector<wchar_t, 1> ArgsUTF16;
|
||||
SmallVector<char, 1> ArgsCurCP;
|
||||
|
||||
if ((EC = windows::UTF8ToUTF16(Contents, ArgsUTF16)))
|
||||
return EC;
|
||||
|
||||
if ((EC = windows::UTF16ToCurCP(
|
||||
ArgsUTF16.data(), ArgsUTF16.size(), ArgsCurCP)))
|
||||
return EC;
|
||||
|
||||
OS.write(ArgsCurCP.data(), ArgsCurCP.size());
|
||||
} else if (Encoding == WEM_UTF16) {
|
||||
SmallVector<wchar_t, 1> ArgsUTF16;
|
||||
|
||||
if ((EC = windows::UTF8ToUTF16(Contents, ArgsUTF16)))
|
||||
return EC;
|
||||
|
||||
// Endianness guessing
|
||||
char BOM[2];
|
||||
uint16_t src = UNI_UTF16_BYTE_ORDER_MARK_NATIVE;
|
||||
memcpy(BOM, &src, 2);
|
||||
OS.write(BOM, 2);
|
||||
OS.write((char *)ArgsUTF16.data(), ArgsUTF16.size() << 1);
|
||||
} else {
|
||||
llvm_unreachable("Unknown encoding");
|
||||
}
|
||||
|
||||
if (OS.has_error())
|
||||
return std::make_error_code(std::errc::io_error);
|
||||
|
||||
return EC;
|
||||
}
|
||||
|
||||
bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef<const char*> Args) {
|
||||
// The documented max length of the command line passed to CreateProcess.
|
||||
static const size_t MaxCommandStringLength = 32768;
|
||||
|
@@ -166,6 +166,9 @@ namespace windows {
|
||||
std::error_code UTF8ToUTF16(StringRef utf8, SmallVectorImpl<wchar_t> &utf16);
|
||||
std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
|
||||
SmallVectorImpl<char> &utf8);
|
||||
/// Convert from UTF16 to the current code page used in the system
|
||||
std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len,
|
||||
SmallVectorImpl<char> &utf8);
|
||||
} // end namespace windows
|
||||
} // end namespace sys
|
||||
} // end namespace llvm.
|
||||
|
Reference in New Issue
Block a user