aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Support/AutoConvert.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Support/AutoConvert.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Support/AutoConvert.cpp73
1 files changed, 62 insertions, 11 deletions
diff --git a/contrib/llvm-project/llvm/lib/Support/AutoConvert.cpp b/contrib/llvm-project/llvm/lib/Support/AutoConvert.cpp
index 4fb7e242c348..8170e553ac6e 100644
--- a/contrib/llvm-project/llvm/lib/Support/AutoConvert.cpp
+++ b/contrib/llvm-project/llvm/lib/Support/AutoConvert.cpp
@@ -14,21 +14,36 @@
#ifdef __MVS__
#include "llvm/Support/AutoConvert.h"
+#include <cassert>
#include <fcntl.h>
#include <sys/stat.h>
+#include <unistd.h>
-std::error_code llvm::disableAutoConversion(int FD) {
+static int savedStdHandleAutoConversionMode[3] = {-1, -1, -1};
+
+int disableAutoConversion(int FD) {
static const struct f_cnvrt Convert = {
- SETCVTOFF, // cvtcmd
- 0, // pccsid
- (short)FT_BINARY, // fccsid
+ SETCVTOFF, // cvtcmd
+ 0, // pccsid
+ 0, // fccsid
};
- if (fcntl(FD, F_CONTROL_CVT, &Convert) == -1)
- return std::error_code(errno, std::generic_category());
- return std::error_code();
+
+ return fcntl(FD, F_CONTROL_CVT, &Convert);
}
-std::error_code llvm::enableAutoConversion(int FD) {
+int restoreStdHandleAutoConversion(int FD) {
+ assert(FD == STDIN_FILENO || FD == STDOUT_FILENO || FD == STDERR_FILENO);
+ if (savedStdHandleAutoConversionMode[FD] == -1)
+ return 0;
+ struct f_cnvrt Cvt = {
+ savedStdHandleAutoConversionMode[FD], // cvtcmd
+ 0, // pccsid
+ 0, // fccsid
+ };
+ return (fcntl(FD, F_CONTROL_CVT, &Cvt));
+}
+
+int enableAutoConversion(int FD) {
struct f_cnvrt Query = {
QUERYCVT, // cvtcmd
0, // pccsid
@@ -36,17 +51,53 @@ std::error_code llvm::enableAutoConversion(int FD) {
};
if (fcntl(FD, F_CONTROL_CVT, &Query) == -1)
- return std::error_code(errno, std::generic_category());
+ return -1;
+
+ // We don't need conversion for UTF-8 tagged files.
+ // TODO: Remove the assumption of ISO8859-1 = UTF-8 here when we fully resolve
+ // problems related to UTF-8 tagged source files.
+ // When the pccsid is not ISO8859-1, autoconversion is still needed.
+ if (Query.pccsid == CCSID_ISO8859_1 &&
+ (Query.fccsid == CCSID_UTF_8 || Query.fccsid == CCSID_ISO8859_1))
+ return 0;
+
+ // Save the state of std handles before we make changes to it.
+ if ((FD == STDIN_FILENO || FD == STDOUT_FILENO || FD == STDERR_FILENO) &&
+ savedStdHandleAutoConversionMode[FD] == -1)
+ savedStdHandleAutoConversionMode[FD] = Query.cvtcmd;
+
+ if (FD == STDOUT_FILENO || FD == STDERR_FILENO)
+ Query.cvtcmd = SETCVTON;
+ else
+ Query.cvtcmd = SETCVTALL;
- Query.cvtcmd = SETCVTALL;
Query.pccsid =
(FD == STDIN_FILENO || FD == STDOUT_FILENO || FD == STDERR_FILENO)
? 0
: CCSID_UTF_8;
// Assume untagged files to be IBM-1047 encoded.
Query.fccsid = (Query.fccsid == FT_UNTAGGED) ? CCSID_IBM_1047 : Query.fccsid;
- if (fcntl(FD, F_CONTROL_CVT, &Query) == -1)
+ return fcntl(FD, F_CONTROL_CVT, &Query);
+}
+
+std::error_code llvm::disableAutoConversion(int FD) {
+ if (::disableAutoConversion(FD) == -1)
+ return std::error_code(errno, std::generic_category());
+
+ return std::error_code();
+}
+
+std::error_code llvm::enableAutoConversion(int FD) {
+ if (::enableAutoConversion(FD) == -1)
return std::error_code(errno, std::generic_category());
+
+ return std::error_code();
+}
+
+std::error_code llvm::restoreStdHandleAutoConversion(int FD) {
+ if (::restoreStdHandleAutoConversion(FD) == -1)
+ return std::error_code(errno, std::generic_category());
+
return std::error_code();
}